Showing posts with label Web Framework. Show all posts
Showing posts with label Web Framework. Show all posts

Tuesday, February 27, 2018

Paging and Sorting using Spring Boot

Picture Credit : Pixabay


Please follow Rest API Server to see the big picture and GitHub repo details.

Paging and Sorting is an important use case for any application. Any web or mobile frontend, a listing will usually need such a capability.

To support Paging and sorting in a Spring boot application, we need to do the following.

The Spring data repository interface

Sunday, August 17, 2014

JSP - Developing Custom Tag

Custom tags are useful as they help in exposing business functionalities to page designers in a simple way. At runtime the tags are converted into java calls when the jsp page is translated into servlet.

There are two ways of developing tags:
  • Developing tag logic in plain files.
  • Developing tag logic using Java classes.

We will look into the way of developing the tag logic using Java classes as it is more powerful and flexible and provides tool support at development time.

To implement a tag the first thing to do is to write a class which implements SimpleTag interface. However there is a utility class which can be used to extending our tag class and provides default implementation for the interface functions.

HelloTag.java:

public class HelloTag extends SimpleTagSupport {

      public String name = "world";

      public void setName(String name){
         this.name= name;
     }

     public void doTag()throws IOException{
         this.getJspContext().getOut().println("Hello " + name);
      }
}

This class is a bean class having one property. Now we want to expose this tag and want to expose the property as an attribute of tag. For that we have to write a tld file and place it at WEB-INF/tlds folder. Let's put helloTag.tld helloTag.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
     <tlib-version>1.0</tlib-version>
     <short-name></short-name>
      <uri>com.crayom.helloTag</uri>
      <tag>
           <name>helloTag</name>
          <tag-class>com.crayom.HelloTag</tag-class>
         <body-content>empty</body-content>
         <attribute><name>name</name></attribute>
      </tag>
</taglib>

Our tag is ready and raring to be used. Let's write a jsp where we use this tag.

<%@taglib prefix="hello" uri="com.crayom.helloTag" %>
<html>
        <body>
                <hello:helloTag name="Lalit"/>
       </body>
</html>

Deploy your application and hit the jsp. When the jsp is translated into servlet the tag code is replaced with following:

HelloTag helloTag = new HelloTag();
helloTag.setJSPContext(context);
helloTag.setParent(null);

//As there is no parent
helloTag.setName(“Lalit”);

//helloTag.setJspBody(new JspFragment(...)) - This is not called as body is empty
helloTag.doTag();

Container calls the setJspContext() method to provide the context information in the form of JspContext instance. JspContext provides access to all the JSP scope variables and the current output stream for the page and it implements a number of utility methods the tag handler may use. In the tld you would have notices the we have written body-content is empty. It means is that we do not have body in the tag. That's the reason that in the trasnlated jsp code the setJspBody method is commented. When the body is presented it is set by calling the setJspBody.The body is treated as JspFragment and passed to the tag class by calling public void setJspBody(JspFragment body) The container calls this method with a reference to a JSP fragment representing the custom action body before calling the doTag(). Again if the custom action doesn’t have a body this method is not called at all. The body is evaluated by calling the invoke method on the JspFragment object. If we want to manipulate the body we have to pass a String writer to the invoke method. The body is written on the StringWriter which can than be manipulated.

Which is the best web framework

Which is the best web framework in Java world is one of the most debated topic. It's actually a highly debated topic even outside of Java but we will concentrate on Java based web frameworks. There are endless debates on this issue in project teams of all levels and people fight for it for life and death. There are people who are even happy to adopt a framework agnostic approach as it gives them more flexibility or they think so.

First let's dwell on the question of whether to use framework or not. I think there are two arguments that go in favor of no framework approach.


  • Working with plain servlet and JSP gives you the flexibility. There are situations while using in framework where certain features are not there or not in the way you want them to be. Than getting the things you desire becomes a pain and it leads to a lot of tweaking. With Servlet and JSP everything is in your control.
  • Working with plain servlet and JSP gives you performance advantages. Frameworks are written more generically and try to handle a lot of situation. But this bloats the code and hits the performance.

