天天看點

SpringMVC檔案上傳,攔截器,異常處理

SpringMVC的檔案上傳

檔案上傳

單檔案上傳

導入相應坐标

pom.xml

<!--檔案上傳-->
        <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.6</version>
        </dependency>
           

配置檔案上傳解析器

spring-mvc.xml

<!--配置檔案上傳解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UYF-8"/>
        <property name="maxUploadSize" value="500000"/>
    </bean>
           

檔案上傳代碼

upload.jsp

<%--
  Created by IntelliJ IDEA.
  User: auas
  Date: 2021/1/7
  Time: 18:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/quick22" method="post" enctype="multipart/form-data">
    名稱<input type="text" name="username"><br/>
    檔案1<input type="file" name="uploadFile"><br/>
    <input type="submit" value="送出">
</form>

</body>
</html>

           

name=“uploadFile” 要與 MultipartFile uploadFile 一緻

@RequestMapping(value="/quick22")
    @ResponseBody
    public void save22(String username, MultipartFile uploadFile) throws IOException {
        System.out.println(username);
        System.out.println(uploadFile);
        //獲得上傳檔案的名稱
        String originalFilename = uploadFile.getOriginalFilename();
        uploadFile.transferTo(new File("C:\\Users\\auas\\Desktop\\建立檔案夾"+originalFilename));
    }
           
SpringMVC檔案上傳,攔截器,異常處理

桌面顯示有此檔案

多檔案上傳

檔案上傳代碼

@RequestMapping(value="/quick23")
    @ResponseBody
    public void save23(String username, MultipartFile[] uploadFile) throws IOException {
        System.out.println(username);
        for (MultipartFile multipartFile : uploadFile) {
            String originalFilename = multipartFile.getOriginalFilename();
            multipartFile.transferTo(new File("C:\\upload\\"+originalFilename));
        }
    }
           

upload.jsp

<%--
  Created by IntelliJ IDEA.
  User: auas
  Date: 2021/1/7
  Time: 18:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/quick23" method="post" enctype="multipart/form-data">
        名稱<input type="text" name="username"><br/>
        檔案1<input type="file" name="uploadFile"><br/>
        檔案2<input type="file" name="uploadFile"><br/>
    	檔案3<input type="file" name="uploadFile"><br/>
        <input type="submit" value="送出">
    </form>

</body>
</html>

           

SpringMVC的攔截器

攔截器

Spring MVC 的攔截器類似于 Servlet 開發中的過濾器 Filter,用于對處理器進行預處理和後處理。

将攔截器按一定的順序聯結成一條鍊,這條鍊稱為攔截器鍊(InterceptorChain)。在通路被攔截的方法或字段時,攔截器鍊中的攔截器就會按其之前定義的順序被調用。攔截器也是AOP思想的具體實作。

  • SpringMVC攔截器-interceptor和filter差別
    SpringMVC檔案上傳,攔截器,異常處理
  • 攔截器方法
    SpringMVC檔案上傳,攔截器,異常處理

實作代碼

編寫攔截器:

public class MyInterceptor1 implements HandlerInterceptor {
    //在目标方法執行之前 執行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle.....");
        //return flase; 設定flase,後面所有都不執行
        return true  //放行
}
    //在目标方法執行之後 視圖對象傳回之前執行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("postHandle...");
    }
    //在流程都執行完畢後 執行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion....");
    }
}

           

配置:在SpringMVC的配置檔案中配置

Spring-mvc.xml

<!--配置攔截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--對哪些資源執行攔截操作-->
            <mvc:mapping path="/**"/>
            <bean class="com.itheima.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

           

編寫測試程式測試:

編寫Controller,發請求到controller,跳轉頁面

@Controller
public class TargetController {

    @RequestMapping("/target")
    public ModelAndView show(){
        System.out.println("目标資源執行......");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name","itcast");
        modelAndView.setViewName("index");
        return modelAndView;
    }

}
           

index.jsp頁面

<html>
<body>
<h2>Hello World! ${name}</h2>
</body>
</html>
           

http://localhost:8080/itheima_spring_mvc_war_exploded/target

preHandle…

目标資源執行…

postHandle…

afterCompletion…

應用場景

preHandle 應用場景

SpringMVC檔案上傳,攔截器,異常處理
SpringMVC檔案上傳,攔截器,異常處理

postHandle使用

SpringMVC檔案上傳,攔截器,異常處理
SpringMVC檔案上傳,攔截器,異常處理

多個攔截器執行

