Add attributes to the model of all controllers in Spring 3

烈酒焚心 提交于 2019-11-28 18:32:31

You could write an org.springframework.web.servlet.HandlerInterceptor. (or its convenience subclass HandlerInterceptorAdapter)

@See: Spring Reference chapter: 15.4.1 Intercepting requests - the HandlerInterceptor interface

It has the method:

void postHandle(HttpServletRequest request,
                HttpServletResponse response,
                Object handler,
                ModelAndView modelAndView) throws Exception;

This method is invoked after the controller is done and before the view is rendered. So you can use it, to add some properties to the ModelMap

An example:

/**
 * Add the current version under name {@link #VERSION_MODEL_ATTRIBUTE_NAME}
 * to each model. 
 * @author Ralph
 */
public class VersionAddingHandlerInterceptor extends HandlerInterceptorAdapter {

    /**
     * The name under which the version is added to the model map.
     */
    public static final String VERSION_MODEL_ATTRIBUTE_NAME =
                "VersionAddingHandlerInterceptor_version";

    /**        
     *  it is my personal implmentation 
     *  I wanted to demonstrate something usefull
     */
    private VersionService versionService;

    public VersionAddingHandlerInterceptor(final VersionService versionService) {
        this.versionService = versionService;
    }

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

        if (modelAndView != null) {
            modelAndView.getModelMap().
                  addAttribute(VERSION_MODEL_ATTRIBUTE_NAME,
                               versionService.getVersion());
        }
    }
}

webmvc-config.xml

<mvc:interceptors>
    <bean class="demo.VersionAddingHandlerInterceptor" autowire="constructor" />
</mvc:interceptors>

You can also use @ModelAttribute on methods e.g.

@ModelAttribute("version")
public String getVersion() {
   return versionService.getVersion();
}

This will add it for all request mappings in a controller. If you put this in a super class then it could be available to all controllers that extend it.

You could use a Controller Class annotated with @ControllerAdvice

"@ControllerAdvice was introduced in 3.2 for @ExceptionHandler, @ModelAttribute, and @InitBinder methods shared across all or a subset of controllers."

for some info about it have a look at this part of the video recorded during SpringOne2GX 2014 http://www.youtube.com/watch?v=yxKJsgNYDQI&t=6m33s

like @blank answer this work for me:

@ControllerAdvice(annotations = RestController.class)
public class AnnotationAdvice {

    @Autowired
    UserServiceImpl userService;

    @ModelAttribute("currentUser")
    public User getCurrentUser() {
       UserDetails userDetails = (UserDetails) 
       SecurityContextHolder.getContext().getAuthentication().getPrincipal();
       return userService.findUserByEmail(userDetails.getUsername());
}
}

There is one issue that occurs with redirection when using @ModelAttribute or HandlerInterceptor approach. When the handler returns Redirect view, the model attributes added this way are appended as query parameters.

Another way to handle this situation is to create session-scoped bean, that can be autowired in base application controller, or explicitelly in every controller where access is needed.

Details about available scopes and usage can be found here.

if you need add some global variables that every view can resolve these variables, why not define into a properties or map? then use spring DI, refer to the view resolver bean. it is very useful,such as static veriable, e.g. resUrl

<property name="viewResolvers">
        <list>
            <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="viewClass"
                    value="org.springframework.web.servlet.view.JstlView" />
                <property name="attributes" ref="env" />
                <property name="exposeContextBeansAsAttributes" value="false" />
                <property name="prefix" value="${webmvc.view.prefix}" />
                <property name="suffix" value="${webmvc.view.suffix}" />
            </bean>
        </list>
    </property>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!