Search This Blog

Tuesday, December 14, 2010

Struts 2 example

Lets create a simple struts application that would involve a controller , a model and a view. The following structure exists for my project : I have downloaded the struts library and placed the jar files in lib. My codes are under src. The struts only configuration file lies in the src directory. My views are under web. To get started we need to route our incoming requests to our struts dispatcher, we do it in our web.xml :

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

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
Once this is done, we can define our controller that will handle our requests. In my case i have named it MyController and contains :

import com.opensymphony.xwork2.ActionSupport;
public class MyController extends ActionSupport {
        private User user;
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    public String execute() throws Exception {
        this.user = new User();
        user.setId(1);
        user.setUsername("user1");
        user.setPassword("password");
        return SUCCESS;
    }
}

The above controller uses User model that i have defined in User.java :

public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

execute() is the method called when request comes to the controller. In MyController we initialize the User object and set its properties. We can also access this user object from jsp rendered by this controller, we'll c that later. Remember Object getters and setters are necessary for this to work. Controller can return different results, based on which it renders different views. For example if success is returned, required view can be rendered else if error is returned error page can be shown. We define all this in struts.xml that lies in my classspath :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">


<struts>
        <package name="test" namespace="/" extends="struts-default">
            <action name="showuser" class="MyController" >
                <result name="success">index.jsp</result>
                <result name="error">error.jsp</result>
            </action>
        </package>
</struts>
In my case i have defined only one action showuser, which will route this request to MyController which will then return a result. In case of success index.jsp will be rendered, error.jsp otherwise. Now lets show the user details which were initialized in MyController in our index.jsp :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head><title>Simple jsp page</title></head>
  <body>
    <s:property value="user.id" />
    <s:property value="user.username" />
    <s:property value="user.password" />
  </body>
</html>
This will print the user id, username, password on the screen when we try to access http://localhost/showuser There is one more interesting thing to see over here, the auto wiring feature of struts. If we define Objects in the controller with its getter and setter and then pass the object as parameter in the url its value is automatically assigned to the object. For example if we add a String variable "message" in MyController and define setter and getter over it, we can use the url http://localhost/showuser?message=HelloWorld it will be printed on the page.

public class MyController extends ActionSupport {
        private User user;
        private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head><title>Simple jsp page</title></head>
  <body>
    <s:property value="message" />
  </body>
</html>

Thursday, December 9, 2010

Struts 2, Spring 3, Hibernate - The Big Picture

Today, we will get a java web application running using these three master frameworks -> Struts, Spring and Hibernate. Each one has its own speciality, that overcome some of the drawbacks of the underlying platform. Spring framework allows you to create and pass objects( java beans) at runtime using constructors or setters rather than doing it implicitly in the host class, the concept being known as Dependency Injection or Inversion of Control (IOC). This makes the classes independent, which indeed helps in testing. Spring also has other components but we wont use it here. Struts provides a Model View Controller (MVC) framework. It helps in separating your logic from the view. The controllers handle the requests, the views generate output and model represents an entity. Hibernate lets us save Persistence Java Objects/POJOs into the database and also retrieve them. All these components have their own configuration xml files. I will break up this topic into 4 parts, in 3 of them we will see how we can get these components running independently and at last using these into one application. ======================================== AN APPLICATION IN SPRING The IDE i prefer for java is IntelliJ Idea, so the initial project settings may differ based on the IDE you use. Download Spring 3 Framework here The structure of the application goes like this : Extract the Spring archive to a folder, import the jar files in dist folder to the lib folder of your project and make sure they are added to the build path. Actually all files are not required, and in Spring you get the freedom to choose only the components you need. The jar file that i have included are : commons-logging, spring-web, spring-webmvc, spring-beans, spring-context, spring-core, spring-asm, spring-expression. commons-logging jar is needed and can be found in projects/spring-build/lib/ivy of the Spring framework extracted folder. Don't forget to include Java EE library. The src folder will contain my source, within which i have defined a package in.codeconnect, my java files will go in here. The web directory contains a sub directory 'pages' where i will keep my views/jsp files. WEB-INF will contain 2 Spring configuration files : applicationContext.xml and dispatcher-servlet.xml and one server config file : web.xml. I have created 2 classes in my package : This is a simple class with getter and setter,that will contain my greeting message :

package in.codeconnect;

public class MessageClass {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
This is the Controller :

package in.codeconnect;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloWorldController implements Controller {
    private MessageClass messageObject;

    public MessageClass getMessageObject() {
        return messageObject;
    }

    public void setMessageObject(MessageClass messageObject) {
        this.messageObject = messageObject;
    }

    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
           ModelAndView modelAndView = new ModelAndView("pages/say_hello.jsp");
           modelAndView.addObject("message",messageObject.getMessage());
           return modelAndView;
    }
}
Note this class has a MessageClass object defined along with its getter and setter. handleRequest() is the function called when request comes to this contoller. Here we create a new view whose jsp is located in /pages with name say_hello.jsp. Then we add a variable that will contain our greeting message using addObject(), whose value will be equal to messageObject's message property. Lets go through the configuration files. web.xml is the main file and this is how it will look :

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> 
<context-param> <param-name>contextConfigLocation</param-name> 
<param-value>/WEB-INF/applicationContext.xml
</param-value> 
</context-param> <listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class> 
</listener> <servlet> <servlet-name>dispatcher</servlet-name> 
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class> 
<load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
<servlet-name>dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
It states that any request coming with .html suffix should be directed to Springs dispatcher, and this is where the action starts. applicationContext.xml can contain all beans definitions except the controller bean definition. dispatcher-servlet.xml should basically contain controller bean definition, but anything can go here. Blank 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.xsd"> 
</beans>
dispatcher-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.xsd"> 
<bean name="messageObject" class="in.codeconnect.MessageClass"> 
<property name="message" value="Hello World" /> </bean> 
<bean name="/sayHello.html" class="in.codeconnect.HelloWorldController"> 
<property name="messageObject" ref="messageObject" /> 
</bean> </beans>
We can see above , we define a bean messageObject of type MessageClass and set its message using "value='Hello World'" (Dependency Injection).Here the setmessage() method of this object will be called to set message value. Next we define another bean, our controller that will be looked upon when request comes to /sayHello.html . We then specify its messageObject to be equal to the previous bean defined above using 'ref' . What is in my say_hello.jsp :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html> <head><title>Simple jsp page</title></head> 
<body>${message}</body> </html>
So When the application starts, the beans are created and then injected in order of dependency. You should see Hello World message when page loads in the browser. ${message} is one that was added using modelAndView.addObject().