我想在系统关闭前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);
}
}
}
答案 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);
}
现在我可以注释需要维护通知的特定方法。十分简单。 :)