Spring MVC, Security + Hibernate + DWR, Let's PLay
OK, time for DWR ;)
the DWR servlet and Spring configuration:
in you web.xml edit the line to add a new file called dwr-context.xml
<param-value>/WEB-INF/applicationContext.xml,/WEB-INF/hibernate-context.xml,/WEB-INF/dwr-context.xml</param-value>
and add the DWR servlet and associate it with /dwr/* requests.
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
dwr-context.xml:
under /WEB-INF create a new file called dwr-context.xml, the file will configure the integration points between Spring and DWR.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<dwr:configuration />
<dwr:annotation-config id="dwrAnnotationConfig"/>
<dwr:annotation-scan base-package="com.mtz.spring.dto"/>
</beans>
this file defines three configurations:
1- a default dwr configuration: the default configurations is fine as we are relying mostly on annotatios.
2- annotation config: DWR will scan spring beans for certain annotations.
3- annotation scan: DWR will scan the class path for certain annotations.
simply, if you have service class and want this service to be exposed to dwr you have two options, either, create a spring bean or let dwr scan its path, both ways, those classes had to have certain annotations.
the User class
as the User is under the package
com.mtz.spring.dto and no Spring beans were (and mostly will never) created from that class, we need DWR to scan the classes under this package.
the class has been mentioned before, what needs to be explained
@DataTransferObject: DWR will marshal and unmarshal this object using a certain converter, in our example it is
type="hibernate3", converter=H3BeanConverter.class, also for each property you need on the javascript object you have to expose it using the annotation
@RemoteProperty
DAO and Service
in the package
com.mtz.spring.dao
create the interface UserDAO
package com.mtz.spring.dao;
import com.mtz.spring.dto.User;
import java.util.List;
/**
*
* @author salemmo
*/
public interface UserDAO {
public User getUser(int id);
public User addUser(User user);
public User removeUser(User user);
public List<User> getAllUsers();
}
in the package
com.mtz.spring.dao
create the class UserDAOImpl
package com.mtz.spring.dao;
import com.mtz.spring.dto.User;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
/**
*
* @author salemmo
*/
public class UserDAOImpl implements UserDAO{
public User getUser(int id) {
Session session = sessionFactory.getCurrentSession();
User u = (User) session.get(User.class, id);
return u;
}
public User addUser(User user) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(user);
return user;
}
public User removeUser(User user) {
Session session = sessionFactory.getCurrentSession();
session.delete(user);
return user;
}
public List<User> getAllUsers() {
Session session = sessionFactory.getCurrentSession();
return session.createQuery("from User").list();
}
private SessionFactory sessionFactory;
/**
* @return the sessionFactory
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* @param sessionFactory the sessionFactory to set
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
in the package
com.mtz.spring.service
create the interface UserService
package com.mtz.spring.service;
import com.mtz.spring.dto.User;
import java.util.List;
/**
*
* @author salemmo
*/
public interface UserService {
public User getUser(int id);
public User addUser(User user);
public User removeUser(User user);
public List<User> getAllUsers();
}
in the package
com.mtz.spring.service
create the class UserServiceImpl
package com.mtz.spring.service;
import com.mtz.spring.dao.UserDAO;
import com.mtz.spring.dto.User;
import java.util.List;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author salemmo
*/
@RemoteProxy
public class UserServiceImpl implements UserService{
@RemoteMethod
@Transactional
public User getUser(int id) {
return getUserDAO().getUser(id);
}
@Transactional
@RemoteMethod
public User addUser(User user) {
return getUserDAO().addUser(user);
}
@Transactional
@RemoteMethod
public User removeUser(User user) {
return getUserDAO().removeUser(user);
}
@Transactional
@RemoteMethod
public List<User> getAllUsers() {
return getUserDAO().getAllUsers();
}
private UserDAO userDAO;
/**
* @return the userDAO
*/
public UserDAO getUserDAO() {
return userDAO;
}
/**
* @param userDAO the userDAO to set
*/
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
the important things to know about the UserServiceImpl are the annotations.
@RemoteProxy: tells DWR that you want this service to be exposed.
@RemoteMethod: tells DWR that you want this method to be exposed.
@Transactional: tells hibernate that you want this method to run in transaction.
Wrap it up in the applicationContext.xml
edit your applicationContext.xml to add the service bean
<bean class="com.mtz.spring.dao.UserDAOImpl" id="userDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean class="com.mtz.spring.service.UserServiceImpl" id="userService">
<property name="userDAO" ref="userDAO"/>
</bean>
edit hello.jsp
edit /WEB-INF/jsp/hello.jsp to make use of DWR
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%
String contextPath=request.getContextPath();
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type='text/javascript' src='<%=contextPath%>/dwr/engine.js'></script>
<script type='text/javascript' src='<%=contextPath%>/dwr/interface/UserServiceImpl.js'></script>
<script type='text/javascript' src='<%=contextPath%>/dwr/util.js'></script>
<title>Welcome to Spring Web MVC project</title>
<script type="text/javascript">
function goGetit(){
UserServiceImpl.getUser(document.getElementById("userid").value, {
callback:function(user) {
document.getElementById("userage").value=user.age;
document.getElementById("username").value=user.name;
}
});
}
function goSaveit(){
var user= {
id: document.getElementById("userid").value,
age:document.getElementById("userage").value,
name:document.getElementById("username").value
};
UserServiceImpl.addUser(user, {
callback:function(user) {
var useraction = (document.getElementById("userid").value=="")? "added":"altered";
document.getElementById("message").innerHTML = "User "+useraction+" with the ID: "+user.id;
getAllUsers();
}
});
}
function goRemoveit(){
var user= {
id: document.getElementById("userid").value
};
UserServiceImpl.removeUser(user, {
callback:function(user) {
document.getElementById("userid").value="";
document.getElementById("userage").value="";
document.getElementById("username").value="";
document.getElementById("message").innerHTML = "User removed with the ID: "+user.id;
getAllUsers();
}
});
}
function getAllUsers(){
UserServiceImpl.getAllUsers({
callback:function(users) {
var cellFunctions = [
function(user) { return user.id; },
function(user) { return user.age; },
function(user) { return user.name; }
];
dwr.util.removeAllRows("allusers");
dwr.util.addRows( "allusers", users, cellFunctions,{ escapeHtml:false });
}
});
}
</script>
</head>
<body onload="getAllUsers()">
<H2>Hello! This is the default welcome page for a Spring Web MVC project.</H2>
<h3>${message}<h3/>
<input type="text" id="userid"><input type="button" value="Get User By ID" onclick="goGetit();"/>
<hr width="70%"/>
<div id="message"> </div>
<table>
<tr>
<td>Age:</td>
<td><input type="text" id="userage"></td>
</tr>
<tr>
<td>Name:</td>
<td><input type="text" id="username"></td>
</tr>
<tr>
<td><input type="button" value="Add/Edit User" onclick="goSaveit();"/></td>
<td><input type="button" value="Remove User" onclick="goRemoveit();"/></td>
</tr>
</table>
<hr width="70%"/>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Age</th>
<th>Name</th>
</tr>
</thead>
<tbody id="allusers"> </tbody>
</table>
</body>
</html>
Test it
deploy the project and you should see the following page
Next - Configuring Spring Security