However before you venture into the plain servlet and JSP approach, remember that eventually for non trivial application you will land up something similar to a framework. There are usually many boiler plate patterns, for handling of them you will start up writing your own proprietary framework. Then the following question comes

  • How many good developers you have got to handle these infrastructural framework development? Present day web development is not trivial. There are internationalization, AJAX, rich GUI features which are reasonably complex.
  • How long these developers are going to be employed with you? What if some critical people leave than can you handle the situation?
  • The proprietary in house developed framework usually lack good documentation and wide community support. This makes the ramp up of new developers very difficult.
  • Eventually you will land into a situation where your own framework will start hindering your own development because of the lack of flexibility. Don't assume that you will be able to handle all the complexity in a reasonable way. This argument is a self sustaining argument and a sweet trap.
  • Do you and your team better of spending their time writing business level code or infrastructural code? Better value for money.

Even than if you want to go for plain servlet and JSP approach, give it a deep thought many times before you convince yourself about the path you are going to take.

Now let's assume that you have decided that you want to go for one of the framework. Let's understand how the landscape of frameworks span. Fundamentally we can divide the web frameworks in three broad categories:


- MVC type frameworks: Prevents you from low level request and response processing. Struts was the undisputed king here but Spring MVC is making good inroads here. he idea here is that you donot have to do low level request and response processing. The request is parsed by the framework and sets the parameter values present in the request to attributes in java objects based on certain defined mapping. Similarly the response is created from java objects based on some mapping. Apart from that the action mapping is done which basically means that which request is handled by which method of which class. In Servlet and JSP world usually these mappings are done either by mapping servlet/jdp in web.xml based on url pattern or hitting the jsp's directly. Currently in Spring 3+ the MVC part has been completely reorganized especially using the annotation based approach. It has made, writing web applications much easier.


- Component based frameworks: It adopts more swing like programming model where you think more in terms of components and event handlers. The space is quite open. The prominent names are JSF, wicket and tapestry.In JSF itself there are many libraries. The idea here is that as a developer you basically choose your components and than bind them to the backing beans. For example the value in an input box is set as an attribute of an object and click of a button results in a method call in another object based on mapping. The low level Request Response processing is handled by the framework.


The approach here is to go to component based framework and having pages in pure html.These frameworks do have little steep learning curve but bring productivity. However be careful about the performance especially many of these frameworks provide statefulness behaviour which can quickly eat your resources. However the UI space is very rich here. Check Richfaces and Icefaces. JSF2.0 has also brought many new changes especially supporting Http GET.


There is another one vaadin also which comes in this category. I have not played with it but it seems to be a choice to evaluate.


- Javascript and HTML generator - There are third set of frameworks which provide a pure Java way of writing. GWT is one of the leading framework in this. The code is written in pure Java. There are compilers than, which convert the Java code into HTML and Javascript. They can provide very good response time to end users as a lot of code can be easily pushed to client side.


- Javascript based Single page applications - Here the front end is completely build using Js frameworks like Angular and it interacts with the back end using rest style web services and using JSON data.


At the end, I am sure you are looking for a crisp answer to which one to adopt. Unfortunately I have no simple answer to that, and I have found different frameworks useful for different situations. I will try to put some situations and the choices and the reason behind them


In almost all the situations, I would not go for a pure JSP and servlet strategy. I still cannot think of a good reason for that strategy.


