Sébastien’s Coding Journey

March 20, 2009

Using Velocity layout in Spring

Filed under: Spring — Tags: , , — Sébastien Ayotte @ 9:21 am

Intro

In my previous post I was playing with Velocity and the Spring framework. In this post I will show how to build a Velocity layout. Then I will inform Spring to use our layout when rendering a view.

Let’s build the layout

<html>
    <body>
        <div>
            #parse ("head.vm")
        </div>
        <div>
            $screen_content
        </div>
        <div>
            #parse ("foot.vm")
        </div>
    </body>
</html>

The $screen_content variable is used by the VelocityLayoutViewResolver to include the result of an other VM in the layout. Let’s name this template.vm. Take a look at the content of the head.vm and foot.vm files.

I'm the header.
I'm the footer.

What are we showing?

I’ll show what I know about the X-Men and the Avenger. So I need a VM that will show some rosters from the X-Men and a VM that will show some rosters from the Avenger. Take a look at the content of the xmen.vm and the anvenger.vm files.

#foreach ($xmen in $xmens)
    $xmen<br />
#end
#foreach ($avenger in $avengers)
    $avenger<br />
#end

We need some controllers too

The XmenController provides some names for the X-Men’s crew and the AvengerController provides some names for the Avenger’s crew.

/**
 * Knows a little about the X-Men.
 * 
 * @author Sébastien Ayotte
 * 
 */
final class XmenController extends ParameterizableViewController {

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
		List<String> xmens = new ArrayList<String>();
		xmens.add("Professor X");
		xmens.add("Cyclops");
		xmens.add("Iceman");
		xmens.add("Archangel");
		xmens.add("Beast");
		xmens.add("Phoenix");
		Map<String, List<String>> model = new HashMap<String, List<String>>();
		model.put("xmens", xmens);
		return new ModelAndView(getViewName(), model);
	}
	
}
/**
 * Knows a little about the Avenger.
 * 
 * @author Sébastien Ayotte
 *
 */
final class AvengerController extends ParameterizableViewController {

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
		List<String> avengers = new ArrayList<String>();
		avengers.add("Thor");
		avengers.add("Iron Man");
		avengers.add("Henry Pym");
		avengers.add("Wasp");
		avengers.add("Hulk");
		Map<String, List<String>> model = new HashMap<String, List<String>>();
		model.put("avengers", avengers);
		return new ModelAndView(getViewName(), model);
	}
	
}

We need to configure the Spring context

<?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="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/mods/core/sample/velocity/" />
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityLayoutView" />
        <property name="layoutUrl" value="template.vm" />
        <property name="cache" value="true" />
        <property name="prefix" value="" />
        <property name="suffix" value=".vm" />
    </bean>
    
    <bean name="/core/sample/velocity/showxmens.do" class="sample.velocity.XmenController">
        <property name="viewName" value="xmen" />
    </bean>
    
    <bean name="/core/sample/velocity/showavengers.do" class="sample.velocity.AvengerController">
        <property name="viewName" value="avenger" />
    </bean>
    
</beans>

Try it!

I’m using Tomcat to deploy my application. I can now call http://localhost:8080/sample/core/sample/velocity/showxmens.do to have a list of the X-Men’s crew or I can call http://localhost:8080/sample/core/sample/velocity/showavengers.do to get a list of the Avenger’s crew. The two lists will be shown in the layout we define previously.

March 19, 2009

A simple example using Velocity in Spring

Filed under: Spring — Tags: , , — Sébastien Ayotte @ 1:33 pm

What are we gonna do?

Let’s say that you want to show the world that you know something about the X-Men. So you want a Spring controller that provides the names of some of the rosters and you also want to use Velocity to display this list.

Write a controller

/**
 * Knows a little about the X-Men.
 * 
 * @author Sébastien Ayotte
 */
