Spring being one of the most customizable framework, provides an ability to plug in a custom view resolver.
Assume if the web application uses a particular JSP for festive time, having links or logic for some offers while other is vanila JSP page rendering response. I will demonstrate you how to achieve smooth transition in JSPs without messing up your controller return values and thus code release.
I will be using the code base from my previous example here.
Gist -> What we are trying to do here is to have an XML file for mapping ModelAndView response from our controller with the actual JSP file, that is some what like adding Struts flavor to Spring MVC. Lets see how can we achieve this. (Ohh! you are too impatient ? Download project)
So here we go ->
I would be using JAXB to marshal & unmarshal the XML and our object. So lets quickly create a XML file, and then we would deal with JAXB stuff.
viewMapping.xml ->
<?xml version="1.0"?> <!DOCTYPE viewMappings [ <!ELEMENT viewMapping (sourcePage, destinationPage)* > <!ELEMENT sourcePage (#PCDATA)> <!ELEMENT destinationPage (#PCDATA)> ]> <viewMappings> <viewMapping> <sourcePage>pranam</sourcePage> <destinationPage>index</destinationPage> </viewMapping> <viewMapping> <sourcePage>namaste</sourcePage> <destinationPage>hello</destinationPage> </viewMapping> </viewMappings>
Step 2. Update your springMVC-servlet.xml file to point to a custom View Resolver –
<bean id="viewResolver" class="com.roadtobe.supaldubey.examples.spring.web.CustomViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
Below is our very own view resolver that tries to map ModelAndView response viewName with our actual JSP page using our XML –
public class CustomViewResolver extends org.springframework.web.servlet.view.InternalResourceViewResolver { private static final String VIEW_MAPPING_XML = "/viewMapping.xml"; private Map<String, String> mapping = new HashMap<String, String>(); public CustomViewResolver() { super(); ViewHolder viewHolder = JAXB.unmarshal(getClass().getResourceAsStream(VIEW_MAPPING_XML), ViewHolder.class); for (CustomViews view : viewHolder.getCustomViews()) { mapping.put(view.getRequestedView(), view.getTargetView()); } viewHolder.getCustomViews().clear(); } @Override protected View loadView(String viewName, Locale locale) throws Exception { if (mapping.get(viewName) != null) { viewName = mapping.get(viewName); } AbstractUrlBasedView view = buildView(viewName); View viewObj = (View) getApplicationContext().getAutowireCapableBeanFactory() .initializeBean(view, viewName); return viewObj; } }
Here, we are taking the viewName as returned by our controller and are using
the name to generate our own JSP view. We are using our XML mapping to fetch the JSP name
using the view name. Isn’t it simple. 🙂
Tweak our controller a bit to get a fair idea of what’s happening –
@RequestMapping("welcome") public ModelAndView welcome(@RequestParam(value = "name", required = false, defaultValue = "Supal Dubey") String name) { Map<String, String> model = new HashMap<String, String>(); model.put("user", name); model.put("returnedPage", "namaste"); return new ModelAndView("namaste", model); }
Next, modify our JSP to print the server return –
<html> <head> <title>Supal Dubey! Spring MVC Demo</title> </head> <body> Hello ${user}! Page returned by controller is ${returnedPage}. </body> </html>
Also do not forget to create a Java Object to hold this mapping.
CustomView.java ->
public class CustomViews { @XmlElement(name = "sourcePage") private String requestedView; @XmlElement(name = "targetPage") private String targetView; //... Getters and Setters. //Do not forget to override equals & hashcode
[ad#in-blog]
That’s all, now when ever you need to point to different JSP, just change the XML mapping and bounce the server.
And Yeah!! Last and surely not least Make sure that your mapping file is in your classpath. 😉
Drop a comment in case you have any questions.
8 Comments
mbt toning · July 26, 2012 at 9:00 am
Wow! Thank you! I continuously wanted to write on my website something like that. Can I implement a part of your post to my website?
Supal Dubey · July 26, 2012 at 12:44 pm
Yes please! I would also be happy if you can give credit for the part. Don’t be evil ! 🙂
bridal jewelry · July 27, 2012 at 3:11 pm
high quality wedding dress, Interested in the contents of your content is very lovable’s a I Purchase of high quality wedding, your content, I really like post.
Keneth Kazmer · September 3, 2012 at 7:36 pm
I simply want to say I am just beginner to weblog and honestly liked you’re blog site. Very likely I’m want to bookmark your blog post . You actually come with superb well written articles. Appreciate it for sharing your website.
brisbane · September 14, 2012 at 2:12 pm
Hello, I just hopped over to your web page via StumbleUpon. Not somthing I would usually browse, but I appreciated your thoughts none the less. Thanks for making something well worth browsing.
duplicate contacts · September 23, 2012 at 5:05 pm
Is it alright to put a portion of this in my web site if I publish a reference point to this site?
Supal Dubey · September 23, 2012 at 5:14 pm
Yes please ..
Callie · February 20, 2013 at 4:32 am
“Supal Dubey! Tech, Web, Fun – Creating a custom View Resolver in Spring MVC” ended
up being a superb blog. If only there were significantly
more weblogs like this one on the web. Anyways, thanks a lot
for your personal time, Jere