Spring under the hood

April 10, 2011

Writing a simple web application using Spring MVC template

Filed under: Hibernate, Spring, JQuery — Administrator @ 12:48 pm

Based on the template we created let us start implementing a Spring MVC application, the application has a web interface, where given a brand it will display all the cars for that brand. To download the sample, click here. Download and import the pom.xml in STSIDE.

The car POJO looks as below,

@Entity
public class Car implements java.io.Serializable {
private String brand;
private String model;
private long Id;
//
private static final long serialVersionUID = 1L;
//
@Id
public long getId() {
return Id;
}
//
public void setId(long id) {
Id = id;
}
//
@Column
public String getBrand() {
return brand;
}
//
public void setBrand(String brand) {
this.brand = brand;
}
//
@Column
public String getModel() {
return model;
}
//
public void setModel(String model) {
this.model = model;
}
}

Once you defined the POJO you don’t need to do anything else, based on the configuration below in the root-context.xml,

<prop key="hibernate.hbm2ddl.auto">create-drop</prop>

When the SpringSource TC Server starts it will automatically create the database and the db schema with the entity name. In our case we have used hsqldb inmemory database.

CarDao interface and CarHibernateDao implementation is as below,

public interface CarDao {
List getCars(String brand);
//
List getCars();
}
//
@Repository
public class CarHibernateDao extends HibernateDaoSupport implements CarDao {
@Autowired
public void init(SessionFactory factory) {
setSessionFactory(factory);
}
//
public List getCars(String brand) {
return getHibernateTemplate().find("from Car car where car.brand=?", brand);
}
//
public List getCarBrands() {
// TODO Auto-generated method stub
return getHibernateTemplate().find("select distinct car.brand from Car car");
}
}

CarService interface and CarSerivceImpl implementation is as below,

public interface CarService {
List getCars(String brand);
//
List getCarBrands();
}
//
@Service
public class CarServiceImpl implements CarService{
@Autowired
CarDao carDao;
//
public List getCars(String brand) {
// TODO Auto-generated method stub
return carDao.getCars(brand);
}
//
public List getCarBrandss() {
// TODO Auto-generated method stub
return carDao.getCars();
}
}

Controller code looks as below,

@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {
logger.info("Welcome home!");
//
return "index";
}
//
@RequestMapping(value = "/indexResponse", method = RequestMethod.GET)
public void indexResponse(HttpServletResponse response, @RequestParam String brand) throws JSONException, IOException {
logger.info("in indexResponse!");
//
List cars = carService.getCars(brand);
JSONArray array = new JSONArray();
//
for (Object obj : cars) {
Car car = (Car) obj;
JSONObject json = new JSONObject();
json.put("brand", car.getBrand());
json.put("model", car.getModel());
array.put(json);
}
handleJSONResponse(response, array.toString());
}
//
@RequestMapping(value = "/listCarsBrand", method = RequestMethod.GET)
public void listCarsBrand(HttpServletResponse response) throws JSONException, IOException {
logger.info("in listCars!");
//
List cars = carService.getCarBrands();
JSONArray array = new JSONArray();
//
for (Object obj : cars) {
String brand = (String) obj;
JSONObject json = new JSONObject();
json.put("brand", brand);
array.put(json);
}
handleJSONResponse(response, array.toString());
}
protected void handleJSONResponse(HttpServletResponse response, String jsonString) throws IOException {
response.setContentType("application/json;charset=UTF-8");
PrintWriter out;
out = response.getWriter();
out.print(jsonString);
out.flush();
}

WEB-INF/views/index.jsp file looks as below,

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>spartanjava.com - Simple JSON sample</title>
<script src="${pageContext.request.contextPath}/static/jquery/jquery.min.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/static/js/scripts.js" type="text/javascript"></script>
</head>
<body>
<form>
<select id="brand">
</select>
<input id="butt1" type="button" value="List" />
</form>
<ul id="carList">
</ul>
</body>
</html>

The JQuery script looks as below,

