014-Spring Boot web【三】攔截器HandlerInterceptor、異常處理頁面,全局異常處理ControllerAdvice

1、攔截器HandlerInterceptor

1.一、HandlerInterceptor接口說明

  preHandle,congtroller執行前,若是返回false請求終端html

  postHandle,controller執行以後,頁面渲染前java

  afterCompletion,整個請求結束後,頁面也渲染完畢,通常是資源清理操做web

  同時提供異步攔截器AsyncHandlerInterceptorspring

1.二、攔截器使用步驟

  1》寫一個攔截器,實現HandlerInterceptor 接口springboot

  2》寫一個類,繼承WebMvcConfigurerAdapter抽象類,而後重寫addInterceptors方法,把上一步的攔截器加入registry.addInterceptor(new LogHandlerInterceptor());app

1.三、示例

  啓動類異步

package com.lhx.spring.springboot_web; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
View Code

  創建UserControlleride

package com.lhx.spring.springboot_web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class UserController { @GetMapping(value = "/user/home") public String home() { System.out.println("--------user home--------"); return "user home"; } }
View Code

  增長攔截器LogHandlerInterceptor post

package com.lhx.spring.springboot_web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LogHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("----------preHandle----------"+handler.getClass()); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("----------postHandle----------"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("----------afterCompletion----------"); } }
View Code

  增長配置類WebConfiguration 編碼

package com.lhx.spring.springboot_web; import org.springframework.boot.SpringBootConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SpringBootConfiguration public class WebConfiguration extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogHandlerInterceptor()); } }
View Code

2、異常處理

2.一、編碼拋出異常代碼

@GetMapping(value = "/user/help") @ResponseBody public String help() { throw new IllegalArgumentException("args is empty"); } 
View Code

2.二、分析代碼

  查看:org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,發現默認已經被springboot定製。

  去除springboot默認異常顯示,只需在啓動類添加:@SpringBootApplication(exclude=ErrorMvcAutoConfiguration.class)便可。則返回錯誤就會變成Tomcat提供的

2.三、添加自定義錯誤頁

  1》去除springboot默認的:@SpringBootApplication(exclude=ErrorMvcAutoConfiguration.class)

  2》在src/main/resources下增長public,在pulic中增長404.html,500.html

  3》增長CommonErrorPageRegistry實現ErrorPageRegistrar增長@Component註解,能夠針對錯誤碼處理或者具體異常處理

package com.lhx.spring.springboot_web; import org.springframework.boot.web.servlet.ErrorPage; import org.springframework.boot.web.servlet.ErrorPageRegistrar; import org.springframework.boot.web.servlet.ErrorPageRegistry; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @Component public class CommonErrorPageRegistry implements ErrorPageRegistrar { @Override public void registerErrorPages(ErrorPageRegistry registry) { ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"); ErrorPage e500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html"); ErrorPage args = new ErrorPage(IllegalArgumentException.class, "/args.html"); registry.addErrorPages(e404); registry.addErrorPages(e500); registry.addErrorPages(args); } }
View Code

    以上將404,500邏輯添加

 3、全局異常處理

3.一、局部異常處理

  當前Controller使用,能夠在當前Controller中使用ExceptionHandler註解

以下代碼

package com.lhx.spring.springboot_web; import java.io.FileNotFoundException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class BookController { @ExceptionHandler(value = Exception.class) public String error(Exception e) { return "fount exception:"+e.getMessage(); } @GetMapping("book/error1") public String error1() throws FileNotFoundException { throw new FileNotFoundException("book not found"); } @GetMapping("book/error2") public String error2() throws ClassNotFoundException { throw new ClassNotFoundException("class not found"); } }
View Code

  其中:@ExceptionHandler(value = Exception.class) 表明全部;也可指代具體異常,如文件沒有發現@ExceptionHandler(value = FileNotException.class)

3.二、全局異常處理

  1》寫一個GlobalExceptionHandler異常處理類,而且使用@ControllerAdvice註解

  2》寫一個方法,須要添加@ExceptionHandler(value = Exception.class)註解,在方法中編寫具體代碼邏輯

package com.lhx.spring.springboot_web; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = Exception.class) @ResponseBody public String errorHandler(Exception e) { return "global error:" + e.getClass().getName(); } }
View Code

  能夠有多個不一樣的異常處理。

3.三、就近原則

  局部異常優先級高於全局異常處理

一個比較通用的寫法

@ControllerAdvice @ResponseBody public class ResponseExceptionHandler { Logger logger=LoggerFactory.getLogger(ResponseExceptionHandler.class); @ExceptionHandler(ResponseException.class) public ResponseEntity<ResponseResult> handleException(Exception e) { logger.error("請求異常信息",e); ResponseException cex = (ResponseException) e; return new ResponseEntity(ResponseResult.error(cex.getResponseCode()), HttpStatus.OK); } }
相關文章
相關標籤/搜索