栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

框架---springmvc2(尚马day68)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

框架---springmvc2(尚马day68)

0609springmvc 1.RESTURL(重要)

url描述性状态转移.(描述请求方法,把相同的url转到不同的处理器方法)

是一种url的写法风格,与之前url写法区别如下:

rest风格的url,没有动词

传统url参数请求方法rest风格参数
/user/getById?id=12GET|GET/user/12参数属于uri的一部分
/user/add请求体jsonPOST|POST/user请求体json
/user/update请求体jsonPOST|PUT/user请求体json
/user/deleteByID?id=12GET|DELETE/user/12参数属于uri的一部

注意点1:请求方法与url只要有一个(url排除路径变量的)不同,就是不同的处理器方法.

注意点2:参数不再?追加到url后面,而是属于uri的一部分.

注意点3:只有参数个数是固定的情况才使用rest风格的url,参数不能为""

springmvc支持rest风格url

  • @GetMapping.@PostMapping.@PutMapping.@DeleteMapping分别进行查询,添加,修改,删除映射.进行url映射时,使用{}定义路径变量,括号内是路径变量名

@DeleteMapping("{id}")
    public AxiosResult del(@PathVariable Integer id,@RequestBody SysUser u){
        return AxiosResult.suc();
 }
 
 @GetMapping("{userid}")
    public AxiosResult getById(@PathVariable("userid") Integer id){
        SysUser u =new SysUser();
        u.setId(id);
        u.setUname("aaa");
        return AxiosResult.suc(u);
    }
  • 在处理器方法形参使用@PathValiable来获取指定路径变量,默认是获取形参名对应的路径变量,也可以指定名称@PathVariable("userid")

  • put请求,默认无法获取请求体的k=v参数.本质来说tomcat就不支持put,delete请求.要用put,delete请求要求前端后端选择axios,springmvc都要支持put,delete. axios在进行put,delte请求时,底层仍然是发送post,method:put|delete,springmvc在解析method,对put,delete请求的请求再进行分发.

axios.get

axios.post

axios.put

axios.delete

2.静态资源处理

在前端未分离开发模式下才需要静态资源处理.一旦前端代码独立项目部署,那么不需要静态资源处理.

静态资源:html,css,js,jpb,png.音视频,文件

jsp能访问?

访问jsp文件,在tomcat下有默认的JspServlet来处理jsp请求
​
Tomcat:
DefaultServlet此servlet映射路径/  没有springmvc环境时,访问tomcat下的静态资源都是default来处理.有了springmvc的DisptcherServlet以后,覆盖了defaultServlet
​
JspServlet此servlet映射路径 *.jsp  

html不能访问?

当访问html,css,js等文件时,这些请求也进入DispatcherServlet,解析uri,查找HandlerMethod方法.找不到则404.

springmvc静态资源处理1:


        default
        *.html
        *.css
        *.jpg
    

springmvc静态资源处理2:(建议使用)


    
    

springmvc静态资源处理3

    
    
    

3.异常处理(重要)

异常处理的目的1:服务端的异常的内存级别的错误信息,不返回给前端,正常返回前端错误码,文字信息.

异常处理的目的2:上线运行后,需要记录程序运行过程中产生的exception异常堆栈数据.

自定义的切面,写异常通知方法.织入到所有的控制层对象中.当控制层抛出异常后,进入异常通知方法进行处理.

在springmvc中已经有封装好的异常通知.

  • 局部异常处理

缺点:只对某一个处理器类中的方法产生的异常生效.

优点:能够对不同的异常转到不同的方法进行处理.

 @ExceptionHandler(ArithmeticException.class)
    public AxiosResult doArithmeticException(ArithmeticException e){
        System.out.println(e.getMessage());
        return AxiosResult.error(e.getMessage());
    }
​
​
    @ExceptionHandler(FileNotFoundException.class)
    public AxiosResult doFileNotFoundException(FileNotFoundException e){
        System.out.println(e.getMessage());
        return AxiosResult.error(e.getMessage());
    }
​
    @ExceptionHandler(Exception.class)
    public AxiosResult doException(Exception e){
        System.out.println(e.getMessage());
        return AxiosResult.error(e.getMessage());
    }
​

  • 全局异常处理

优点:对所有处理器类中的方法异常进行处理.

