02 springMVC 响应 文件上传 异常处理 拦截器

目录

响应

返回值是String类型

返回值为空

返回值是ModelAndView

使用forward和redirect关键字进行页面跳转

响应json数据

过滤静态资源

发送ajax请求

响应json格式数据

文件上传

必要前提

修改form表单属性enctype为multipart/form-data

method属性必须是post

传统方法的文件上传

springMVC方式上传

原理图

配置文件解析器对象

控制器方法

跨服务器文件上传

异常处理

分析

代码编写

编写自定义异常类

编写异常处理类

配置异常处理器

拦截器

概念

入门代码

编写拦截器的类

配置拦截器

HandlerInterceptor接口方法介绍

postHandle()

afterCompletion()

多个拦截器之间的拦截顺序

拦截顺序规则(个人见解)


  1. 响应

    1. 返回值是String类型

      1. 常用
      2. springMVC会根据视图解析器中的前缀和后缀去寻找对应的页面资源文件
      3. 如果你想返回的页面在视图解析器理面没有配置, 那么你就需要自己手动使用重定向或转发了
    2. 返回值为空

      1. springMVC默认会去访问请求路径下面的页面文件, 但一般不这么使用
      2. 需要自己使用重定向或转发来跳转页面
    3. 返回值是ModelAndView

      1. 不常用
      2. 存储数据使用方法addObject()
        1. 底层使用的依旧是ModelMap
      3. 跳转页面使用的是方法setViewName
        1. 底层使用的是视图解析器
      4. 当我们使用返回值是String的跳转方式时, 底层使用的依旧是ModelAndView方式
      5. /**
         * @return 返回值是ModelAndView类型
         */
        @RequestMapping("/ModelAndView")
        public ModelAndView test02() {
            ModelAndView modelAndView = new ModelAndView();
            User user = new User("李乾1", "123", 23);
            //存储数据
            modelAndView.addObject("user", user);
            //设置要跳转的页面
            modelAndView.setViewName("success");
            return modelAndView;
        }
        

         

    4. 使用forward和redirect关键字进行页面跳转

      1. 用得不多
      2. /**
         * 使用关键字进行页面跳转
         *
         * @return
         */
        @RequestMapping("/ForwardOrRedirect")
        public String ForwardOrRedirect() {
            // return "forward:/WEB-INF/pages/success.jsp";
            return "redirect:/index.jsp";// 不需要写虚拟路径, springMVC会自动帮你写虚拟路径
        }
        

         

    5. 响应json数据

      1. 过滤静态资源

        1. 前端控制器dispatcherServlet默认会拦截所有的静态资源
        2. 需要告诉前端控制器那些静态资源不要拦截
          1. springmvc.xml中配置
          2. <!--告诉前端控制器不要拦截那些资源-->
            <!--<mvc:resources location="/css/" mapping="/css/**"/>-->
            <!--<mvc:resources location="/images/" mapping="/images/**"/>-->
            <mvc:resources location="/js/" mapping="/js/**"/>
            

             

      2. 发送ajax请求

        1. js表达式
          1. $.ajax({
                url:"user/ajax",//请求的url
                contentType:"application/json;charset=utf-8",//发送的数据格式和字符集编码
                data:'{"username":"asd","password":"123","age":22}',//json数据
                dataType:"json",//预期服务器返回的数据类型
                type:"post",//请求的方式
                success:function (data) {//请求成功之后的回调函数
                    alert(data);
                    alert(data.username)
                    alert(data.password)
                    alert(data.age)
                }
            })
            

             

        2. 控制器获取数据的方式
          1. 请求中的json数据是在请求体中, 所以要给形参添加@RequestBody注解
      3. 响应json格式数据

        1. 第一步需要导入jar包坐标
          1. <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.9.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.9.0</version>
            </dependency>
            

             

        2. 给控制器方法中的返回值添加注解@ResponseBody注解即可
  2. 文件上传

    1. 必要前提

      1. 修改form表单属性enctype为multipart/form-data

        1. 修改之后, 请求体的正文就变成了MIME类型, 我们自己解析比较麻烦, 可以使用第三方的组件Commons-fileupload
        2. jar包坐标
          1. <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
            

             

      2. method属性必须是post

    2. 传统方法的文件上传

      1. 文件通过request请求发到服务器, 我们要做的就是, 解析request请求里面的数据内容, 如果是文件, 就把它上传到服务器
      2. /**
         * 传统方法的文件上传
         *  文件通过request请求发到服务器, 我们要做的就是, 解析request请求里面的数据内容, 如果是文件, 就把它上传到服务器
         *
         * @param request
         * @return
         * @throws Exception
         */
        @RequestMapping("/upload")
        public String upload(HttpServletRequest request) throws Exception {
            //设置上传的位置, 一般在webapps下面的ROOT文件夹里面
            String path = request.getSession().getServletContext().getRealPath("/uploads");
            //判断该路径是否存在, 不存在就再创建一个新的
            File file = new File(path);
            if (!file.exists()) {
                //路径不存在
                file.mkdirs();
            }
            //获取解析request对象的对象(磁盘文件项)
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            //解析request对象, 获取数据项
            List<FileItem> items = upload.parseRequest(request);
            for (FileItem item : items) {
                if (item.isFormField()) {
                    //是普通的表单数据
                } else {
                    //是上传文件数据
                    //获取文件名
                    //UUID: 保证文件名字不重复
                    String name = UUID.randomUUID().toString().replaceAll("-", "") + item.getName();
                    item.write(new File(path, name));
                    //删除临时文件, 一旦文件项大于10kb就会产生缓存文件, 低于10kb的缓存文件出现在内存里面, 不需要我们管
                    item.delete();
                }
            }
            return "success";
        }
        

         

    3. springMVC方式上传

      1. 需要配置一个文件解析器
        1. bean的属性id必须为: multipartResolver
      2. 相比传统方式的优点
        1. 解析request的操作不需要而我们来做了
      3. 原理图

      4. 配置文件解析器对象

        1. <!--配置文件解析器对象-->
          <!--id属性必须为multipartResolver-->
          <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
              <!--配置上传文件大小, 10485769=10MB -->
              <property name="maxUploadSize" value="10485769"></property>
          </bean>
          

           

      5. 控制器方法

        1. /**
           * 使用springMVC方式上传文件
           *
           * @param request
           * @param upload  此参数名字必须和type属性为file的input标签的name属性值保持一致
           * @return
           * @throws Exception
           */
          @RequestMapping("/upload")
          public String upload(HttpServletRequest request, MultipartFile upload) throws Exception {
              //设置上传的位置, 一般在webapps下面的ROOT文件夹里面
              String path = request.getSession().getServletContext().getRealPath("/uploads");
              //判断该路径是否存在, 不存在就再创建一个新的
              File file = new File(path);
              if (!file.exists()) {
                  //路径不存在
                  file.mkdirs();
              }
              //获取文件名
              //UUID: 保证文件名字不重复
              //getOriginalFilename(): 获取原始文件名字
              String filename = "aaa" + UUID.randomUUID().toString().replaceAll("-", "") + upload.getOriginalFilename();
              upload.transferTo(new File(path, filename));
              return "success";
          }
          

           

    4. 跨服务器文件上传

      1. 文件服务器
        1. 负责存储用户上传文件的服务器
      2. 需要导入jar包的依赖坐标
        1. <dependency>
              <groupId>com.sun.jersey</groupId>
              <artifactId>jersey-core</artifactId>
              <version>1.18.1</version>
          </dependency>
          <dependency>
              <groupId>com.sun.jersey</groupId>
              <artifactId>jersey-client</artifactId>
              <version>1.18.1</version>
          </dependency>
          

           

      3. 控制器方法代码
        1. /**
           * 跨服务器文件上传
           *
           * @param upload
           * @return
           * @throws Exception
           */
          @RequestMapping("/upload2")
          public String upload2(MultipartFile upload) throws Exception {
              System.out.println("upload2...");
              //定义上传到文件服务器的位置
              String path = "http://localhost:81/uploads/";
              //获取文件名
              //UUID: 保证文件名字不重复
              //getOriginalFilename(): 获取原始文件名字
              String filename = UUID.randomUUID().toString().replaceAll("-", "")
                      + "_" + upload.getOriginalFilename();
              System.out.println("filename = " + filename);
              //创建客户端对象
              Client client = Client.create();
              //和文件服务器进行连接
              WebResource webResource = client.resource(path + filename);
              //上传文件
              webResource.put(upload.getBytes());
              return "success";
          }
          

           

  3. 异常处理

    1. 分析

      1. 底层出现异常一般情况都是向上抛出
      2. 新组件
        1. 异常处理器组件
    2. 代码编写

      1. 编写自定义异常类

        1. 用来做提示信息用的
        2. 需要异常类都要继承Exception类
        3. package lq.exception;
          
          /*
          author: lq
          time: 2020-05-09 11:17 
          */
          public class SysException extends Exception {
              private String massage;
          
              public SysException(String message) {
                  this.massage = massage;
              }
          
              public String getMassage() {
                  return massage;
              }
          
              public void setMassage(String massage) {
                  this.massage = massage;
              }
          }
          

           

      2. 编写异常处理类

        1. 跳转到指定页面
        2. 需要实现HandlerExceptionResolver接口
        3. package lq.exception;
          
          import org.springframework.web.servlet.HandlerExceptionResolver;
          import org.springframework.web.servlet.ModelAndView;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          /*
          author: lq
          time: 2020-05-09 11:19 
          */
          public class SysExceptionResolver  implements HandlerExceptionResolver {
              /**
               * 异常处理器类
               * @param httpServletRequest
               * @param httpServletResponse
               * @param o 不常用, 表示当前处理器对象
               * @param e 接收抛出的异常对象
               * @return 返回的是一个ModelAndView对象, 可以帮你实现存储信息和页面跳转
               */
              @Override
              public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
                  SysException sysException=null;
                  //判断接收到的异常是不是我们自定义的异常
                  if (e instanceof SysException){
                      //是, 直接赋值
                      sysException= (SysException) e;
                  }else {
                      //不是, 再重新新建一个
                      e=new SysException("系统维护中...");
                  }
                  //创建视图对象
                  ModelAndView modelAndView = new ModelAndView();
                  //往request中存储错误信息
                  modelAndView.addObject("errorMsg",((SysException) e).getMassage());
                  //设置跳转页面
                  modelAndView.setViewName("error");
                  return modelAndView;
              }
          }
          

           

      3. 配置异常处理器

        1. <!--配置异常处理器对象-->
          <bean id="sysExceptionResolver" class="lq.exception.SysExceptionResolver"></bean>
          

           

  4. 拦截器

    1. 概念

      1. 用于对控制器中的方法进行预处理和后处理
      2. 拦截器和过滤器的区别
        1. 过滤器是sun公司提供的, 任何javaWeb工程都可以使用
        2. 拦截器是springMVC自己的, 只有使用springMVC框架的项目才可以使用
        3. 过滤器一旦配置了/*就可以拦截所有的资源(jsp 图片 静态资源)
        4. 拦截器只能拦截控制器中的方法
    2. 入门代码

      1. 编写拦截器的类

        1. 实现HandlerInterceptor接口
          1. 实现了接口之后并没有让实现方法, 不是接口里面没有方法, 接口里面是有方法的, 只不过JDK1.8之后对接口进行了加强, 允许在接口中直接实现方法
        2. package lq.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 MyInterceptor implements HandlerInterceptor {
              /**
               * 预处理
               * @param request
               * @param response
               * @param handler
               * @return 返回值为true放行 返回值为false不放行, 使用request response这两个对象跳转到指定页面
               * @throws Exception
               */
              @Override
              public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                  System.out.println("preHandle...");
                  return true;
              }
          
              @Override
              public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
                  System.out.println("postHandle...");
              }
          }
          

           

      2. 配置拦截器

        1. <!--配置拦截器-->
          <mvc:interceptors>
              <mvc:interceptor>
                  <!--拦截的路径-->
                  <mvc:mapping path="/user/*"/>
                  <bean class="lq.interceptor.MyInterceptor"></bean>
                  <!--不拦截的路径-->
                  <!--<mvc:exclude-mapping path="" />-->
              </mvc:interceptor>
          </mvc:interceptors>
          

           

    3. HandlerInterceptor接口方法介绍

      1. postHandle()

        1. 在控制器方法执行后, success.jsp页面执行前执行
        2. 当你在这个方法里面指定了一个新的跳转之后, 那么springMVC就会往新的页面跳转, 不再往旧的页面跳转, 但是, 旧的页面依然会被执行(jsp页面会现在服务器内部执行)
      2. afterCompletion()

        1. 会在success.jsp页面执行之后执行
        2. 通常可以用于释放一些资源
        3. 最后执行
        4. 无法在此方法中实现页面跳转
    4. 多个拦截器之间的拦截顺序

      1. 拦截顺序规则(个人见解)

        1. 当两个拦截器拦截的路径相同时(即mvc:mapping标签的path属性相同), 拦截顺序以在springmvc.xml配置拦截器时的顺序为准
          1. 配置在上面的拦截器会先执行, 配置在后面的拦截器会后执行
          2. <!--配置拦截器-->
            <mvc:interceptors>
                <mvc:interceptor>
                    <mvc:mapping path="/user/*"/>
                    <bean class="lq.interceptor.MyInterceptor"></bean>
                </mvc:interceptor>
                <mvc:interceptor>
                    <mvc:mapping path="/user/*"/>
                    <bean class="lq.interceptor.MyInterceptor2"></bean>
                </mvc:interceptor>
            </mvc:interceptors>
            

             

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值