Java 在Spring 3中向所有控制器的模型添加属性
我的Spring3应用程序中的每个视图都有一组可以依赖的属性。因此,每个控制器的第一行类似于:Java 在Spring 3中向所有控制器的模型添加属性,java,spring,spring-mvc,spring-3,Java,Spring,Spring Mvc,Spring 3,我的Spring3应用程序中的每个视图都有一组可以依赖的属性。因此,每个控制器的第一行类似于: ControllerHelper.addDefaultModel(model, personManager, request); 在这里我要补充 如果用户登录,则从数据库检索用户对象和全名 通常设置一次的变量集(例如imagesHost) 访问者可以切换到的语言集 当前语言 一些统计数据(例如,我们系统中的总人数) 所有这些都允许每个视图显示登录用户的姓名,方便地参考图像位置、语言列表和有关站点
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 returnnull
您能提供一个将其放入一个超类的示例和子类如何使用它吗?@trusktr我创建了一个RootController
类,并创建了子类所需的字段受保护的
。这种方法很容易实现,我能够整合每个子类所需的功能控制器进入这个RootController
,这样我就不必在子类(“DRY”)中重复相同的代码@ControllerAdvice
是一个很好的选择,这应该是最好的答案,如果你需要多个控制器的相同模型属性,而不是你需要的控制器建议注释。回答得好!只是一个小小的注释:用@ControllerAdvice注释的类可以被任何类使用,不需要是控制器类。我在一个服务类上使用了它。避免该问题的另一种方法是不直接将字符串值作为属性返回,而是将它们放在HashMap或列表中,然后将该映射或列表作为属性返回:@modeldattribute(name=“mymap”)public map getSettings()
,然后在视图中通过前缀映射名称(“mymap.key”)访问这些值.