final class XmenController extends ParameterizableViewController {

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
		/*
		 * I am putting the list I want to show in the model. I like to extend from the
		 * ParameterizableViewController cause I can configure the name of the view while
		 * I'm defining the controller's bean in the xml context file. So I can use the
		 * getViewName method to retrieve the name of the view I configured. 
		 */
		List<String> xmens = new ArrayList<String>();
		xmens.add("Professor X");
		xmens.add("Cyclops");
		xmens.add("Iceman");
		xmens.add("Archangel");
		xmens.add("Beast");
		xmens.add("Phoenix");
		Map<String, List<String>> model = new HashMap<String, List<String>>();
		model.put("xmens", xmens);
		return new ModelAndView(getViewName(), model);
	}
	
}

Also write a VM

I’m displaying each X-Men’s name on their own line.

<html>
    <body>
        #foreach ($xmen in $xmens)
            $xmen<br />
        #end
    </body>
</html>

Configure everything

So now we need to tell Velocity where to get is VM. We also need to define the ViewResolver for Velocity. Finally, we configure the controller that knows everything about the X-Men.

<?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="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/mods/core/sample/velocity/" />
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
        <property name="cache" value="true"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".vm"/>
    </bean>
    
    <bean name="/core/sample/velocity/showxmens.do" class="sample.velocity.XmenController">
        <property name="viewName" value="index" />
    </bean>
    
</beans>

Where do I put my files?

My tree looks like this.