攔截器在預處理後什麼情況下會執行目标資源,什麼情況下不執行目标資源,以及在有多個攔截器的情況下攔截器的執行順序是什麼?

再編寫一個攔截器2,

public class MyInterceptor2 implements HandlerInterceptor {
    //在目标方法執行之前 執行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle22222.....");
        return true;
    }

    //在目标方法執行之後 視圖對象傳回之前執行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("postHandle2222...");
    }

    //在流程都執行完畢後 執行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion2222....");
    }
}
           

配置攔截器2

<!--配置攔截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--對哪些資源執行攔截操作-->
            <mvc:mapping path="/**"/>
            <bean class="com.itheima.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--對哪些資源執行攔截操作-->
            <mvc:mapping path="/**"/>
            <bean class="com.itheima.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

           

結論:

當攔截器的preHandle方法傳回true則會執行目标資源,如果傳回false則不執行目标資源

多個攔截器情況下,配置在前的先執行,配置在後的後執行

攔截器中的方法執行順序是:preHandler-------目标資源----postHandle---- afterCompletion

SpringMVC檔案上傳,攔截器,異常處理

SpringMVC異常處理機制

系統中異常包括兩類:預期異常和運作時異常RuntimeException,前者通過捕獲異常進而擷取異常資訊,後者主要通過規範代碼開發、測試等手段減少運作時異常的發生。

系統的Dao、Service、Controller出現都通過throws Exception向上抛出,最後由SpringMVC前端控制器交由異常處理器進行異常處理,如下圖:

SpringMVC檔案上傳,攔截器,異常處理

異常處理兩種方式

① 使用Spring MVC提供的簡單異常處理器SimpleMappingExceptionResolver

② 實作Spring的異常處理接口HandlerExceptionResolver 自定義自己的異常處理器

簡單異常處理器SimpleMappingExceptionResolver

代碼

package com.itheima.service;

import com.itheima.exception.MyException;
import java.io.FileNotFoundException;

public interface DemoService {
    void show1();
    void show2();
    void show3() throws FileNotFoundException;
    void show4();
    void show5() throws MyException;
}

           
package com.itheima.service;

import com.itheima.exception.MyException;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class DemoServiceImpl implements DemoService {
    public void show1() {
        System.out.println("抛出類型轉換異常....");
        Object str = "zhangsan";
        Integer num = (Integer)str;
    }

    public void show2() {
        System.out.println("抛出除零異常....");
        int i = 1/0;
    }

    public void show3() throws FileNotFoundException {
        System.out.println("檔案找不到異常....");
        InputStream in = new FileInputStream("C:/xxx/xxx/xxx.txt");
    }

    public void show4() {
        System.out.println("空指針異常.....");
        String str = null;
        str.length();
    }

    public void show5() throws MyException {
        System.out.println("自定義異常....");
        throw new MyException();
    }
}

           

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>通用的錯誤提示頁面</h1>
    <h1>${info}</h1>
</body>
</html>

           

相應異常與視圖的映射配置

spring-mvc.xml

<!--配置簡單映射異常處理器-->
    <bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”> 
        <!--統一使用異常-->
        <property name=“defaultErrorView” value=“error”/>   預設錯誤視圖
        <!-- 或 根據 不同情況顯示不同異常 
        <property name=“exceptionMappings”>
            <map>		異常類型		                             錯誤視圖
                <entry key="com.itheima.exception.MyException" value="error"/>  自定義異常
                <entry key="java.lang.ClassCastException" value="error"/>     類型轉換異常
            </map>
        </property>
        -->
</bean>
           

測試類

package com.itheima.controller;

import com.itheima.exception.MyException;
import com.itheima.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.FileNotFoundException;

@Controller
public class DemoController {

    @Autowired
    private DemoService demoService;

    @RequestMapping(value = "/show")
    public String show() throws FileNotFoundException, MyException {
        System.out.println("show running......");
        demoService.show1();

        return "index";
    }

}

           
自定義異常處理步驟

實作Spring的異常處理接口HandlerExceptionResolver 自定義自己的異常處理器

  • 自定義異常
package com.itheima.resolver;

import com.itheima.exception.MyException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyExceptionResolver implements HandlerExceptionResolver {

    /*
        參數Exception:異常對象
        傳回值ModelAndView:跳轉到錯誤視圖資訊
     */
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();

        if(e instanceof MyException){
            modelAndView.addObject("info","自定義異常");
        }else if(e instanceof ClassCastException){
            modelAndView.addObject("info","類轉換異常");
        }

        modelAndView.setViewName("error");

        return modelAndView;
    }
}

           
  • spring-mvc.xml