Posts Tagged ‘spring mvc’

Why Did I Want a JSON View Resolver?

Friday, September 11th, 2009

In my previous post, I documented a scenario that I encountered while setting up a JSON view resolver in a Spring MVC project.  Let me take a step back and explain my motivations for why I wanted a JSON view resolver.

In any Spring MVC application, Controller classes are responsible for processing some data, then returning a ModelAndView .  Typically views eventually return HTML either directly from a JSP or through a templating framework like Tiles.  However, custom views  can provide output such as Excel or PDF files.  In my case, I wanted an easy way to return a JSON response from certain Controller methods that would be called from an Ajax request.

HTML is a perfectly valid response to an Ajax request; often the Javascript processes an HTML response and then inserts the HTML into a page.  But occasionally JSON makes more sense, like when a page simply needs to know something about what is going on back on the server without displaying anything to the user(for example, whether the user has a valid session that has not timed out).  JSON is the native format of Javascript, so it is a convenient way to return a response to a Javascript client.

I found a great project called Spring Json View that offers all the features of Spring MVC like validation, exception handling, and error handling and automatically converts the Model to a JSON object.  It was probably a bit more than I needed for what I was trying to accomplish, but I was working on an internal company project and one of our secondary goals was to build skills and identify patterns that would be useful on future projects.  So I tested it out for this simple scenario, and I expect that this pattern could be useful on future projects.

Check out the configuration snippets from my previous post to see how I integrated Spring Json View into Spring MVC.

Also, here’s a quick example of how a controller method can use it:

@RequestMapping(method = RequestMethod.GET)
public ModelAndView isLoggedIn(ModelMap model) {
model.addAttribute("loggedIn",
!SecurityContextHolder.getContext().getAuthentication().getName().equals("guest"));
return new ModelAndView("jsonView", model);
}

Spring MVC Custom Property Editors

Thursday, January 22nd, 2009

From my experience, one of the initially frustrating things in Spring MVC was figuring out how to use a Property Editor correctly.

The idea is simple. You want to be able to convert back and forth between Java objects and their String representations. For example, let’s say you are making an internal website for a company and you want to display a list of employees. You want to be able to select an employee from the drop-down list, submit a form, and do some operation on the selected employee. Property Editors allow you to convert between your Employee objects and their String representations in the list. Spring has a number of built-in Property Editors, but for an Employee object, we will have to create a custom Property Editor to make this conversion. I found the official Spring documentation on this subject to be good, but a bit confusing on this subject.

Using Spring MVC with annotations, there are five concepts that will work together to achieve our desired goal.

1. There is an Employee object with this structure:

public class Employee {
private Long employeeID;
private String name;
} 

2. In the controller, we want to get a list of Employee objects and create a Model Attribute for use in the drop-down on the JSP:

@ModelAttribute("employees")
public List initEmployees()   {
return employeeDAO.getEmployees();
}

3. In the JSP, we want to be able to populate a drop-down list with the Employee objects and perform an operation on one of them. The drop-down on the JSP looks like this:

<form:select path="employee">
<form:options items="${employees}" itemValue="employeeID" itemLabel="name" />
</form:select>

4. Next we create the custom Property Editor. The setAsText(String) method overrides the default implementation in the PropertyEditorSupport class and will read in the selected employeeID from the drop-down list and convert it back to the appropriate Employee object.

public class EmployeeNamePropertyEditor extends PropertyEditorSupport {
EmployeeDAO employeeDAO;

public EmployeeNamePropertyEditor(EmployeeDAO employeeDAO)   {
this.employeeDAO = employeeDAO;
}

public void setAsText(String text)   {
Employee employee = new Employee();
employee = employeeDAO.getEmployee(Long.parseLong(text));
setValue(employee);
}
} 

5. The last change is in the controller class. We need to register this Property Editor and associate it with the Employee object in every controller where we will need to make the conversion.

@InitBinder
public void initBinder(WebDataBinder binder)    {
binder.registerCustomEditor(Employee.class, new EmployeeNamePropertyEditor(employeeDAO));
} 

After completing these steps, you should be able to properly configure a Property Editor for use with any Object that you like.

Chaining Spring View Resolvers

Friday, December 12th, 2008

Take this example of chaining view resolvers:

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="/WEB-INF/views.xml"/>
<property name="order" value="1"/>
</bean>

And this views.xml:

<beans><bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView"/></beans>

This should evaluate each view through the XmlViewResolver, then default back to the UrlBasedViewResolver if the XmlViewResolver does not find a view.

Now, let’s say we have the following tiles definition:

<definition name="forecastOverviewReport" extends=".mainTemplate" >
 <put-attribute name="pageHeader" value="Forecast Overview"/>
 <put-attribute name="body" value="/WEB-INF/jsp/forecastOverviewReport.jsp"/>
</definition>

Looks pretty good.

Now, what if we, by coincidence, have this bean definition?

<bean id="forecastOverviewReport" class="com.credera.forecasting.reporting.ForecastOverviewReport">
<property name="employeeDAO" ref="employeeDAO"/>
</bean>

Uh oh. The XmlViewResolver will find the bean definition above (even though it’s not in the views.xml which was explicitly specified!), and give you this lovely error:

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'forecastOverviewReport' must be of type [org.springframework.web.servlet.View], but was actually of type [com.credera.forecasting.reporting.ForecastOverviewReport]

But without the XmlViewResolver, this would have been perfectly fine. So, if you are chaining in an XmlViewResolver, make sure none of your tiles definition names are the same as any bean definition ids.