有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Spring3中向所有控制器的模型添加属性

我的Spring3应用程序中的每个视图都有一组可以依赖的属性。因此,每个控制器的第一行类似于:

ControllerHelper.addDefaultModel(model, personManager, request);

在这里我要补充

  • 如果用户登录,则从数据库检索用户对象和全名
  • 通常设置一次的变量集(例如imagesHost
  • 访问者可以切换到的语言集
  • 当前语言
  • 一些统计数据(例如,我们系统中的总人数)

所有这些都允许每个视图显示登录用户的姓名,方便地参考图像位置、语言列表和有关站点的一些总体统计信息

所以问题是,控制器模型对象是存储所有数据的最佳位置,还是有一个更方便的位置可以让视图访问这些信息

其次,我真的不想让上面的ControllerHelper行作为每个控制器的第一行。它实际上并不总是第一行,有时我首先检查是否需要在该控制器中重定向,因为我不想无缘无故地浪费资源填充模型。也许一个过滤器或注释或一些Spring回调机制可以确保ControllerHelper代码在控制器完成之后调用,但在视图呈现之前调用,如果返回重定向,则跳过此操作


共 (6) 个答案

  1. # 1 楼答案

    您还可以在方法上使用@modeldattribute,例如

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

    这将为控制器中的所有请求映射添加它。如果你把它放在一个超类中,那么所有扩展它的控制器都可以使用它

  2. # 2 楼答案

    比如@blank回答我的工作:

    @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());
    }
    }
    
  3. # 3 楼答案

    你可以写一个^{}。(或其便利子类^{}

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

    其方法如下:

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

    此方法在控制器完成后和视图呈现前调用。因此,您可以使用它向ModelMap添加一些属性

    例如:

    /**
     * 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配置。xml

    <mvc:interceptors>
        <bean class="demo.VersionAddingHandlerInterceptor" autowire="constructor" />
    </mvc:interceptors>
    
  4. # 4 楼答案

    您可以使用带有@ControllerAdvice注释的控制器类

    @ControllerAdvice是在3.2中为@ExceptionHandler、@ModelAttribute和@InitBinder方法引入的,这些方法在所有或部分控制器中共享

    有关它的一些信息,请查看SpringOne2GX 2014期间录制的这部分视频 http://www.youtube.com/watch?v=yxKJsgNYDQI&t=6m33s

  5. # 5 楼答案

    如果需要添加一些全局变量,每个视图都可以解析这些变量 为什么不定义到属性或映射中 然后使用SpringDI,参考视图解析器bean。 它非常有用,例如静态可验证,例如Resul

    <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>
    
  6. # 6 楼答案

    使用@ModelAttribute或HandlerInterceptor方法时,重定向会出现一个问题当处理程序返回重定向视图时,以这种方式添加的模型属性将作为查询参数追加

    处理这种情况的另一种方法是创建会话范围的bean,它可以在基本应用程序控制器中自动连接,也可以在需要访问的每个控制器中显式连接

    有关可用作用域和用法的详细信息,请参见here