Reputation: 343
I have a sidebar almost in all my pages, which needs some methods and queries to get executed (say a list of cities and events in them). So basically, now I call the method and then model.setAttribute("mylist",list) almost in all my controllers.
A good solution for me would be if I could call a Controller or Service for that sidebar subpage when I include it in JSP but well its not possible in View layer. What I could do would be putting Java snippet codes in that JSP subpage being included in all pages, well which is bad.
Right now I'm adding those method calls and setting the result attributes in all my Controllers, which is a lot of repeated code. What is a good design solution for these cases?
In Summery: I want to have some method calls in almost all my controllers because in Apache Tiles I'm using a sidebar sub page which needs those method calls to be done in controller/service layer.
Upvotes: 1
Views: 190
Reputation: 2286
Another option is to add an interceptor to your MVC configuration. For example, this interceptor retrieves the number of unread conversations a user has in order to display it in his navbar and stores it in the HttpServletRequest as an attribute with request scope. It could have been added to the ModelAndView as well:
public class PageModelInterceptor extends HandlerInterceptorAdapter {
private MessagingService mailboxService;
public PageModelInterceptor() {
}
@Override
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) {
addNbConversationUpdates(request);
}
private void addNbConversationUpdates(final HttpServletRequest request) {
if (XSecurity.principal() != null) {
final int nbUpdatedConversations = mailboxService.getUpdatedConversations(XSecurity.principal().getId()).size();
request.setAttribute("nbConversationUpdates", nbUpdatedConversations);
}
}
public void setMailboxService(final MessagingService mailboxService) {
this.mailboxService = mailboxService;
}
}
This needs to be added to your dispatcher-servlet.xml or whatever file your web application context is declared in.
<mvc:interceptor>
<mvc:mapping path="/ui/**" />
<bean class="com.xyz.project.web.PageModelInterceptor">
<property name="mailboxService" ref="mailboxService" />
</bean>
</mvc:interceptor>
As you can see you can declare a path pattern and so exclude the URLs for which this isn't necessary.
Upvotes: 1
Reputation: 10075
If what you need is additional model attributes in most of your views i would go for the @ControllerAdvice annotation. There you can declare methods annotated with @ModelAttribute and this will be called on each controller call.
This can lead to some overhead so keep it simple and fast ;)
Upvotes: 1
Reputation: 6111
If I got your Question properly, you need some list object whose values you need to get displayed in all view pages at left/right side.
If that list values(table from where list is getting populated) is not changing frequently then you can hit Query once and get your list ready only once, then you can set that list as Session Variable, So that you can fetch it directly at View Layer.
Based on you correct requirement, you can go some similar requirement if this doesn't work.
Upvotes: 0