Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Spring 3中向所有控制器的模型添加属性_Java_Spring_Spring Mvc_Spring 3 - Fatal编程技术网

Java 在Spring 3中向所有控制器的模型添加属性

Java 在Spring 3中向所有控制器的模型添加属性,java,spring,spring-mvc,spring-3,Java,Spring,Spring Mvc,Spring 3,我的Spring3应用程序中的每个视图都有一组可以依赖的属性。因此,每个控制器的第一行类似于: ControllerHelper.addDefaultModel(model, personManager, request); 在这里我要补充 如果用户登录,则从数据库检索用户对象和全名 通常设置一次的变量集(例如imagesHost) 访问者可以切换到的语言集 当前语言 一些统计数据(例如,我们系统中的总人数) 所有这些都允许每个视图显示登录用户的姓名,方便地参考图像位置、语言列表和有关站点

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

ControllerHelper.addDefaultModel(model, personManager, request);
在这里我要补充

  • 如果用户登录,则从数据库检索用户对象和全名
  • 通常设置一次的变量集(例如
    imagesHost
  • 访问者可以切换到的语言集
  • 当前语言
  • 一些统计数据(例如,我们系统中的总人数)
所有这些都允许每个视图显示登录用户的姓名,方便地参考图像位置、语言列表和有关站点的一些总体统计信息

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

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

您可以编写一个。(或其便利子类)

@见:

其方法如下:

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-config.xml

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

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

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

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

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

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


可以找到有关可用范围和用法的详细信息。

如果需要添加一些全局变量,每个视图都可以解析这些变量 为什么不定义到属性或映射中 然后使用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>

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

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

有关它的一些信息,请查看SpringOne2GX 2014期间录制的这部分视频

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

你不能把这些东西放在会话中吗?所以我可以把用户对象和全名放在会话中,剩下的东西放在会话中没有任何意义。我将会话保存在数据库中,以便更容易地进行集群,因此我尝试将其保持在最小值。如果我在会话中存储用户对象和全名,这意味着我将对每个请求进行数据库调用。无论如何,我都是这样做的,每次请求时都从数据库中检索这些对象,但至少检索这些对象可以让hibernate缓存更容易。我也有同样的问题要解决@在您是如何解决的?如
getModelMap()中所述
never return
null
您能提供一个将其放入一个超类的示例和子类如何使用它吗?@trusktr我创建了一个
RootController
类,并创建了子类所需的字段
受保护的
。这种方法很容易实现,我能够整合每个子类所需的功能控制器进入这个
RootController
,这样我就不必在子类(“DRY”)中重复相同的代码
@ControllerAdvice
是一个很好的选择,这应该是最好的答案,如果你需要多个控制器的相同模型属性,而不是你需要的控制器建议注释。回答得好!只是一个小小的注释:用@ControllerAdvice注释的类可以被任何类使用,不需要是控制器类。我在一个服务类上使用了它。避免该问题的另一种方法是不直接将字符串值作为属性返回,而是将它们放在HashMap或列表中,然后将该映射或列表作为属性返回:
@modeldattribute(name=“mymap”)public map getSettings()
,然后在视图中通过前缀映射名称(“mymap.key”)访问这些值.