一、拦截器HandlerInterceptor
1.1、HandlerInterceptor接口说明
preHandle,congtroller执行前,如果返回false请求终端
postHandle,controller执行之后,页面渲染前
afterCompletion,整个请求结束后,页面也渲染完毕,一般是资源清理操作
同时提供异步拦截器AsyncHandlerInterceptor
1.2、拦截器使用步骤
1》写一个拦截器,实现HandlerInterceptor 接口
2》写一个类,继承WebMvcConfigurerAdapter抽象类,然后重写addInterceptors方法,把上一步的拦截器加入registry.addInterceptor(new LogHandlerInterceptor());
1.3、示例
启动类
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
建立UserController
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
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.1、编码抛出异常代码
@GetMapping(value = "/user/help")
@ResponseBody
public String help() {
throw new IllegalArgumentException("args is empty");
}
View Code
2.2、分析代码
查看:org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,发现默认已经被springboot定制。
去除springboot默认异常显示,只需在启动类添加:@SpringBootApplication(exclude=ErrorMvcAutoConfiguration.class)即可。则返回错误就会变成Tomcat提供的
2.3、添加自定义错误页
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.1、局部异常处理
当前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.2、全局异常处理
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.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);
}
}
|