Spring Boot拦截器配置

Spring Boot自定义拦截器需实现拦截器接口,使用注册接口对拦截器实例进行注册。

拦截器接口

org.springframework.web.servlet.HandlerInterceptor

preHandle(..) - 前置处理,返回Boolean值决定是否执行后续操作。

postHandle(..) - 后置处理,位于视图渲染之前,可向ModelAndView中添加数据。

afterCompletion(..) - 前置条件返回false或处理完成时调用。可获取响应数据及异常信息。

示例:

@Component
public class DemoInterceptor implements HandlerInterceptor {

	@Autowired
	private DemoService ds;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
	}
}

Spring Boot拦截器配置

创建一个配置类(若没有),将拦截器实例注册到spring容器中,如下所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

      @Autowired
	  DemoInterceptor demoInterceptor;

      @Override
      public void addInterceptors(InterceptorRegistry registry) {
          registry.addInterceptor(new LocaleChangeInterceptor());
          registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
          registry.addInterceptor(demoInterceptor).addPathPatterns("/demo/*");
    }
}

至此,拦截器配置完成并能够工作了。以下是对特殊需求的处理。

ResponseBodyAdvice

Spring MVC中拦截器会拦截所有@Controller注解的类,但对@ResponseBody和ResponseEntity后置处理无能为力。

若被拦截方法使用@ResponseBody注解或返回值为ResponseEntity类型,拦截器后置处理会失效。

若需后置处理,需实现ResponseBodyAdvice接口,在beforeBodyWrite中执行后置处理。

org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice<T>

实现如上接口,通过注解将拦截器应用到指定Controller上。

//针对@RestController注解
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}

//针对packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}

//针对具体类
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}

默认@ControllerAdvice作用于标有@Controller注解类。

可将以上类声明为Spring bean或包含在自动扫描类路径中。

异常处理

异常处理中@ExceptionHandler将在具有匹配异常处理方法的advice中选择第一个。

 @RestControllerAdvice
 public class WebRestControllerAdvice {
   
  @ExceptionHandler(CustomNotFoundException.class)
  public ResponseMsg handleNotFoundException(CustomNotFoundException ex) {
   ResponseMsg responseMsg = new ResponseMsg(ex.getMessage());
   return responseMsg;
  }
 }

拦截器

DispatcherServlet在调用Controller前会先调用拦截器preHandle方法,并在Controller返回后调用postHandle方法和afterCompletion方法。

DispatcherServlet负责将拦截器应用到所有@Controller注解类上。