缺点:无法对不同异常分开处理.

 @Override
    public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object o, Exception e) {
        if(o instanceof HandlerMethod){
            HandlerMethod m = (HandlerMethod)o;
            Object bean = m.getBean();
            Method method = m.getMethod();
        }
​
//如果需要对不同的异常返回给客户端不同的错误信息的话,需要重复的if-elseif判断,无上限的elseif.
        AxiosResult a  =  AxiosResult.error();
        PrintWriter writer = null;
        try {
            writer = resp.getWriter();
            writer.print(JSON.toJSONString(a));
            writer.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
​
        return null;
    }

  • 全局统一异常处理(重要)

使用@RestControllerAdvice来对控制层对象进行统一异常处理,所有的异常类型都在此注解对应的类中进行处理,添加不同的方法,使用@ExceptionHandler注解来限定每个方法处理器的异常类型.
通过自定义异常来接收业务异常信息.

@RestControllerAdvice+@ExceptionHandler+自定义RuntimeException+异常枚举对象

4.文件上传下载

springmvc对commons-fileupload组件进行了二次封装.使用更加简单.

  • 添加commons-fileupload;commons-io包;

  • 配置CommonsMultipartResolver对象到springmvc容器对象.此对象检测req请求是否content-type=multipart/form-data;内部要解析req对象,得到文件数据,把文件数据封装MuipartFile对象


    
        
        
        
        
    
  • 编写文件上传接口

@PostMapping("upload")
    public AxiosResult doUpload(MultipartFile myfile,MultipartFile jl) throws IOException {
        String originalFilename = myfile.getOriginalFilename();
        long size = myfile.getSize();
        //文件内容字节数组,小文件使用getBytes方法.一次性把InputStream流的数据读取到bytes数组
//        byte[] bytes = myfile.getBytes();
//        IOUtils.write(bytes,out);
        //大文件使用流来慢慢的读
        InputStream in = myfile.getInputStream();//文件内容,文件流
        //把文件存到指定的磁盘目录
}
  • 编写文件下载接口

//文件下载,返回值类型必须是ResponseEntity,因为文件下载必须指定content_disposition响应头
    @GetMapping("download")
    public ResponseEntity doDownload(String filePath,String realName) throws Exception {
        File f = new File(root,filePath);
        if(!f.exists())
            throw new MvcException(E.NOT_EXISTS);
​
        byte[] bytes = IOUtils.toByteArray(new FileInputStream(f));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition","attachment;filename="+ URLEncoder.encode(realName, "utf-8"));
        return new ResponseEntity(bytes,headers, HttpStatus.OK);
    }

5.拦截器

interceptor拦截器,是控制层框架中的一个概念,类似于原生servlet中的filter过滤器的作用.

  • 从HandlerInterceptor接口派生拦截器类,重写preHandle前拦截方法

@Component
public class LoginInterceptor implements HandlerInterceptor {
    //前拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object login_user = session.getAttribute("LOGIN_USER");
        if(login_user==null) throw new MvcException(E.NO_LOGIN);
        return true;
    }
    }

  • 配置拦截器


    
        
            
            
            
            
            
            
            
        
    

6.跨域处理

什么情况会造成跨域?

当我们前端独立部署服务器的时,有自己的ip,port,在前端项目访问页面视图,页面视图中发起向服务端的请求,服务端也是独立部署,有自己的ip,port,服务端的ip与port与前端服务器的ip,port必定有不同.

浏览器不允许在页面中发起与当前路径不同的请求(协议,ip,port).如果发起源地址不同的请求,就会造成浏览器跨域异常.

解决跨域异常的方案:

服务端在收到客户端请求时,首先检测客户端ip,port,method,请求头是否在服务端配置白名单中.如果都允许,就处理请求,并在响应头放入跨域相关响应头.

springmvc解决方案:

  • 在处理器类上添加CrossOrigin注解,没用

@CrossOrigin(origins = "http://localhost:8088",methods = {RequestMethod.GET,RequestMethod.POST},allowedHeaders = "*")
  • 在springmvc.xml配置,全局配置跨域,没用


        
    
  • 基于过滤器进行跨域配置

第一步:向容器中注册CorsFilter对象

 
        
            
                
                    
                        
                            
                                
                                
                                    
                                        GET
                                        POST
                                        PUT
                                        DELETE
                                        
                                        OPTIONS
                                    
                                
                                
                                
                            
                        
                    
                
            
        
    

第二步:在web.xml配置过滤器代理对象


        delegatingFilterProxy
        org.springframework.web.filter.DelegatingFilterProxy
        
            targetBeanName
            corsFilter
        
    
    
        delegatingFilterProxy
        /*
    

预检请求:

当前后端分离时,浏览器请求分为简单请求与复杂请求.

简单请求:

Get请求

content-type为urlEncoded,multipart/form-data的post请求

复杂请求:

post请求,contnet-type:applicaitn/json

put

delete请求

浏览器对复杂请求,先发送一次OPTIONS预检请求,此次预检请求不带请求参数,不带cookie;如果预检请求返回200,才发起第二次真正的请求.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/970451.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号