If the client has something specific in mind and does not want to change the mind. The reason could be there existing stack of technology or cost consideration or that their best Beer buddies think that way, you have no choice. (Believe me, I have atleast seen one case where I thought the other choice was much better but just that one of the client's best friend thought the other way, it went the other way).


One of the strong parameter of choice is usually based on what kind of developers are available. If we have a formula one team on GWT or on JSF and there are no other special requirements, I would settle on that. It's about playing on the strength of the team.


If we do not have an existing team and we have to build one. Also the application is a standard web application with normal expectations in user about how web applications behave. One of the important behavior parameter is a slightly lagging response time. Than MVC would be a good choice. The learning curve is faster. A good choice can be Spring MVC with Spring as the backend. This provides a consistent framework to work with.


If we are looking for very rich UI and the application does not have a very strict performance requirement, JSF is a good choice. JSF libraries provide very rich UI interfaces but they carry a lot of data. Also the learning curve is steep here. However once you get a handle of it, it's very easy.


Than comes the situation when end user is looking for a desktop like behavior which basically means very fast response time. Than frameworks like GWT are a good choice. The other alternative is to use MVC frameworks and use Javascript frameworks like Dojo or jquery. Thought the learning curve of GWT is steep but it's much easier to maintain GWT based applications. A very fast response time usually means a lot of javascript code and which can easily become a maintainance headache. It's better to adopt something like GWT which can generate the code automatically.


There is one more trend you might want to check before taking the final decision. It's coming in the name of HTML5 especially the ability to provide a database at browser. But that path is still has to go some way before becoming stable. Even there is not enough consistent support from browsers.


So Good luck with your choice.

Tuesday, August 12, 2014

Spring MVC before Spring 3.0

****This article is relevant for Spring 2.5 and lesser version. Spring 3.0 has an annotation way of doing things.*****

Spring MVC is a web framework to handle web requests using Model View Controller pattern. Spring MVC works around a DisptacherServlet which handles all the request. If you take any web request than the fundamental steps required to process a request is as follows. The request is recieved in the form of Http request from client browser. The request is converted into a HttpRequest object and passed to a Servlet. In the case of Spring it is DisptacherServlet. The DispatcherServlet consults a handler mapping and decides the controller which is going to process the request. The request is processed by the controller and it returns a ModelAndView object. The ModelAndView contains both the Model and View. Model contains the data and view contains a logical id which can be resolved into an actual view which in most cases is a jsp file though there are many choices here. The view uses the Model data and generates the response which is returned back to the client browser.

Let's make a MVC application and look into differenet aspects of application. In this web application we have two page. In first page we will take the name of student and save it. The other page will list the Students.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>SpringMVC</display-name>

<!-- The parameter tells about the location of configuration XML. Usually
    all the data access beans and service layer beans are kept here. 
             You can register more than one XML here. 
             For multiple context file, use comma delimiter. 
             Please be careful that in case of multiple bean having same name the
             later one will override the earlier one. -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>

<!-- The listener is reponsible for building the spring container. 
             It looks for all configuration XML as defined by parameter contextConfigLocation 
             and also looks for a configuration which is named as Dispatch Servlet name. 
             In this case it will be named as springapp-servlet.xml -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<!-- Dispatcher Servlet which traps all the request targeted for Spring MVC -->
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<!-- Mapping for the request. It can be anything -->
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>

Now let's write the data access layer code. This is similar to Spring JDBC? classes . Right now we will be calling the data access layer code directly from front layer. In real life you might want to put one more layer of indirection by putting a service layer in the middle. Let's write the domain model class and the DAO access layer.
Student.java

/**
 * Java bean which will be used to save and retrieve data.
 *
 */
public class Student {
protected String name;
//Getters and setters
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

The DAO interface.

public interface StudentDao {
public void saveStudent(Student student);
public List<Student> getAllStudents();
}

The implementation of DAO. We will use plain JDBC at the moment.

public class StudentJdbcDao implements StudentDao {

protected SimpleJdbcTemplate simpleJdbcTemplate;
public void setSimpleJdbcTemplate(SimpleJdbcTemplate simpleJdbcTemplate) {
this.simpleJdbcTemplate = simpleJdbcTemplate;
}

@Override
public void saveStudent(Student student) {
simpleJdbcTemplate.update("insert into STUDENT (name) values (?)",student.getName());

}

@Override
public List<Student> getAllStudents() {
return simpleJdbcTemplate.query 
("Select name as Name from Student",
 new ParameterizedRowMapper<Student>(){
         public Student mapRow(ResultSet rs,int rowNum)
          throws SQLException {
         Student student = new Student();
         student.setName(rs.getString("Name"));
         return student;          
         }
 }
);
}
}

Register the dao class as bean in Spring. We will register them in applicationContext.xml. This is the configuration file which is referred by Spring from contextConfigLocation in web.xml
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<!-- The Dao class -->
<bean id="studentDao" class="com.oyejava.springmvc.StudentJdbcDao">
<property name="simpleJdbcTemplate" ref="jdbcTemplate" />
</bean>

<!-- Template class to access JDBC code -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>

<!-- Configuration for the data source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"    
     destroy-method="close">
   <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
   <property name="url" value="jdbc:hsqldb:hsql://localhost" />
   <property name="username" value="sa" />
   <property name="password" value="" />
</bean>
</beans>

Also let's write another configuration XML in WEB-INF directory. The name of this file will be springapp-servlet.xml. The pattern is <Dispatcher Servlet name in web.xml>-servlet.xml.
springapp-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="studentListController"
class="com.oyejava.springmvc.StudentListController">
<property name="studentDao" ref="studentDao" />
</bean>

    <!-- command class and command name are used to retrieve and set the 
value as name value pair in HttpRequest and Response. The form view
tells that when the request comes for this Controller than which
form to display in which user input can be taken. -->
<bean id="studentCreateController"
class="com.oyejava.springmvc.StudentCreateController">
<property name="studentDao" ref="studentDao" />
<property name="formView" value="createStudent" />
<property name="commandName" value="student" />
<property name="commandClass" value="com.oyejava.springmvc.Student" />
</bean>

<bean id="simpleUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/studentList.htm">studentListController</prop>
<prop key="/createStudent.htm">studentCreateController</prop>
</props>
</property>
</bean>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

</beans>

The spring context made of using the configuarion as referred by contextConfigLocation becomes the Global application context. The context created by configuration in springapp-Servlet context becomes the child context and refers to the bean in global application context. For example the studentCreateController bean refers to studentDao. studentDao bean is present in global application context.

The Web application startup process is that the Servlet container initializes the web application and then fires the contextInitialized event. ContextLoaderListener, which is a Listener, receives the event and creates the global WebApplicationContext. This is placed in ServletContext. Than the DispatcherServlet is initialized, creating its own WebApplicationContext and nesting it inside the global WebApplicationContext. Dispatcher servlet brings up all the components and does the wiring of dependencies. Now web application is ready to serve the request.

Let's now look into the controller class.

/**
 * The controller class which is used to take the user input and 
 * process the data at the backend
 */
public class StudentCreateController extends SimpleFormController {

protected StudentDao studentDao;

public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}

//The is object which is used to set the values when the form is 
//displayed first time
protected Object formBackingObject(HttpServletRequest request)
throws Exception {
Student student = new Student();
student.setName("Default Name");
return student;
}

//This method is called when the form is submitted by the user.
//The command class is Student so Spring automatically parses the
//HttpRequest object, retrieves the name value pair out of it and
//sets the properties in the command object.
protected ModelAndView onsubmit(Object command) throws Exception {
  Student student = (Student) command;
  studentDao.saveStudent(student);
  return new ModelAndView("redirect:/studentList.htm");
}
}

Also the controller for listing the student looks like:

//Listing of Students

public class StudentListController extends AbstractController {

   protected StudentDao studentDao;
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
   }
   // This issues a request to database through data access layer and
   //gets the list of students. The list of students is put inside a 
   //ModelAndView Object
    protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
     List<Student> studentList = studentDao.getAllStudents();

    //studentList - This is the logical view id and based on view resolve
    //will get converted into a physical view which can be a jsp file
    //students - This is the name of the parameter against which the list 
    //          will be stored.
    //This will be used in jsp file to access the student list object.
    //studentList - studentList object.
 return new ModelAndView("studentList","students",studentList);
    }
}

