You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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中,不管是正常视图还是异常视图都可以直接读取:

  1. 定义拦截器:
@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;
    }
}
  1. 注册拦截器(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:39:02