Spring中如何让异常处理视图获取全局@ModelAttribute属性
方案1:复用现有全局模型属性类,统一注入异常视图
直接将你已经写好的GlobalModelAttributes注入到全局异常处理类中,抽取公共方法统一把全局属性添加到异常返回的ModelAndView里,不用每个异常处理方法重复写代码:
@ControllerAdvice public class GlobalExceptionHandler { private static final String ERROR_4_XX = "error/4xx"; // 注入已有的全局模型属性类 @Autowired private GlobalModelAttributes globalModelAttributes; @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({InvalidRequestException.class}) public ModelAndView handleBadRequest() { ModelAndView result = new ModelAndView(ERROR_4_XX); result.addObject("EXCEPTION_MESSAGE", "An invalid value provided"); // 调用公共方法填充全局属性 populateGlobalAttributes(result); return result; } // 其他异常处理方法也只需要调用这一行即可 @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler({ResourceNotFoundException.class}) public ModelAndView handleNotFound() { ModelAndView result = new ModelAndView("error/404"); populateGlobalAttributes(result); return result; } // 统一填充全局模型属性的公共方法 private void populateGlobalAttributes(ModelAndView mav) { mav.addObject("mkey", globalModelAttributes.mKey()); // 后续新增其他全局属性,只需要在这里加一行即可 // 如果全局属性数量较多,也可以通过反射扫描GlobalModelAttributes中所有带@ModelAttribute注解的方法批量调用注入 } }
这个方案改动最小,完全复用你已经写好的全局属性逻辑,不需要额外配置。
方案2:用拦截器注入请求域属性(零改动异常处理器)
因为Spring异常处理流程可以正常读取请求域的属性,你可以把全局公共属性通过拦截器注入到HttpServletRequest中,不管是正常视图还是异常视图都可以直接读取:
- 定义拦截器:
@Component public class GlobalAttributeInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 把全局属性放到请求域中,Thymeleaf可以直接通过${mkey}读取 request.setAttribute("mkey", "aValue"); return true; } }
- 注册拦截器(Spring Boot示例):
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private GlobalAttributeInterceptor globalAttributeInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(globalAttributeInterceptor).addPathPatterns("/**"); } }
这个方案不需要修改任何现有异常处理代码,后续新增全局属性只需要在拦截器里加一行即可,适配所有视图场景。
内容的提问来源于stack exchange,提问作者Aye Chan
相关产品推荐
相关产品推荐

