How to target specific handlers with a @ControllerAdvice @ModelAttribute?

喜你入骨 提交于 2019-12-02 04:33:46

问题


I'd like to display a warning message on specific pages 5 minutes prior to a system shutdown. Rather than add it manually to each these pages I created a @ControllerAdvice class with a @ModelAttribute method that adds the message to the Model parameter, but from what I understand reading the documentation and SO and some initial testing this model attribute will be added to every method with a @RequestMapping.

I realize I could refactor my code so that the targeted methods are all in one controller and limit the @ControllerAdvice to that one controller, but I would end up with a collection of otherwise non-related methods in that controller which muddies up the overall structure of my controllers.

So, is there a way to indicate which specific methods in multiple controllers the @ModelAttribute is applied to? Would a custom annotation be a solution (not sure how that would work)? I'd like to do this via annotations if possible.

Edit:

The @ControllerAdvice code is pretty basic:

@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);          
        }
    }
}

回答1:


A controller advice can be limited to certain controllers (not methods) by using one of the values of the @ControllerAdvice annotation, e.g.

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

If you need to do it on a method level I suggest to take a look at Interceptors.




回答2:


Thanks to @zeroflagL for pointing me to the interceptor solution. I ditched the @ControllerAdvice approach and ended up with this:

Custom annotation:

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

Interceptor:

@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);
}

Now I can annotate the specific methods that require the maintenance notification. Easy peasy. :)



来源:https://stackoverflow.com/questions/36041509/how-to-target-specific-handlers-with-a-controlleradvice-modelattribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!