$(document).ready(function() {
$("#butt1").click(function () {
listCars();
});
$("#brand").click(function () {
$.getJSON('/myTestSpring/listCars', {
}, listCarsCallback1);
});
});
function listCarsCallback1(data) {
var listHTML = "";
$.each(data, function(i, car) {
listHTML += "“;
});
$(”#brand”).html(listHTML);
}
function listCars() {
var brand = $(”#brand”).val();
$.getJSON(’/myTestSpring/indexResponse’, {
“brand” : brand
}, listCarsCallback);
}
function listCarsCallback(data) {
var listHTML = “”;
$.each(data, function(i, car) {
listHTML += “<li>” + car[”model”] + “</li>”;
});
$(”#carList”).html(listHTML);
}

Configuring Spring MVC application to work with Hibernate using Spring MVCProject in STS IDE

Filed under: Spring — Administrator @ 12:07 pm

The best way to write Spring MVC based application is to use STS IDE Ver 1.5 and above.

In this write up, I will show you is how to configure the application to use Hibernate, Spring ORM, so that we can write a dynamic web application using HSQL inmemory or file database. I will also show you how to configure to write a simple Ajax based application using JQuery, JSON with Spring MVC.

To start go to File->New -> Spring Project Template -> Spring MVC Project, give a project name and give the package name as com.hcl.springtest you are all set. It also gives you a pom.xml file, so incase you want to use it for deployment to different environment it is easy. It only has Spring MVC 3.x jar files included, and does not have any other jars.

To configure the pom.xml to use Hibernate is as below,

<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.5.6-Final</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>transaction-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<!--- THIS LINE IS TO CONFIGURE JSON ---/>
<dependency>
<groupId>json</groupId>
<artifactId>org.json</artifactId>
<version>1.0</version>
</dependency>
<!--- THIS LINE IS TO CONFIGURE HSQLDB---/>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.0.0</version>
</dependency>

In WEB-INF/spring/root-context.xml file, you need to add the below config information,

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:mem:DAOUnitTest" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--- THIS IS THE MAGIC TO SCAN ALL THE POJOS AND AND CREATE THE DATABASE WHEN THE TOMCAT SERVER STARTS ---/>
<property name="packagesToScan" value="com.hcl.springtest" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
<!--- BELOW CONFIGURATION IS WHEN THE SERVER STARTS THE DATABASE WILL ALWAYS BE CREATED AS NEW AND THE SCHEMA IS REGENERATED--->
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>

Replace WEB-INF/spring/appServlet/controller.xml with the below content,

From:
<context:component-scan base-package="com.hcl.springtest.controller" />
To:
<context:component-scan base-package="com.hcl.springtest" />

Once this is in place, we are ready to develop a Spring MVC application. In my next writeup, I will show you how to write the application.

March 24, 2011

SimpleMappingExceptionResolver: centralized way to manage Ajax and Html error responses

Filed under: Spring — Administrator @ 10:23 am

This example demonstrate how we can manage server exception as meaningful response to end users.

The changes we need to do in the spring context file to handle this:

<bean class="com.hcl.exceptionresolver.CustomMappingExceptionResolver">
</bean>

The actual implementation looks as below:

public class CustomMappingExceptionResolver extends SimpleMappingExceptionResolver {
//
private static Log logger = LogFactory.getLog(CustomMappingExceptionResolver.class);
private static final String STANDARD_ERROR_CODE = "999999";
private static final String STANDARD_ERROR_DESCRIPTION = "Java Exceptions";
private static final String REQUEST_HEADER_TYPE = "accept";
private static final String REQUEST_HEADER_TYPE_JSON = "application/json";
private static final String REQUEST_HEADER_TYPE_HTML = "text/html";
private static final String EXCEPTION_TYPE = "exception";
private static final CharSequence REQUEST_HEADER_TYPE_XML = "xml";
//
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
//
LocalServiceException serviceException = new LocalServiceException(STANDARD_ERROR_CODE, STANDARD_ERROR_DESCRIPTION, ex);
//
String errorView = "jsonerror";
if (request.getHeader(REQUEST_HEADER_TYPE).contains(REQUEST_HEADER_TYPE_JSON)) {
logger.debug("this is JSON request");
errorView = "jsonerror";
} else if (request.getHeader(REQUEST_HEADER_TYPE).contains(REQUEST_HEADER_TYPE_HTML)) {
logger.debug("this is HTML request");
errorView = "htmlerror";
} else if (request.getHeader(REQUEST_HEADER_TYPE).contains(REQUEST_HEADER_TYPE_XML)) {
logger.debug("this is XML request");
errorView = "xmlerror";
}
ModelAndView modelAndView = new ModelAndView(errorView);
modelAndView.addObject(EXCEPTION_TYPE, localServiceException);
return modelAndView;
}
}

The tiles.xml looks as below:

<definition name="jsonerror" template="/WEB-INF/view/errors/errorjson.jsp"></definition>
<definition name="htmlerror" template="/WEB-INF/view/errors/errorhtml.jsp"></definition>
<definition name="xmlerror" template="/WEB-INF/view/errors/errorxml.jsp"></definition>

The jsp pages like as below:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json");
%>
{
"errorCode" : "<c:out value="${exception.errorCode}"/>",
"errorDescription" : "<c:out value="${exception.errorDescription}"/>",
"uniqueIdentifier" : "<c:out value="${exception.uniqueIdentifier}"/>",
"stackTrace" : "<c:out value="${exception.JSONStackTrace}"/>"
}

When your controller throws an exception, the exception resolver will intercepts it and show a polite HTML response or a JSon resource based on the respective requests.

Next Page »

Powered by WordPress