SpringMVC进阶

1. ajax异步交互

springMVC默认使用MappingJackson2HttpMessageConverter对json数据进行格式转换,需要导入Jackson的包并同时配置处理器适配器和处理器映射器

   <!-- 导入Jackson包-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>
<!-- 配置处理器适配器和处理器映射器 ,可以对json格式解析,进行了方法的增强-->
    <mvc:annotation-driven />
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2021/7/17
  Time: 17:19
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax</title>
</head>
<body>
<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
<button id="btn1">ajax异步处理</button>
<script>
    $("#btn1").click(function () {
    //请求地址
        let url ="${pageContext.request.contextPath}/ajax";
        // 请求数据
            let data='[{"id":1,"username":"张三"},{"id":2,"username":"李四"}]';
            $.ajax({
                type:'POST',
                url:url,
                data:data,
                contentType:'application/json:charset=utf-8',
                success:function (resp) {
                    alert(JSON.stringify(resp));
                }
            })
    })
</script>
</body>
</html>
  • @RequestBody:当使用ajax提交并制定contentType为json格式时,需要通过HttpMessageConverter接口将json格式转为对应的POJO对象
  • @ResponseBody:当将POJO对象返回时,通过HttpMessageConverter接口转换为制定的json,xml格式等,通过response响应给客户端
 @RequestMapping("/ajax")
    @ResponseBody
    public List<User> ajax(@RequestBody List<User> list){
        System.out.println(list);
        return list;
    }

2. RESTful

  • Restful是一种软件架构风格,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件,能更简洁更有层次的实现缓存机制
  • Restful风格的请求是使用“url+请求方式表示一次请求目的的,HTTP协议中的操作方式为GET,POST,PUT,DELETE
客户端请求 原来风格URL地址 RESTful风格URL地址
查询所有 /user/findAll GET /user
根据ID查询 /user/findById?id=1 GET /user/{1}
新增 /user/save POST /user
修改 /user/update PUT /user
删除 /user/delete?id=1 DELETE /user/{1}
  • @PathVariable:用于接受RESTful请求地址中的占位符的值
  • @RestController=@Controller+@ResponseBody,简化开发,前端通过ajax与服务器进行异步交互,处理器将json数据返回
 @GetMapping("/user/{id}")// 等同于@RequestMapping(path = "/user/{id}",method = RequestMethod.GET)
    // @Controller + @ResponseBody 的作用等同于   @RestController
    public String find(@PathVariable Integer id){
        return "findbyId:"+id;
    }

    @PostMapping(value = "/user")
// @ResponseBody
    public String post() {
        return "post";
    }

    @PutMapping(value = "/user")
// @ResponseBody
    public String put() {
        return "put";
    }

    @DeleteMapping(value = "/user/{id}")
// @ResponseBody
    public String delete(@PathVariable Integer id) {
        return "delete:"+ id;
    }

3. 文件上传

  • 文件上传的三要素:表单项要有类型type= file,表单的提交方式为post,表单的enctype属性为多部分表单形式enctype=“multipart/form-data
  • 原理:当form表单修改为多部分表单multipart/form-data 时,request.getParameter()将失效,而表单属性为application/x-www-form-urlencoded,可以根据键值对的形式取值

     

 

  •  文件上传步骤(多文件上传传递参数用数组形式)
    • 导入fileuploadio坐标
    <!--导入文件上传包-->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.3.3</version>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.6</version>
            </dependency>
    • 配置文件上传解析器
    <!--    配置文件解析器-->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="5242880"/>
            <property name="maxInMemorySize" value="40960"/>
        </bean>
    • 编写文件上传代码
    @RequestMapping("/files")
        public String files(String fname, MultipartFile[] files) throws IOException {
            System.out.println(fname);
            for (MultipartFile file : files) {
                String filename = file.getOriginalFilename();
               file.transferTo(new File("d:/upload/"+filename));
            }
            return "success";
        }

     

4. 异常处理

  • java异常处理包括捕获和抛出,捕获处理(try-catch会造成业务代码和异常处理代码的耦合
  • springMVC的异常处理机制通过throws Exception向上抛出,由前端控制器交由异常处理器进行异常处理

 

 

 

 

  • 自定义异常处理
    •  创建异常处理器类实现HandlerExceptionResolver
    @Component
    public class MyException implements HandlerExceptionResolver {
        @Override
    // Object是处理器,也就是controller,e是发生的错误
        public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
            System.out.println(e.getMessage());
         ModelAndView modelAndView=new ModelAndView();
         modelAndView.addObject("error",e.getMessage());
         modelAndView.setViewName("error");
            return modelAndView;
        }
    }
    • 配置异常处理器
    <bean id="myException" class="error.MyException"></bean>
    • 编写异常页面,测试异常跳转
  • web 的异常处理机制web.xml
<!--处理500异常-->
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
<!--处理404异常-->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>

5. 拦截器

  • springMVC拦截器类似于servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理
  • 拦截按一定的顺序联结成拦截器链,在访问被拦截的方法或字段时,拦截器链中的拦截器按定义顺序被调用

 

 

 

 

  •  自定义拦截器
    • 创建拦截器类实现HandlerInterceptor接口
    package interceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyHandlerInterceptor2 implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("在方法请求调用之前。。。。");
    //return true 表示放行
    //        若是false则后续的方法都会被拦截,无法执行
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("调用方法后到视图之间");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("视图之后");
        }
    }
    • 配置拦截器
    <!-- 配置拦截器-->
    <!--  1在方法请求调用之前。。。。
    2在方法请求调用之前。。。。
    3在方法请求调用之前。。。。
    3调用方法后到视图之间
    2调用方法后到视图之间
    1调用方法后到视图之间
    3视图之后
    2视图之后
    1视图之后-->
      <mvc:interceptors>
          <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="interceptor.MyHandlerInterceptor1"/>
          </mvc:interceptor>
          <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="interceptor.MyHandlerInterceptor2"/>
          </mvc:interceptor>
          <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="interceptor.MyHandlerInterceptor3"/>
          </mvc:interceptor>
      </mvc:interceptors> 
    • 测试拦截器的拦截效果

 

posted @ 2021-07-17 17:51  forever_fate  阅读(55)  评论(0)    收藏  举报