SSM05_SpringMVC_跨服务器文件上传

SpringMVC学习

响应数据和结果视图

返回值分类

返回字符串

  • Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。

    @RequestMapping(value="/hello")
    public String sayHello() {
    	System.out.println("Hello SpringMVC!!");
        // 跳转到XX页面
        return "success";
      }
    
  • 具体的应用场景

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        /**
         * 返回String
         * @param model
         * @return
         */
        @RequestMapping("/testString")
        public String testString(Model model){
            System.out.println("testString方法执行了...");
            // 模拟从数据库中查询出User对象
            User user = new User();
            user.setUsername("美美");
            user.setPassword("123");
            user.setAge(30);
            // model对象
            model.addAttribute("user",user);
            return "success";
        }
      }
    

返回值是void

  • 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。

    • 默认会跳转到@RequestMapping(value="/initUpdate") initUpdate的页面。
  • 可以使用请求转发或者重定向跳转到指定的页面

        /**
         * 是void
         * 请求转发一次请求,不用编写项目的名称
         */
        @RequestMapping("/testVoid")
        public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
            System.out.println("testVoid方法执行了...");
            // 编写请求转发的程序
            // request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
    
            // 重定向
            // response.sendRedirect(request.getContextPath()+"/index.jsp");
    
            // 设置中文乱码
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
    
            // 直接会进行响应
            response.getWriter().print("你好");
    
            return;
        }
    

返回值是ModelAndView对象

  • ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图

        /**
         * 返回ModelAndView
         * @return
         */
        @RequestMapping("/testModelAndView")
        public ModelAndView testModelAndView(){
            // 创建ModelAndView对象
            ModelAndView mv = new ModelAndView();
            System.out.println("testModelAndView方法执行了...");
            // 模拟从数据库中查询出User对象
            User user = new User();
            user.setUsername("小凤");
            user.setPassword("456");
            user.setAge(30);
    
            // 把user对象存储到mv对象中,也会把user对象存入到request对象
            mv.addObject("user",user);
    
            // 跳转到哪个页面
            mv.setViewName("success");
    
            return mv;
        }
    

SpringMVC框架提供的转发和重定向

  • forward请求转发

    • controller方法返回String类型,想进行请求转发也可以编写成
       /**
         * 使用关键字的方式进行转发或者重定向
         * @return
         */
        @RequestMapping("/testForwardOrRedirect")
        public String testForwardOrRedirect(){
            System.out.println("testForwardOrRedirect方法执行了...");
    
             请求的转发
             return "forward:/WEB-INF/pages/success.jsp";
    
        }
    
  • redirect重定向

    • controller方法返回String类型,想进行重定向也可以编写成

          /**
           * 使用关键字的方式进行转发或者重定向
           * @return
           */
          @RequestMapping("/testForwardOrRedirect")
          public String testForwardOrRedirect(){
              System.out.println("testForwardOrRedirect方法执行了...");
      
              // 重定向
              return "redirect:/index.jsp";
          }
      

ResponseBody响应json数据

  • DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而 不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置

    • mvc:resources标签配置不过滤

    • location元素表示webapp目录下的包下的所有文件

    • mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b

          <!--前端控制器,哪些静态资源不拦截-->
          <mvc:resources location="/css/" mapping="/css/**"/>
          <mvc:resources location="/images/" mapping="/images/**"/>
          <mvc:resources location="/js/" mapping="/js/**"/>
      
  • 使用@RequestBody获取请求体数据

        <script>
            // 页面加载,绑定单击事件
            $(function(){
                $("#btn").click(function(){
                    // alert("hello btn");
                    // 发送ajax请求
                    $.ajax({
                        // 编写json格式,设置属性和值
                        url:"user/testAjax",
                        contentType:"application/json;charset=UTF-8",
                        data:'{"username":"hehe","password":"123","age":30}',
                        dataType:"json",
                        type:"post",
                        success:function(data){
                            // data服务器端响应的json的数据,进行解析
                            alert(data);
                            alert(data.username);
                            alert(data.password);
                            alert(data.age);
                        }
                    });
    
                });
            });
    
        </script>
    
  • 使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应

  • 要求方法需要返回JavaBean的对象

      	/**
         * 模拟异步请求响应
         */
        @RequestMapping("/testAjax")
        public @ResponseBody User testAjax(@RequestBody User user){
            System.out.println("testAjax方法执行了...");
            // 客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中
            System.out.println(user);
            // 做响应,模拟查询数据库
            user.setUsername("haha");
            user.setAge(40);
            // 做响应
            return user;
        }
    
  • json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包

```xml
    <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>
```

SpringMVC实现文件上传

SpringMVC传统方式文件上传

  • SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的 name属性名称相同。

  • 代码:

        /**
         * SpringMVC文件上传
         * @return
         */
        @RequestMapping("/fileupload2")
        public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception {
            System.out.println("springmvc文件上传...");
    
            // 使用fileupload组件完成文件上传
            // 上传的位置
            String path = request.getSession().getServletContext().getRealPath("/uploads/");
            // 判断,该路径是否存在
            File file = new File(path);
            if(!file.exists()){
                // 创建该文件夹
                file.mkdirs();
            }
    
            // 说明上传文件项
            // 获取上传文件的名称
            String filename = upload.getOriginalFilename();
            // 把文件的名称设置唯一值,uuid
            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid+"_"+filename;
            // 完成文件上传
            upload.transferTo(new File(path,filename));
    
            return "success";
        }
    
  • 配置文件解析器对象

        <!--配置文件解析器对象,要求id名称必须是multipartResolver -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="10485760" />
        </bean>
    

