在Spring 3中为所有控制器的模型添加属性
我的 Spring 3 应用程序中的每个视图都有一组可以依赖的属性。因此,每个控制器的第一行类似于:
ControllerHelper.addDefaultModel(model, personManager, request);
我将在其中添加
- 如果人员登录到
- 通常设置一次的变量集中,
- 从数据库检索的用户对象和全名(例如
imagesHost
)访问者可以切换到 - 当前语言
- 的语言集一些统计数据(例如我们系统中的总人数)
这一切都允许每个视图显示登录用户的名称,轻松引用图像位置,语言列表以及有关的一些总体统计数据该网站。
所以问题是,控制器模型对象是存储所有数据的最佳位置还是有一个更方便的位置使视图可以轻松访问此信息?
其次,我真的很喜欢不必将上面的 ControllerHelper
行作为每个控制器中的第一行。它实际上并不总是第一行,有时我首先检查是否需要在该控制器中重定向,因为我不想无缘无故地浪费资源来填充模型。也许过滤器或注释或某些 Spring 回调机制可以确保在控制器完成后但在视图完成之前调用 ControllerHelper 代码渲染后,如果返回重定向则跳过此步骤?
Every single view in my Spring 3 app has a set of attributes they can rely on. So the first line of every controller is something like:
ControllerHelper.addDefaultModel(model, personManager, request);
In there I'll add
- user object and full name retrieved from the database if person is logged in
- set of variables which are typically set once (e.g.
imagesHost
) - set of languages a visitor can switch to
- current language
- some statistics (e.g. total # of people in our system)
This all allows each view to display the logged in user's name, easily reference an image location, a list of languages and some overall stats about the site.
So the question is, is the controller model object the best place to store all the data or is there a more convenient place which makes it just as easy for views to access this info?
And secondly, I'd REALLY love not to have to have the ControllerHelper
line above as the first line in every controller. It's actually not always the first line, sometimes I first check if I need to redirect in that controller, because I don't want to waste resources filling the model for no reason. Maybe a filter or annotation or some Spring callback mechanism could make sure the ControllerHelper
code is called after the controller is finished but right before the view is rendered, skipping this if a redirect was returned?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以编写 <代码>org.springframework.web.servlet.HandlerInterceptor。 (或其便利子类
HandlerInterceptorAdapter
)@See: Spring参考章节:
15.4.1 拦截请求 - HandlerInterceptor 接口
它有一个方法:
该方法在控制器完成之后、视图渲染之前被调用。因此您可以使用它向 ModelMap 添加一些属性
示例:
webmvc-config.xml
You could write an
org.springframework.web.servlet.HandlerInterceptor
. (or its convenience subclassHandlerInterceptorAdapter
)@See: Spring Reference chapter:
15.4.1 Intercepting requests - the HandlerInterceptor interface
It has the method:
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:
webmvc-config.xml
您还可以在方法上使用@ModelAttribute,例如
这将为控制器中的所有请求映射添加它。如果你把它放在一个超类中,那么它可以被所有扩展它的控制器使用。
You can also use @ModelAttribute on methods e.g.
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.
您可以使用带有 @ControllerAdvice 注释的控制器类
“@ControllerAdvice 是在 3.2 中引入的,用于在所有控制器或控制器子集之间共享的 @ExceptionHandler、@ModelAttribute 和 @InitBinder 方法。”
有关它的一些信息,请查看 SpringOne2GX 2014 期间录制的视频的这一部分
http://www.youtube.com/watch?v=yxKJsgNYDQI&t=6m33s
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
就像@blank 为我回答这个工作:
like @blank answer this work for me:
使用 @ModelAttribute 或 HandlerInterceptor 方法时,重定向会出现一个问题。 当处理程序返回重定向视图时,以这种方式添加的模型属性将作为查询参数附加。
处理这种情况的另一种方法是创建会话范围的 bean,它可以在基本应用程序控制器中自动装配,或者明确地在每个需要访问的控制器中。
有关可用范围和用法的详细信息,请参阅 此处。
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.
如果你需要添加一些全局变量,每个视图都可以解析这些变量,
为什么不定义到属性或映射中?
然后使用spring DI,引用视图解析器bean。
它非常有用,例如静态可验证,例如 resUrl
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