目錄
響應
傳回值是String類型
傳回值為空
傳回值是ModelAndView
使用forward和redirect關鍵字進行頁面跳轉
響應json資料
過濾靜态資源
發送ajax請求
響應json格式資料
檔案上傳
必要前提
修改form表單屬性enctype為multipart/form-data
method屬性必須是post
傳統方法的檔案上傳
springMVC方式上傳
原理圖
配置檔案解析器對象
控制器方法
跨伺服器檔案上傳
異常處理
分析
代碼編寫
編寫自定義異常類
編寫異常處理類
配置異常處理器
攔截器
概念
入門代碼
編寫攔截器的類
配置攔截器
HandlerInterceptor接口方法介紹
postHandle()
afterCompletion()
多個攔截器之間的攔截順序
攔截順序規則(個人見解)
-
響應
-
傳回值是String類型
- 常用
- springMVC會根據視圖解析器中的字首和字尾去尋找對應的頁面資源檔案
- 如果你想傳回的頁面在視圖解析器理面沒有配置, 那麼你就需要自己手動使用重定向或轉發了
-
傳回值為空
- springMVC預設會去通路請求路徑下面的頁面檔案, 但一般不這麼使用
- 需要自己使用重定向或轉發來跳轉頁面
-
傳回值是ModelAndView
- 不常用
- 存儲資料使用方法addObject()
- 底層使用的依舊是ModelMap
- 跳轉頁面使用的是方法setViewName
- 底層使用的是視圖解析器
- 當我們使用傳回值是String的跳轉方式時, 底層使用的依舊是ModelAndView方式
-
/** * @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; }
-
使用forward和redirect關鍵字進行頁面跳轉
- 用得不多
-
/** * 使用關鍵字進行頁面跳轉 * * @return */ @RequestMapping("/ForwardOrRedirect") public String ForwardOrRedirect() { // return "forward:/WEB-INF/pages/success.jsp"; return "redirect:/index.jsp";// 不需要寫虛拟路徑, springMVC會自動幫你寫虛拟路徑 }
-
響應json資料
-
過濾靜态資源
- 前端控制器dispatcherServlet預設會攔截所有的靜态資源
- 需要告訴前端控制器那些靜态資源不要攔截
- springmvc.xml中配置
-
<!--告訴前端控制器不要攔截那些資源--> <!--<mvc:resources location="/css/" mapping="/css/**"/>--> <!--<mvc:resources location="/images/" mapping="/images/**"/>--> <mvc:resources location="/js/" mapping="/js/**"/>
-
發送ajax請求
- js表達式
-
$.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) } })
-
- 控制器擷取資料的方式
- 請求中的json資料是在請求體中, 是以要給形參添加@RequestBody注解
- js表達式
-
響應json格式資料
- 第一步需要導入jar包坐标
-
<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>
-
- 給控制器方法中的傳回值添加注解@ResponseBody注解即可
- 第一步需要導入jar包坐标
-
-
-
檔案上傳
-
必要前提
-
修改form表單屬性enctype為multipart/form-data
- 修改之後, 請求體的正文就變成了MIME類型, 我們自己解析比較麻煩, 可以使用第三方的元件Commons-fileupload
- jar包坐标
-
<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>
-
-
method屬性必須是post
-
-
傳統方法的檔案上傳
- 檔案通過request請求發到伺服器, 我們要做的就是, 解析request請求裡面的資料内容, 如果是檔案, 就把它上傳到伺服器
-
/** * 傳統方法的檔案上傳 * 檔案通過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"; }
-
springMVC方式上傳
- 需要配置一個檔案解析器
- bean的屬性id必須為: multipartResolver
- 相比傳統方式的優點
- 解析request的操作不需要而我們來做了
-
原理圖
-
配置檔案解析器對象
-
<!--配置檔案解析器對象--> <!--id屬性必須為multipartResolver--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--配置上傳檔案大小, 10485769=10MB --> <property name="maxUploadSize" value="10485769"></property> </bean>
-
-
控制器方法
-
/** * 使用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"; }
-
- 需要配置一個檔案解析器
-
跨伺服器檔案上傳
- 檔案伺服器
- 負責存儲使用者上傳檔案的伺服器
- 需要導入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>
-
- 控制器方法代碼
-
/** * 跨伺服器檔案上傳 * * @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"; }
-
- 檔案伺服器
-
-
異常處理
-
分析
- 底層出現異常一般情況都是向上抛出
- 新元件
- 異常處理器元件
-
代碼編寫
-
編寫自定義異常類
- 用來做提示資訊用的
- 需要異常類都要繼承Exception類
-
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; } }
-
編寫異常處理類
- 跳轉到指定頁面
- 需要實作HandlerExceptionResolver接口
-
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; } }
-
配置異常處理器
-
<!--配置異常處理器對象--> <bean id="sysExceptionResolver" class="lq.exception.SysExceptionResolver"></bean>
-
-
-
-
攔截器
-
概念
- 用于對控制器中的方法進行預處理和後處理
- 攔截器和過濾器的差別
- 過濾器是sun公司提供的, 任何javaWeb工程都可以使用
- 攔截器是springMVC自己的, 隻有使用springMVC架構的項目才可以使用
- 過濾器一旦配置了/*就可以攔截所有的資源(jsp 圖檔 靜态資源)
- 攔截器隻能攔截控制器中的方法
-
入門代碼
-
編寫攔截器的類
- 實作HandlerInterceptor接口
- 實作了接口之後并沒有讓實作方法, 不是接口裡面沒有方法, 接口裡面是有方法的, 隻不過JDK1.8之後對接口進行了加強, 允許在接口中直接實作方法
-
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..."); } }
- 實作HandlerInterceptor接口
-
配置攔截器
-
<!--配置攔截器--> <mvc:interceptors> <mvc:interceptor> <!--攔截的路徑--> <mvc:mapping path="/user/*"/> <bean class="lq.interceptor.MyInterceptor"></bean> <!--不攔截的路徑--> <!--<mvc:exclude-mapping path="" />--> </mvc:interceptor> </mvc:interceptors>
-
-
-
HandlerInterceptor接口方法介紹
-
postHandle()
- 在控制器方法執行後, success.jsp頁面執行前執行
- 當你在這個方法裡面指定了一個新的跳轉之後, 那麼springMVC就會往新的頁面跳轉, 不再往舊的頁面跳轉, 但是, 舊的頁面依然會被執行(jsp頁面會現在伺服器内部執行)
-
afterCompletion()
- 會在success.jsp頁面執行之後執行
- 通常可以用于釋放一些資源
- 最後執行
- 無法在此方法中實作頁面跳轉
-
-
多個攔截器之間的攔截順序
-
攔截順序規則(個人見解)
- 當兩個攔截器攔截的路徑相同時(即mvc:mapping标簽的path屬性相同), 攔截順序以在springmvc.xml配置攔截器時的順序為準
- 配置在上面的攔截器會先執行, 配置在後面的攔截器會後執行
-
<!--配置攔截器--> <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>
- 當兩個攔截器攔截的路徑相同時(即mvc:mapping标簽的path屬性相同), 攔截順序以在springmvc.xml配置攔截器時的順序為準
-
-