Controllers

We saw above two examples of Spring controller. Spring comes with a handful of controllers which are used to handle different kind of situations. The different controllers in Spring are:

  • AbstractController : It's the basic Controller and gives access to underlying HttpRequest and HttpResponse object. The ModelAndView object is returned from it. However you can build the response yourself, in that case return null in place of ModelAndView object.
  • MultiActionController : This controller can handle multiple requests using one Controller. The different request can be mapped to different methods of the controller.
  • AbstractCommandController : This follows command pattern. The request object is parsed and the values retrieved from request object is set to the command object. This controller is good for list kind of functioanlity where serach parameters can be set to command objects.
  • AbstractFormController : Provides Form submission support.
  • SimpleFormController : Provides more support for form submission. Provides support similar to AbstractFormController and beyond that supports the initial view to be shown and the view to which the request should go after success.
  • AbstractWizardFormController : Provides support for wizard kind of situation where the user can be directed to follow a pattern of pages to execute a specific task or workflow. For example booking of online tickets.


Handler Mapping

Now let's understand how DispatcherServlet comes to know that which controller should be invoked for a particular request. Spring again delegates this task to a handler mapper, which helps the DispatcherServlet to do the job. For example in the springapp-servlet.xml we have used the handler mapper with name simpleUrlMapping. The property list tells that for which type of url pattern which controller needs to be invoked. Spring again comes up with a handful of mapper adn you can have more than one mapper also existing. Differemnt handler mapping that come with Spring are:

  • BeanNameUrlHandlerMapping - The bean name is used as a URL pattern. For example we can configure our StudentListController as


