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>
    

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