SpringMVC跨服务器方式文件上传

  • 搭建图片服务器

    • 根据文档配置tomcat9的服务器,现在是2个服务器
    • 导入image项目,作为图片服务器使用
  • 实现SpringMVC跨服务器方式文件上传

    • 导入开发需要的jar包
        <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>
    
    • 编写文件上传的JSP页面

          <h3>跨服务器文件上传</h3>
      
          <form action="/user/fileupload3" method="post" enctype="multipart/form-data">
              选择文件:<input type="file" name="upload" /><br/>
              <input type="submit" value="上传" />
          </form>
      
    • 编写控制器

          /**
           * 跨服务器文件上传
           * @return
           */
          @RequestMapping("/fileupload3")
          public String fileuoload3(MultipartFile upload) throws Exception {
              System.out.println("跨服务器文件上传...");
      
              // 定义上传文件服务器路径
              String path = "http://localhost:9090/uploads/";
      
              // 说明上传文件项
              // 获取上传文件的名称
              String filename = upload.getOriginalFilename();
              // 把文件的名称设置唯一值,uuid
              String uuid = UUID.randomUUID().toString().replace("-", "");
              filename = uuid+"_"+filename;
      
              // 创建客户端的对象
              Client client = Client.create();
      
              // 和图片服务器进行连接
              WebResource webResource = client.resource(path + filename);
      
              // 上传文件
              webResource.put(upload.getBytes());
      
              return "success";
          }
      

SpringMVC的异常处理

异常处理思路

  • Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进 行异常的处理。

SpringMVC的异常处理

  • 自定义异常类

    /**
     * 自定义异常类
     */
    public class SysException extends Exception{
    
        // 存储提示信息的
        private String message;
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public SysException(String message) {
            this.message = message;
        }
    
    }
    
  • 自定义异常处理器

    /**
     * 异常处理器
     */
    public class SysExceptionResolver implements HandlerExceptionResolver{
    
        /**
         * 处理异常业务逻辑
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @return
         */
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            // 获取到异常对象
            SysException e = null;
            if(ex instanceof SysException){
                e = (SysException)ex;
            }else{
                e = new SysException("系统正在维护....");
            }
            // 创建ModelAndView对象
            ModelAndView mv = new ModelAndView();
            mv.addObject("errorMsg",e.getMessage());
            mv.setViewName("error");
            return mv;
        }
    
    }
    
  • 配置异常处理器

        <!--配置异常处理器-->
        <bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolver"/>
    
    

SpringMVC框架中的拦截器

拦截器的概述

  • SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
  • 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链 中的拦截器会按着定义的顺序执行。
  • 拦截器和过滤器的功能比较类似,有区别
    • 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
    • 拦截器是SpringMVC框架独有的。
    • 过滤器配置了/*,可以拦截任何资源。
    • 拦截器只会对控制器中的方法进行拦截。
  • 拦截器也是AOP思想的一种实现方式
  • 想要自定义拦截器,需要实现HandlerInterceptor接口。

自定义拦截器步骤

  1. 创建类,实现HandlerInterceptor接口,重写需要的方法

    /**
     * 自定义拦截器
     */
    public class MyInterceptor1 implements HandlerInterceptor{
    
        /**
         * 预处理,controller方法执行前
         * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法
         * return false不放行
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("MyInterceptor1执行了...前1111");
            // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
            return true;
        }
    
        /**
         * 后处理方法,controller方法执行后,success.jsp执行之前
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("MyInterceptor1执行了...后1111");
            // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        }
    
        /**
         * success.jsp页面执行后,该方法会执行
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("MyInterceptor1执行了...最后1111");
        }
    
    }
    
  2. 在springmvc.xml中配置拦截器类

    <!--配置拦截器-->
    <mvc:interceptors>
        <!--配置拦截器-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要拦截的方法
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置拦截器对象-->
            <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor1" />
        </mvc:interceptor>
     </mvc:interceptors>

HandlerInterceptor接口中的方法

  • preHandle方法是controller方法执行前拦截的方法
  • 可以使用request或者response跳转到指定的页面
  • return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
  • return false不放行,不会执行controller中的方法。
  • postHandle是controller方法执行后执行的方法,在JSP视图执行前。
    • 可以使用request或者response跳转到指定的页面
    • 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
  • postHandle方法是在JSP执行后执行
    • request或者response不能再跳转页面了

配置多个拦截器

  1. 再编写一个拦截器的类

    **
     * 自定义拦截器
     */
    public class MyInterceptor2 implements HandlerInterceptor{
    
        /**
         * 预处理,controller方法执行前
         * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法
         * return false不放行
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("MyInterceptor1执行了...前2222");
            // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
            return true;
        }
    
        /**
         * 后处理方法,controller方法执行后,success.jsp执行之前
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("MyInterceptor1执行了...后2222");
            // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        }
    
        /**
         * success.jsp页面执行后,该方法会执行
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("MyInterceptor1执行了...最后2222");
        }
    
    }
    
  2. 配置2个拦截器

        <!--配置拦截器-->
        <mvc:interceptors>
            <!--配置拦截器-->
            <mvc:interceptor>
                <!--要拦截的具体的方法-->
                <mvc:mapping path="/user/*"/>
                <!--不要拦截的方法
                <mvc:exclude-mapping path=""/>
                -->
                <!--配置拦截器对象-->
                <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor1" />
            </mvc:interceptor>
    
            <!--配置第二个拦截器-->
            <mvc:interceptor>
                <!--要拦截的具体的方法-->
                <mvc:mapping path="/**"/>
                <!--不要拦截的方法
                <mvc:exclude-mapping path=""/>
                -->
                <!--配置拦截器对象-->
                <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor2" />
            </mvc:interceptor>
        </mvc:interceptors>
    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章