如何使用@ControllerAdvice @ModelAttribute定位特定处理程序?

时间:2016-03-16 16:28:10

标签: spring-mvc spring-4

我想在系统关闭前5分钟在特定页面上显示警告消息。我没有手动将它添加到每个这些页面,而是使用@ModelAttribute方法创建了一个@ControllerAdvice类,该方法将消息添加到Model参数中,但是根据我的理解阅读文档和SO以及一些初始测试,这个模型属性将被添加到使用@RequestMapping的每个方法。

我意识到我可以重构我的代码,以便有针对性的方法都在一个控制器中,并将@ControllerAdvice限制在那个控制器上,但我最终会在该控制器中收集一些非相关的方法,这些方法混淆了我的控制器的整体结构。

那么,有没有办法指出@ModelAttribute应用于多个控制器中的哪些特定方法?自定义注释是否会成为解决方案(不确定它是如何工作的)?如果可能的话,我想通过注释来做到这一点。

修改

@ControllerAdvice代码非常基本:

@ControllerAdvice
public class GlobalModelController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private MaintenanceInterceptor maintInterceptor; 

    @ModelAttribute()
    public void globalAttributes(Model model, Locale locale) {
        if (maintInterceptor.isMaintenanceWindowSet() && !maintInterceptor.isMaintenanceInEffect()) {
            String msg = maintInterceptor.getImminentMaint(locale);
            model.addAttribute("warningMaint", msg);
            logger.debug("maint msg= " + msg);          
        }
    }
}

2 个答案:

答案 0 :(得分:3)

通过使用@ControllerAdvice注释的某个值,控制器建议可以限制在某些控制器(而不是方法),例如

@ControllerAdvice(assignableTypes = {MyController1.class, MyController2.class})

如果您需要在方法级别上执行此操作,我建议您查看Interceptors

答案 1 :(得分:3)

感谢@zeroflagL指点我的拦截器解决方案。我放弃了@ControllerAdvice方法并最终得到了这个:

自定义注释:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MaintAware {
    String name() default "MaintAware";
}

<强>拦截器:

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

    HandlerMethod handlerMethod = (HandlerMethod)handler;
    Method method = handlerMethod.getMethod();
    MaintAware maintAware = method.getAnnotation(MaintAware.class);
    if (maintAware != null) {
        Locale locale = request.getLocale();
        if (isMaintenanceWindowSet() && !isMaintenanceInEffect()) {
            String msg = getImminentMaint(locale);
            if (!msg.isEmpty())
                modelAndView.addObject("warningMaint", msg);
        }
    }

    super.postHandle(request, response, handler, modelAndView);
}

现在我可以注释需要维护通知的特定方法。十分简单。 :)