javascript
SpringMVC框架--学习笔记(下)
接上篇:SpirngMVC框架--學習筆記(上):https://blog.csdn.net/a745233700/article/details/81038382
17、全局異常處理:
? ? 系統中異常包括兩類,預期異常和運行時異常RuntimeException,前者通過捕獲異常從而獲得異常信息,后者主要通過規范代碼開發、測試通過手段減少運行時異常的發生。
? ? 系統的dao、service、controller出現異常都通過throws Exception向上拋出,最后由springmvc前端控制器交由異常處理器進行異常處理,如下圖:
springmvc提供全局異常處理器(一個系統只有一個異常處理器)進行統一異常處理。
(1)自定義異常類:
對不同的異常類型定義異常類,繼承Exception
//自定義異常: //針對預期的異常,需要在此類中拋出此類的異常 public class CustomException extends Exception{private String message;public CustomException(String message){super(message);this.message=message;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }(2)全局異常處理器:實現HandlerExceptionResolver接口
思路:
? ? 系統遇到異常,在程序中手動拋出,dao拋給service、service給controller、controller拋給前端控制器,前端控制器調用全局異常處理器。
? ? 全局控制器處理思路:
? ? ①解析出異常類型;
? ? ②如果該異常類型是系統自定義的異常,直接取出異常信息,在錯誤頁面展示。
? ? ③如果該異常不是系統自定義的異常,構造一個自定義的異常類型(信息為“未知錯誤”)
在springmvc文件中注冊全局異常處理器:
<!-- 全局異常處理器 --><!-- 不用寫id,系統根據是否實現HandlerExceptionResolver接口,只要實現,就是全局異常處理器,如果配置多個,只有一個起作用 --><bean class="com.zwp.ssm.exception.CustomExceptionResolver"></bean>如果與業務功能相關的異常,建議在service中拋出異常。
與業務功能沒有關系的異常,建議在controller中拋出。
18、上傳圖片:
(1)創建圖片虛擬目錄:
①第一種:
②第二種:
也可以直接修改tomcat的配置:在conf/server.xml文件,添加虛擬目錄:
注意:在圖片虛擬目錄中,一定將圖片目錄分級創建(提高I/O性能),一般我們采用按日期進行分級創建。
(2)加入上傳圖片的jar包:
(3)在頁面的form表單中加入enctype="multipart/form-data"
(4)在springmvc.xml文件中配置解析器:
<!-- 上傳文件 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 設置上傳文件最大尺寸 --><property name="maxUploadSize"><value>5242880</value></property></bean>(5)編寫Controller:
//MultipartFile items_pic用于接收圖片@RequestMapping(value="/editItemsSubmit",method={RequestMethod.POST,RequestMethod.GET})public String editItemsSubmit(Model model,HttpServletRequest request,Integer id,@ModelAttribute("itemsCustom") @Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,BindingResult bindingResult,MultipartFile items_pic) throws Exception{if(bindingResult.hasErrors()){List<ObjectError> allErrors=bindingResult.getAllErrors();//自定義一個list接受自己編碼后的提示字符串,在把自己定義的list傳到界面,//這樣就解決了把亂碼傳到界面的問題了List<String> listErrors=new ArrayList<>();for(ObjectError objectError:allErrors){//System.out.println(objectError.getDefaultMessage());//把返回錯誤的提示再次編碼String strError=new String(objectError.getDefaultMessage().getBytes("ISO-8859-1"),"UTF-8"); listErrors.add(strError);//把編碼好的錯誤提示信息加自己定義好list集合里面去}model.addAttribute("allErrors", listErrors);return "Items/editItems";}//原始名稱String originalFilename=items_pic.getOriginalFilename();System.out.println(originalFilename);//上傳圖片:if(items_pic!=null && originalFilename!=null && originalFilename.length()>0){//存儲圖片的物理路徑:String pic_path="D:\\Tomcat 5.5\\pictures\\";//新的圖片名稱String newFileName=UUID.randomUUID()+originalFilename.substring(originalFilename.lastIndexOf("."));//新圖片:File newFile=new File(pic_path+newFileName);//將內存中的數據寫入磁盤items_pic.transferTo(newFile);//將新圖片名稱寫到itemsCustom中itemsCustom.setPic(newFileName);}//調用service更新商品信息,頁面需要將商品信息傳到此方法中itemsService.updateItems(id, itemsCustom);//頁面轉發:return "forward:queryItems.action";}(6)頁面顯示:
19、json交互:
@RequestBody:將json串轉成java對象
@ResponseBody:將java對象轉成json輸出。
(1)請求是Json串,輸出也是json串。
(2)請求是key/value,輸出是json(常用)
最終結果都是輸出json數據,為了在前端頁面方便對請求結果進行解析。
步驟:
第一步:導入jar包依賴:
第二步:配置json轉化器:
在注解適配器中加入messageConverters
注意:如果使用<mvc:annotation-driver />則不用定義上邊的內容。
第三步:頁面和控制器:
20、springmvc對RESTful的支持:
(1)對url進行規范,寫RESTful格式的url
(2)http的方法規范 :
不管是刪除、添加、更新。。使用的url是一致的,如果進行刪除,需要設置http的方法為delete,同理添加。
后臺controller方法:判斷http方法,如果是delete執行刪除,如果是post執行添加。
(3)對http的contentType規范:
請求是指定contentType,要json數據,設置成json格式的type..
需求:查詢商品信息,返回json數據。
思路:定義方法,進行url映射使用RESTful風格的url,將查詢商品的信息的id傳入controller。輸出json是,使用@ResponseBody將java對象輸出json。
(1)Controller:
(2)前端控制器配置:
<!-- RESTful規范要用第二種方式: --><servlet><servlet-name>springmvc_restful</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- contextConfigLocation:配置springmvc加載的配置文件(處理處映射器、處理器適配器等等) --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:/spring/springmvc.xml</param-value></init-param> </servlet><servlet-mapping><servlet-name>springmvc_restful</servlet-name><!-- 第一種:*.action,訪問以.action結尾由DispatcherServlet進行解析第二種:/,所有訪問的地址都由DispatcherServlet進行解析,對于靜態文件的解析需要配置不讓DispatcherServlet進行解析,使用此種方法可以實現RESTful風格的url第三種:/*,這種配置不對,使用這種配置,最終要轉發到一個jsp頁面,仍然會由DispatcherServlet解析jsp,不能根據jsp頁面找到Handle,會報錯--><url-pattern>/</url-pattern></servlet-mapping>(3)訪問的url:
(4)json結果數據:
--對靜態資源的解析:
在springmvc.xml中添加靜態資源的解析:
<!-- 對靜態資源的解析,如js,css,img... --><!-- <mvc:resources location="/js/" mapping="/js/**"></mvc:resources> --><!-- <mvc:resources location="/css/" mapping="/css/**"></mvc:resources> -->對靜態資源的訪問:
21、springmvc攔截器:
(1)定義攔截器:實現HandlerInterceptor接口
public class HandlerInterceptor1 implements HandlerInterceptor{//進入Handler方法之前//用于身份認證,身份授權//比如身份認證,如果認證不通過表示當前用戶沒有登陸,需要此方法攔截不再向下執行@Overridepublic boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { //return false:表示攔截,不向下執行//return ture:表示放行System.out.println("HandlerInterceptor1...preHandle");return true;}//進去Handler方法之后,返回modelAndView之前執行//應用場景:將公用的模型數據(比如菜單導航)傳到視圖,也可以在這里統一制定視圖@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {System.out.println("HandlerInterceptor1...postHandle");}//執行Handler完成執行此方法//應用場景:統一異常處理,統一日志處理@Overridepublic void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {System.out.println("HandlerInterceptor1...afterCompletion");} }(2)配置攔截器:
①針對HandlerMapping進行攔截配置:(一般不用)
如果在某個HandlerMapping中配置,經過該HandlerMapping映射成功的Handler最終使用該攔截器。
②類似全局的攔截器:
springmvc配置類似全局的攔截器,springmvc框架將配置的類似全局的攔截器注入到每個HandlerMapping中。
<!-- 攔截器 --><mvc:interceptors><!-- 多個攔截器:順序執行 --><mvc:interceptor><!-- /**:表示攔截所有url包括子url路徑 --><mvc:mapping path="/**"/><!-- 攔截器路徑 --><bean class="com.zwp.ssm.intercept.HandlerInterceptor1"></bean></mvc:interceptor><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.zwp.ssm.intercept.HandlerInterceptor2"></bean></mvc:interceptor> </mvc:interceptors>(3)測試:
①兩個攔截器都放行:
總結:preHandle方法按順序執行;postHandle和afterCompletion按攔截器配置的逆向順序執行。
②攔截器1放行,攔截器2不放行:
總結:攔截器1放行,攔截器2的preHandle才會執行;
攔截器2的preHandle不放行,攔截器2的postHandle和afterCompletion不會執行;
只要有一個攔截器不放行,postHandle不會執行。
③攔截器1不放行,攔截器2不放行:
總結:攔截器1的preHandle不放行,postHandler和afterCompletion不會執行。
攔截器1的preHandle不放行,攔截器2不執行。
(4)攔截器小結:
根據測試結果,對攔截器應用。
比如:統一日志處理攔截器,需要該攔截器的preHandle一定要放行,且將它放在攔截器鏈中第一個位置。
比如:登陸認證攔截器,放在攔截器鏈中第一個位置;權限校驗攔截器,放在登陸認證攔截器之后。(因為登陸通過之后才檢驗權限)
(5)攔截器應用:
需求:
①用戶請求url
②攔截器進行攔截校驗:
? ? --如果請求的url是公開地址(無需登陸即可訪問的url),讓放行。
? ? --如果用戶session不存在,跳轉到登陸頁面
? ? --如果用戶session存在,放行,繼續操作。
登陸頁面:
<form action="${pageContext.request.contextPath }/login.action" method="post"> 用戶名:<input type="text" name="username"/><br/> 密碼:<input type="password" name="password"/><br/> <input type="submit" value="登陸"/> </form>攔截器:
public class LoginInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { //獲取請求的urlString url=request.getRequestURI();//判斷url是否是公開地址(實際使用時,將公開地址配置在配置文件中)//這里公開地址是登陸提交的地址if(url.indexOf("login.action")>=0){//如果進行登陸提交,放行return true;}//判斷sessionHttpSession session=request.getSession();//從session中取出用戶身份信息:String username=(String) session.getAttribute("username");if(username!=null){ //身份存在,放行return true;} //執行到這里,表示用戶身份需要認證,跳轉到登陸界面request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); return false; }@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3)throws Exception {} }注冊攔截器:
<!-- 攔截器 --><mvc:interceptors><!-- 多個攔截器:順序執行 --><mvc:interceptor><!-- /**:表示攔截所有url包括子url路徑 --><mvc:mapping path="/**"/><!-- 攔截器路徑 --><bean class="com.zwp.ssm.intercept.LoginInterceptor"></bean></mvc:interceptor></mvc:interceptors>編寫Controller:
@Controller public class LoginController {@RequestMapping("/login")public String login(HttpSession sesison,String username,String password) throws Exception{//調用service進行身份驗證//...//保存用戶身份信息sesison.setAttribute("username", username);//重定向到商品列表return "redirect:items/queryItems.action"; }@RequestMapping("/logout")public String logout(HttpSession sesison) throws Exception{//清除sessionsesison.invalidate();//重定向商品列表return "redirect:items/queryItems.action"; } }登陸成功頁面:
總結
以上是生活随笔為你收集整理的SpringMVC框架--学习笔记(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC框架--学习笔记(上)
- 下一篇: 使用maven整合SSM框架详细步骤