<bean id="/studentList.htm" class="com.oyejava.springmvc.StudentListController">
   <property name="studentDao" ref="studentDao" />
</bean>

  • SimpleUrlHandlerMapping - As we have used in the example above. Maps the pattern to the controller. It is the preferred approach.
  • ControllerClassNameHandlerMapping – Maps controller to URL’s by using the controller’s class name as the basis for the URL. So our StudentListController will be mapped to /studentList.htm
View Resolver

Once the controller has processed the request and returns a logical view we need to map the logical view to the physcial view. In this case the View resolver comes into picture. The different view resolver that are provided by Spring are:

  • AbstractCachingViewResolver - Provides caching of view.
  • XmlViewResolver - Views are mapped using a XML file. The default file is WEB-INF/views.xml.
  • ResourceBundleViewResolver 0 Views are defined in properties file. The default properties file is views.properties.
  • UrlBasedViewResolver - Used when logical view directly map to the physical view.
  • InternalResourceViewResolver - As used in example above. Resolves the view as per the configuration.

To complete the exercise let's put the jsp files which are our actual views.
createStudent.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<body>
<form:form commandName="student">
<label for="name">Name:</label>
<form:input path="name" />
<input type="submit" value="Register" />
</form:form>
</body>
studentList.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<body>
<c:forEach items="${students}" var="student">
<tr>
<td>${student.name} <br/></td>
</tr>
</c:forEach>
</body>
Host the application on a server and hit the url of the application. You will be presented with a create student page and on submission will be taken to the listing of students.

Interceptor
Interceptors are like servlet filters but they act in front of controllers. They have three methods which can overridden. One method is executed before the handler, second one is called after the handler and third method is called when the complete request is finished.
Let' write the interceptor.
LoggingInterceptor.java :

public class LoggingInterceptor extends HandlerInterceptorAdapter {

private static Logger log = Logger.getLogger(LoggingInterceptor.class);

@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
log.info("Entered for processing request");
return true;
}

@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("Exited for processing request");
}
}
Register the interceptor in springapp-servlet.xml and register it with the handler:

<bean id="loggingInterceptor" class="com.oyejava.springmvc.LoggingInterceptor" />

<bean id="simpleUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref local="loggingInterceptor" />
</list>
</property>
<property name="mappings">
<props>
<prop key="/studentList.htm">
studentListController
</prop>
<prop key="/createStudent.htm">
studentCreateController
</prop>
</props>
</property>
</bean>

Internationalization and Localization

Spring supports locale handling in a easy way. It is pretty much similar to other framewroks and uses the properties file. Let's register the MessageSource from Spring in springapp-Servlet.xml

<bean id="messageSource" 
class="org.springframework.context.support.ResourceBundleMessageSource">
   <property name="basename">
     <value>messages</value>
   </property>
</bean>

This will look for properties file for a locale in the classpath with prefix messages. Each locale is resolved accordingly. For example the default locale file will be messages.properties and for german locale it will be messages_de_DE.properties. Spring checks the accepted locale as send by the client and does a close match. The locales can be set in all the browsers. It's also possible to change the default so that Spring looks for locale as a parameter name in request or gets the locale from session. Once this is done we can change our createStudent.jsp to pick the label name from locale. Let's write two properties file and put it at the root of source folder so that it comes in the classpath

messages.properties

name=Name
save=Save

messages_de_DE.properties

Name=Name
save=Außer

Now hit the application by putting the german locale on the top and than english locale on the top.

Validation

Spring provides validator mechanism which can be tied to controller. Let's write a validator which checks that the name of the student is not empty.
The validator class StudentValidator.java

public class StudentValidator implements Validator {

public boolean supports(Class clazz) {
return clazz.equals(Student.class);
}

// Actual validate method
public void validate(Object obj, Errors errors) {
//command object is also available
                Student student = (Student)obj;
//emptyField is resolved by looking into the properties file
//of locale. If it is not present than the fourth argument
//is used to display locale message     
                ValidationUtils.rejectIfEmptyOrWhitespace 
    (errors, "name", "emptyField","Field empty");
}
}

Register the validator with the controller