web
`-- WEB-INF
        |-- mods
        |   |-- core
        |       |-- sample
        |           |-- velocity
        |           |   |-- index.vm
        |           |   `-- velocity.spring.context.xml
        |
        `-- web.xml

Try it!

My web application is powered by Tomcat. So when I type http://localhost:8080/sample/core/sample/velocity/showxmens.do in my browser, it displays a list of X-Men.

Finally

This example is just an introduction. I think the next step is to do a template that will be useful in a web application. You know, the kind of template where you have a header and a footer and the only thing that is changing is the main part of the web page. I don’t know if I can do that with Velocity? But I’m going to give it a try :-).

March 3, 2009

Let’s test a Spring’s Validator with JUnit and EasyMock

Filed under: Spring — Tags: , , , , , — Sébastien Ayotte @ 3:29 pm

In one of my previous articles on How to use a Validator and a MessageResolver to validate a Spring’s SimpleFormController, I showed how to use the Validator interface from Spring. But what happens if I need to do extensive and complexe validations? It should be nice to do a test first. Fortunately I find that  JUnit and EasyMock provides ways to do the tests I desire in a glance.

In this example I expect that my validator will raise an error if the username or/and the name of a user is null.

@Test
public void validate() {
	User user = createMock(User.class);
	expect(user.getUsername()).andReturn(null);
	expect(user.getName()).andReturn(null);
	Errors errors = createMock(Errors.class);
	errors.rejectValue("username", "field.required");
	errors.rejectValue("name", "field.required");
	replay(user, errors);

	UserValidator validator = new UserValidator();
	validator.validate(user, errors);

	verify(user, errors);
}

Basically, I create two mocks. The user mock will return null when the getUsername or the getName method get called by my validator. I expect that the errors mock will be notified if the username or the name of the user is null. Then, the test call replay on the two mocks to tell EasyMock to start recording the usage of the mocks. I can now use my validator with the mocks. Finally, the test tells EasyMock to verify if I got the expected behavior that I recorded previously.

February 19, 2009

How to use a Validator and a MessageResolver to validate a Spring’s SimpleFormController

Filed under: Spring — Tags: , — Sébastien Ayotte @ 2:26 pm

I want to add a form to register some users for my web application. I want to validate the inputs from the form and if an error occurs, I want to be able to inform the user. My web application must provides support for internationalization (i18n). This example demonstrates how to do it with Spring.

Let’s begin by building a simple form.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
    <body>
        <form:form commandName="user">
            Username : <form:input path="username" /><form:errors path="username" /><br />
            Name : <form:input path="name" /><form:errors path="name" /> <br />
            <input type="submit" value="Register" />
        </form:form>
    </body>
</html>

By providing this form, I want the user to be able to specify his username and his name. Of course, I want to be able to validate those fields. Let’s save this form under “WEB-INF/user/userForm.jsp”.

Let’s define the backing object for this form.


class User {
    private String username;
    private String name;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getName() {
        return name;
    }

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

Before I configure the Controller and the MessageResolver for the form, I need to build the Validator for my backing object.


class UserValidator implements Validator {

    public boolean supports(Class clazz) {
        return User.class.isAssignableFrom(clazz);
    }

    public void validate(Object toVerify, Errors errors) {
        User user = (User) toVerify;

        if (user.getUsername() == null || user.getUsername().trim().length() == 0) {
            errors.rejectValue("username", "user.username.required");
        }

        if (user.getName() == null || user.getName().trim().length() == 0) {
            errors.rejectValue("name", "user.name.required");
        }
    }

}

Has you can see, I don’t want to hard-code any messages in my validator. So if a field is empty, I’m rejecting it by specifing the field with an error code. I will use a MessageResolver to look up the message I want to show to the user so I can keep these messages in a lot of differents languages.

Let’s define those messages in “WEB-INF/errors_en_US.properties” cause I want to use the locale en_US.


user.username.required=I need the username!
user.name.required=I need the name!

The last thing I need to do is to configure a SimpleFormController and a MessageResolver in the Spring’s context file.

    <!--
        I want to be able to register some user in the application. To do that I need to get
        some inputs from the user. So I need a simple form. I'll do it with the
        SimpleFormController.
    -->
    <bean id="addUser" class="org.springframework.web.servlet.mvc.SimpleFormController">
        <!-- I want to show the user form. -->
        <property name="formView" value="user/userForm" />
        <!-- If everything goes well I want to come back to the home page. -->
        <property name="successView" value="home/index" />
        <!-- The name of our backing object. -->
        <property name="commandName" value="user" />
        <!-- The backing object class. -->
        <property name="commandClass" value="sample.UserImpl" />
        <!-- I want to validate some field in the user form. -->
        <property name="validator">
            <ref bean="userValidator" />
        </property>
    </bean>
    
    <bean id="userValidator" class="sample.UserValidator"/>
    
    <!-- I have some error messages to look up. I'll need a MessageResolver 
         to do that.
    -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>/WEB-INF/errors</value>
            </list>
        </property>
    </bean>

The validator can now validate the form when it’s submitted. If one of the fields is empty the validator put the guilty field in the Errors object with a corresponding error code. The tag <form:errors> can now look up the message by using the error code specified. Notice that if the tag can’t find the error code a NoSuchMessageException will be thrown.

February 16, 2009

A Spring’s ParameterizableViewController example

Filed under: Spring — Tags: , — Sébastien Ayotte @ 3:34 pm

I use the ParameterizableViewController of Spring to present dynamic content at the user on my web application. Let’s inform the controller which view it will be using.

<bean id="hello" class="sample.HelloWorldController">
    <property name="viewName" value="sample/hello" />
</bean>

Now I can use the controller to get something I want to show from a service, from the database or from a file. Let’s say I just want to say hello to the world from my controller.

final class HelloWorldController extends ParameterizableViewController {
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // I'am creating the ModelAndView with the viewName I mapped previously
        ModelAndView mav = new ModelAndView(getViewName());
        // I'am just generating a message that I want to show to the user.
        mav.addObject("message", "I say Hello World from a controller!");
        return mav;
    }
}

Finally, I can use an EL expression in my view to retrieve the content of the model.


        ${message}

January 30, 2009

Validating a Spring’s AbstractWizardFormController

Filed under: Spring — Tags: , — Sébastien Ayotte @ 4:28 pm

In my article “A Spring’s AbstractWizardFormController example” I present the basics about the AbstractWizardFormController. But a wizard can’t be complete without validating the inputs entered by a user. So let’s check those fields.

To follow-up my previous article I will validate the email entered in the emailForm. To keep it simple I will only check if the field is empty. Let’s modify the controller by overriding one of the validatePage methods from the AbstractWizardFormController.

final class AddUserWizardFormController extends AbstractWizardFormController {

	@Override
	protected ModelAndView processFinish(HttpServletRequest request, HttpServletResponse reponse, Object user, BindException errors) throws Exception {
		/*
		 * One day your wizard must finish. I just have to set _finish in the request and the
		 * controller will call this method.
		 */
		return new ModelAndView("menu").addObject("message", "Job done!");
	}

	@Override
	protected ModelAndView processCancel(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
		/*
		 * Sometimes a wizard can be long and the user want to cancel what he was doing. I
		 * can handle a cancel submission with this method. The only thing I have to do is to
		 * set the _cancel request parameter. The controller will be notified that the user
		 * want to cancel what he is doing and he will call this method.
		 */
		return new ModelAndView("menu").addObject("message", "Job canceled!");
	}

	@Override
	protected void validatePage(Object command, Errors errors, int page) {
		/*
		 * Of course I need to validate the input fields. I don't want to keep anything
		 * inadequate in the software. To keep things brief I'll check only the emailForm.
		 * Let's say that we require the email field.
		 */
		switch(page) {
		case 1:
			// The emailForm is the second page of the wizard. Of course I should do more complex validation for a email.
			ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email.email", "required.email", "Oups! I need the email.");
			break;
		}
	}

}

The controller is now checking if the field “email.email” (on the second page of the wizard) is empty. If it is the case, the controller put a message (“Oups! I need the email”) in the errors container. I can retrieve the errors by using EL expression in the form. Let’s modify the emailForm to inform the user if a problem occur.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<form action="<c:url value="adduser"/>" method="post">
    <table>
        <tr>
            <td>
                Email :
            </td>
            <td>
                <spring:bind path="user.email.email">
	                <input type="text" name="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>"/>
                    <!-- I inform the user if a problem occur with the email. -->
                    <c:out value="${status.errorMessage}"/>
                </spring:bind>
            </td>
        </tr>
        <tr>
            <td>
                <!-- I want to go on the first page of this wizard. -->
                <input type="submit" name="_target0" value="Back" />
            </td>
            <td>
                <!-- I want to go on the third page of this wizard. -->
                <input type="submit" value="Next" name="_target2" />
            </td>
             <td>
                <!-- I want to cancel what I am doing -->
                <input type="submit" name="_cancel" value="Cancel" />
            </td>
        </tr>
    </table>
</form:form>

Basically I’m telling to Spring to bind (<spring:bind>) the email input field with the email property of the user (the form backing object). Now if the user his pressing the Next button and he didn’t entered anything in the email field, a message appear beside the email field saying “Oups! I need the email”.

January 26, 2009

A Spring’s AbstractWizardFormController example

Filed under: Spring — Tags: , — Sébastien Ayotte @ 3:37 pm

Let’s define the scenario for this example. I want to build a module that add users into the application. To be able to add a user in the system I need to gather his username, his name, his email and his role.

I want four forms. The first one will ask for the username and the name of the user. The second one will ask for his email. The third one will ask for his role. The last one will show all the information we entered previously. I want to be able to navigate througth all the forms freely (Basically I want a next and a previous button). Of course I want to be able to cancel the job at all time. On the last form I want to be able to confirm what I entered in the wizard.

Let’s define our controller :

<bean id="adduser" class="sample.AddUserWizardFormController">
        <property name="pages">
            <list>
                <value>user/userForm</value>
                <value>user/emailForm</value>
                <value>user/roleForm</value>
                <value>user/confirmForm</value>
            </list>
        </property>
        <property name="commandName" value="user" />
        <property name="commandClass" value="sample.UserImpl" />
</bean>

The controller could look like this :

final class AddUserWizardFormController extends AbstractWizardFormController {
	@Override
	protected ModelAndView processFinish(HttpServletRequest request, HttpServletResponse reponse, Object user,
                BindException errors) throws Exception {
		/*
		 * One day your wizard must finish. I just have to set _finish in the request and the
		 * controller will call this method.
		 */
		Map model = new HashMap();
		model.put("message", "Job done!");
		return new ModelAndView("menu", model);
	}

	@Override
	protected ModelAndView processCancel(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		/*
		 * Sometimes a wizard can be long and the user want to cancel what he was doing. I
		 * can handle a cancel submission with this method. The only thing I have to do is to
		 * set the _cancel request parameter. The controller will be notified that the user
		 * want to cancel what he is doing and he will call this method.
		 */
		Map model = new HashMap();
		model.put("message", "HAAAAAAAAAAAAAAAAAAAAAA canceled!");
		return new ModelAndView("menu", model);
	}

}

The controller will navigate througth the pages without doing any validation. I just need to give him some information in the request on how to handle those pages. So if I submit _cancel the controller will call the processCancel method. If I submit _finish the controller will call the processFinish method. To go to a next or a previous page in that case I will have to submit _target0, _target1, _target2 or _target3. Basically you need to put _target# in the request to navigate from page to page. In this case it correspond to userForm, emailForm, roleForm or confirmForm respectivelly.

Let’s see a snippet for the emailForm :

<form action="<c:url value="adduser"/>" method="post">
    <table>
        <tr>
            <td>
                Email :
            </td>
            <td>
                <spring:bind path="user.email.email">
	                <input type="text" name="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>"/>
                    <!-- I inform the user if a problem occur with the email. -->
                    <c:out value="${status.errorMessage}"/>
                </spring:bind>
            </td>
        </tr>
        <tr>
            <td>
                <!-- I want to go on the first page of this wizard. -->
                <input type="submit" name="_target0" value="Back" />
            </td>
            <td>
                <!-- I want to go on the third page of this wizard. -->
                <input type="submit" value="Next" name="_target2" />
            </td>
             <td>
                <!-- I want to cancel what I am doing -->
                <input type="submit" name="_cancel" value="Cancel" />
            </td>
        </tr>
    </table>
</form:form>

In brief the AbstractWizardFormController analyse the request and look for _cancel, _finish and _target# parameters to navigate between pages.

January 21, 2009

My first controller with the Spring framework

Filed under: Spring — Tags: , — Sébastien Ayotte @ 4:29 pm

I started learning the Spring framework to build a new web application that I will deploy under Tomcat. When I am learning something I like to do baby steps to be sure that I master every parts of the subject. So let’s begin with a simple controller that writes some stuffs directly in the HTTP response. We should be able to see some output in the browser quickly. I will assume that you have some knowledge on how to deploy/develop a web application.

First of all, let’s configure the DispatcherServlet of Spring in our deployment descriptor (web.xml). I inform the DispatcherServlet that it must look in the applicationContext.xml file to find the resources it needs and we map all the requests to it.

<servlet> 
        <servlet-name>core</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
        <servlet-name>core</servlet-name>
        <url-pattern>/*</url-pattern>
 </servlet-mapping>   

Now I can use http://localhost:8080/myapp/mycontroller to call the controller. They are other HandlerMapping you can use to map the incoming URLs but I like the declarative form of the SimpleUrlHandlerMapping. You should go look to the Spring documentation to have more details about HandlerMapping. Of course I need to define the controller that will be called by those URLs.

    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>
                /mycontroller=mycontroller
            </value>
        </property>
    </bean>

    <bean id="mycontroller" class="sample.MyController" />

And I need to code the controller. Like I said before, it just writes some output directly into the response.

  
public final class MyController extends AbstractController {  
@Override
  protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
    throws Exception {

    PrintWriter pw = response.getWriter();
    pw.write("Hello! I'm using the Spring framework.");
    return null;
  }

It shouldn’t be to hard to get this example running. Stay tune for more exploration on the Spring framework.

Create a free website or blog at WordPress.com.