<bean id="studentCreateController" class="com.oyejava.springmvc.StudentCreateController">
   <property name="studentDao" ref="studentDao" />
   <property name="formView" value="createStudent" />
   <property name="commandName" value="student" />
   <property name="commandClass" value="com.oyejava.springmvc.Student" />
  <property name="validator">
<bean class="com.oyejava.springmvc.StudentValidator" />
  </property>
</bean>

Change the createStudent.jsp to handle error messages:

<body>
   <spring:hasBindErrors name="student">
<c:forEach var="error" items="${errors.allErrors}">
          <spring:message code="${error.code}" text="${error.defaultMessage}" />
</c:forEach>
    </spring:hasBindErrors> 

<form:form commandName="student">
<label for="name"><spring:message code="name" /></label>
<form:input path="name" />
<input type="submit" value=<spring:message code="save"/> />
</form:form>
</body>

Please see the following videos which cover the concepts:


Thursday, August 18, 2011

Seam Framework Introduction

The traditional web application development in Java is usually handled using three tier architecture. The web layer is handled by one framework, the middle layer is handled by another framework and data access layer is handled by third framework. There are certain overlaps here like you can use Spring for web and middle layer and wither hibernate or JDBC or one of other ORM tools. or You can go for Struts as front layer, home grown middle layer and than one of ORM or JDBC tool as data access layer.
This kind of architecture has impedance when the flow moves from one framework to another. The context of three layers are separate so you have to move a lot of data back and forth. Also this has resulted in teams getting divided into similar roles. This division has resulted more because of lack of smooth flow in layers. In fact, if you look closely in these type of architectures, a lot of efforts goes into this and a lot of bug arises out of this. For example the famous LazyInitializationException in Hibernate is a classic example and it has given a lot of patterns based on the kind of frameworks employed in different layers.
Seam uses JSF and EJB3.0 and provides its own integration mechanism. What it means is that a EJB3.0 stateless bean can act as a JSF backing bean. Apart from EJB, Seam can make any POJO to act like a backing bean. In the case of POJO, Seam takes the responsibility of transactions, interception, threading and security. Also Seam provides Conversation and Business Process context in addition to Session and other context present in existing web applications. Seam uses Richfaces or Icefaces in the JSF layer which brings the AJAX feature automatically.
Seam derives its name from its ability to seam the front end and the back end layer together transparently.
To summarize,
  • If you have decided to go for JSF and EJB3.0 as your front end and back end layer than Seam will provide the glue for both the frameworks. Seam replaces JSF managed Bean container with a Seam container and also understands EJB. This results in a smooth transition from one framework another.
  • Seam can use POJO in place of EJB beans and even can use Spring beans.
  • Seam also has integration if you are working with other web frameworks like Wicket or Tapestry.

seam-gen is a utility to set up a CRUD application against a data model. This makes an eclipse project also and supports JBoss. Before we move forward do the following:
Download Seam from download section of http://www.seamframework.org. Download the lated GA version. Unzip it and put at a location.
Set up H2 Database  as we will use it to set the data model and than build a seam application. Also you need JBoss server 
We will use the data model having Student, Course and a Many to Many association between Student and Course. The SQL to insert the datamodel is:
CREATE TABLE STUDENT(ID INT PRIMARY KEY, NAME VARCHAR(255),HEIGHT NUMBER(10));
CREATE TABLE COURSE(ID INT PRIMARY KEY, NAME VARCHAR(255));
CREATE TABLE STUDENT_COURSE(STUDENT_ID INT,COURSE_ID INT, Foreign Key(STUDENT_ID) references STUDENT(ID), Foreign Key(COURSE_ID) references COURSE(ID))
Now go to seam download folder and run the command. In Linux it is ./seam and in windows it is seam.bat. You have to give a command also to the script. Running ./seam help will show all the command possible with descriptions.First let's run the setup command which basically sets the properties for the seam.
./seam setup
SEAM_HOME: /home/lalit/Desktop/Data/examples/training/seam/refrences/jboss-seam-2.1.1.GA
Using seam-gen sources from: /home/lalit/Desktop/Data/examples/training/seam/refrences/jboss-seam-2.1.1.GA/seam-gen
Buildfile: /home/lalit/Desktop/Data/examples/training/seam/refrences/jboss-seam-2.1.1.GA/seam-gen/build.xml
init:
setup:
     [echo] Welcome to seam-gen :-)
    [input] Enter your Java project workspace (the directory that contains your Seam projects) [C:/Projects] [C:/Projects]
/home/lalit/Desktop/Data/examples/training/seam/eclipseCode
    [input] Enter your JBoss AS home directory [C:/Program Files/jboss-4.2.3.GA] [C:/Program Files/jboss-4.2.3.GA]
/home/lalit/Desktop/ProgramFiles/jboss-5.0.0.GA
    [input] Enter the project name [myproject] [myproject]
seamFirstProject
     [echo] Accepted project name as: seamFirstProject
    [input] Do you want to use ICEfaces instead of RichFaces [n] (y, [n])
n
    [input] skipping input as property icefaces.home.new has already been set.
    [input] Select a RichFaces skin [classic] (blueSky, [classic], deepMarine, DEFAULT, emeraldTown, japanCherry, ruby, wine)
    [input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support) [ear] ([ear], war)
ear
    [input] Enter the Java package name for your session beans [com.mydomain.seamFirstProject] [com.mydomain.seamFirstProject]
com.oyeJava.seamFirstProject
    [input] Enter the Java package name for your entity beans [com.oyeJava.seamFirstProject] [com.oyeJava.seamFirstProject]
    [input] Enter the Java package name for your test cases [com.oyeJava.seamFirstProject.test] [com.oyeJava.seamFirstProject.test]
    [input] What kind of database are you using? [hsql] ([hsql], mysql, oracle, postgres, mssql, db2, sybase, enterprisedb, h2)
h2
    [input] Enter the Hibernate dialect for your database [org.hibernate.dialect.H2Dialect] [org.hibernate.dialect.H2Dialect]
    [input] Enter the filesystem path to the JDBC driver jar [/home/lalit/Desktop/Data/examples/training/seam/refrences/jboss-seam-2.1.1.GA/lib/hsqldb.jar] [/home/lalit/Desktop/Data/examples/training/seam/refrences/jboss-seam-2.1.1.GA/lib/hsqldb.jar]
/home/lalit/Desktop/ProgramFiles/h2/bin/h2-1.1.111.jar
    [input] Enter JDBC driver class for your database [org.h2.Driver] [org.h2.Driver]
org.h2.Driver
    [input] Enter the JDBC URL for your database [jdbc:h2:.] [jdbc:h2:.]
jdbc:h2:tcp://localhost/~/test
    [input] Enter database username [sa] [sa]
    [input] Enter database password [] []
    [input] Enter the database schema name (it is OK to leave this blank) [] []
    [input] Enter the database catalog name (it is OK to leave this blank) [] []
    [input] Are you working with tables that already exist in the database? [n] (y, [n])
y
    [input] Do you want to drop and recreate the database tables and data in import.sql each time you deploy? [n] (y, [n])
[propertyfile] Creating new property file: /home/lalit/Desktop/Data/examples/training/seam/refrences/jboss-seam-2.1.1.GA/seam-gen/build.properties
     [echo] Installing JDBC driver jar to JBoss AS
     [copy] Copying 1 file to /home/lalit/Desktop/ProgramFiles/jboss-5.0.0.GA/server/default/lib
     [echo] Type './seam create-project' to create the new project
BUILD SUCCESSFUL
Total time: 4 minutes 28 seconds
Now run the command 
./seam create-project. 
This will create a project structure with all dependencies set in.
After this run ./seam generate which will reverse engineer the data model and create a CRUD application. to deploy it on Jboss call ./seam deploy. If you go to JBoss deploy directory and navigate to server/default/deploy/ you will see the ear seamFirstProject.ear. Now run the server by navigating to JBoss deploy directory  and to bin folder. Issue the command ./run.sh. The server should start with no exceptions.
Hit your application in browser at http://localhost.:8080/seamFirstProject . Please change the host name and othe setting as per your local settings.It will open the home page of your application with menus on the top. This will have all the CRUD functionalities.
You can remove your application from JBoss server by issuing command ./seam undeploy.
There is another way of deploying application. In place of ./seam deploy, you issue command ./seam explode. This does not bundles the application in an archive but copies the whole directory structure in Jboss. In this way, you can hot deployment of classes and other artifacts. This is a preferable mode in development as it saves time in terms of deploy and undeploy  cycle. Seam-gen tools comes as an eclipse plugin also for eclipse IDE which can be downloaded from JBoss site.
The automated CRUD application may not be what you perceive your application to look like. But it's a good start and you can always use the generated artifact later on.