Native Dependency Injection in Struts2

Struts2 Native Dependency Injection

Struts2 provides support for Dependency injection. You may use DI containers like “Spring” in your Struts2 application, or may use Native Dependency Injection available in Struts2 (XWork2) framework. It’s based on Google’s “guice” (both being made by same person).

In this sample application, I have made Two Action classes:

  1. AddProductAction           To Add new product
  2. ListProductAction            To List all products

Both actions are dependent on a “Business” class  : ProductManager. Instead of creating instance of ProductManager in each action class, I have created its instance through “bean” element in “struts.xml”.

<bean class="com.mahendra.ProductManager" name="man" />

The ObjectFactory available in Struts2 will create instance of ProductManager using default constructor and is made available to all other components using name : “man”.

Every Action class needs to have property of type “ProductManager” along with annotation:

@Inject("man")
private ProductManager manager;
// This method is used for Injecting Object
public void setManager(ProductManager manager) {
this.manager = manager;
}

Now, lets create an application.

Requirements:

  1. Java SDK 1.6 (or newer)
  2. Eclipse helios (or newer)
  3. Apache Tomcat 6.0 (or 7.0)
  4. Struts 2.1.x from apache

Steps to create application:

  1. Create new Dynamic Web Application.
  2. Copy all required JAR’s inside “web-inf/lib” folderJARS required:
    commons-fileupload
    commons-io
    commons-lang
    freemarker
    javassist
    ognl
    jstl (For JSTL Core Tags)
    struts2-core
    xwork-core
    
  3. Modify your “web.xml” to have Struts2 dispatcher filter.
    <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>
    
  4. Create new “struts.xml” in your source folder:
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts><bean class="com.mahendra.ProductManager"
    name="man" />
    
    <package name="p1" extends="struts-default"
    namespace="">
    <action name="add"
    class="com.mahendra.AddProductAction">
    <result type="redirectAction">list</result>
    </action> 
    
    <action name="list"
    class="com.mahendra.ListProductAction">
    <result>list.jsp</result>
    </action>
    </package>
    
    </struts>
    
  5. Create Model class : Product
    package com.mahendra;
    public class Product {
    
    private String name;
    private String description;
    private double price;
    
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getDescription() {
    return description;
    }
    public void setDescription(String description) {
    this.description = description;
    }
    public double getPrice() {
    return price;
    }
    public void setPrice(double price) {
    this.price = price;
    }
    
    public Product(String name, String description, double price) {
    super();
    this.name = name;
    this.description = description;
    this.price = price;
    }
    
    public Product() {
    super();
    }
    
    }
    
  6. Shared “Business” class :
    ProductManager

    package com.mahendra;
    
    import java.util.*;
    
    public class ProductManager {
    private List<Product> products;
    
    public ProductManager() {
    System.out.println("Creating new manager...");
    products = new LinkedList<Product>();
    System.out.println("Empty Product list generated");
    }
    
    public void add(Product p) {
    products.add(p);
    }
    
    public Product search(String name) {
    Product p = null;
    for (int i = 0; i < products.size(); i++) {
    if (products.get(i).getName().equals(name)) {
    p = products.get(i);
    break;
    }
    }return p;
    }
    
    public void delete(String name) {
    Product p = search(name);
    if (p != null) {
    products.remove(p);
    }
    }
    
    public List<Product> getProducts() {
    return products;
    }
    
    public void setProducts(List<Product> products) {
    this.products = products;
    }
    }
    
  7. Create First Action class to add new product: AddProductAction
    package com.mahendra;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.inject.Inject;
    public class AddProductAction extendsActionSupport {
    @Inject("man")
    private ProductManager manager;
    private Product product;
    public String execute() {
    manager.add(product);
    return SUCCESS;
    }
    public ProductManager getManager() {
    return manager;
    }
    
    // This method is used for Injecting Object
    public void setManager(ProductManager manager) {
    this.manager = manager;
    }
    
    public Product getProduct() {
    return product;
    }
    
    public void setProduct(Product product) {
    this.product = product;
    }
    }
    
  8. Create another action class to List all products: ListProductAction
    import java.util.List;
    import com.opensymphony.xwork2.inject.Inject;
    
    public   class ListProductAction {
    
    @Inject("man")// requires setter 
    private ProductManager manager; 
    private List<Product> productList;
    
    public  String execute() {
    setProductList(manager.getProducts());
    return "success";
    }
    
    public  ProductManager getManager() {
     return  manager;
    }
    
    public void  setManager(ProductManager manager) {
    this.manager = manager;
    }
    
    public  List<Product> getProductList() {
     return  productList;
    }
    
    public void setProductList(List<Product> productList) {
     this.productList = productList;
    }
    }
    
  9. Create new JSP page “index.jsp” and add following line to load “list” action.
    <% response.sendRedirect("list.action"); %>
    
  10. Create new JSP page “list.jsp” and add following lines to render form and list.
    <%@ taglib uri= "/struts-tags"  prefix= "s"%>
    <html>
    <head>
    <meta http-equiv= "Content-Type"  content= "text/html;charset=ISO-8859-1" >
    <title>Struts2 Dependency Demo</title>
    </head>
    <body>
    
    <s:form action="add"  method="post" >
    <s:textfield name= "product.name" label= "Name of product" />
    <s:textfield name= "product.description" label= "Description"/>
    <s:textfield name= "product.price" label= "Product Price"  />
    <s:submit value= "Save"  />
    </s:form>
    
    <h2>Available Products</h2>
    <table>
    <tr>
    <td>Product Name</td>
    <td>Description</td>
    <td>Price</td>
    </tr>
    <s:iterator value= "productList"  var= "p" >
    <tr>
    <td>${p.name }</td>
    <td>${p.description }</td>
    <td>${p.price }</td>
    </tr>
    </s:iterator>
    </table>
    </body>
    </html>
    

Seam 2.2.2.Final with Apache Tomcat 7.0

From last three days, I was messing up with Seam 2.2, trying to get it work with Tomcat 7.

Seam can work with JBoss AS, GlassFish & other AS. but Tomcat being just a Servlet Container has many drawbacks.

My Setup:

  • JDK 1.7.0
  • Apache Tomcat 7.0
  • eclipse indigo (JBossTools  for indigo installed)
  • Seam 2.2.2.Final
  • JPA with Transaction type: RESOURCE_LOCAL (an alternative to default JTA)
  • Database : MySql 5.1 with MySql J/Connection 5.1

From Seam 2.2.2Final distribution, locate LIB folder, copy following JARs to tomcat 7/LIB folder:

Hibernate dependencies:

  1. annotations-api.jar
  2. cglib-nodep.jar
  3. commons-collections.jar
  4. commons-logging.jar
  5. dom4j.jar
  6. javassist.jar

Hibernate:

  1. hibernate-core.jar
  2. hibernate-annotations.jar
  3. hibernate-commons-annotations.jar
  4. hibernate-entitymanager.jar
  5. hibernate-search.jar
  6. lucene.jar
  7. hibernate-validator.jar

JSF 1.2:

  1. jsf-api.jar
  2. jsf-impl.jar
  3. jsf-facelets.jar

JPA:

  1. jta.jar
  2. persistence-api.jar
  3. ejb3-persistence.jar (used by hibernate+JPA)

Logging for Hibernate and Seam:

  1. log4j.jar
  2. slf4j-api.jar
  3. slf4j-log4j12.jar
  4. log4j.properties (for debug messages)

Drools:

  • drools-api.jar
  • drools-compiler.jar
  • drools-core.jar
  • drools-decisiontables.jar
  • drools-templates.jar

Now,after adding all these JAR’s your tomcat, your tomcat is ready to host seam 2.2 application.

  1. Create new Seam Web Project in eclipse
    Step 1
  2. Use Apache Tomcat 7.0 as Application Server (add if not done already)
  3. use selected configuration (which includes Seam 2.2)
  4. JSF Configuration: Disable Library configuration (We have added all JSF 1.2 Jars to our Tomcat)
  5. Use Seam Runtime : <<select folder where  you have extracted Seam 2.2.2>>
  6. Use Database connection New MSQL (Click on “New” button to create new connection, make sure that you have already created one EMPTY database in MySQL with name TestDB2)
  7. Click Finish to end project creation.
  8. Now, open “Package Explorer” 
  9. Inside package explorer … now you will get “WebContent” Folder which contains another one “META-INF” folder. I will now create context.xml inside this folder. This context will be deployed at the time of application deployment, which will result in deploying a (local) javax.sql.DataSource to Tomcat for current web application.
    <?xml version="1.0" encoding="UTF-8"?>
    <Context path="/TestApp15" docBase="TestApp15" crossContext="true">
        <Resource name="MyData" auth="Container" 
            type="javax.sql.DataSource"
            driverClassName="com.mysql.jdbc.Driver"
            username="root" password="mahendra" 
            url="jdbc:mysql://localhost:3306/TestDB2"/>
    </Context>
  10. Now, there is another META-INF inside src/main with one “persistence.xml”. make few changes in it:
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Persistence deployment descriptor for dev profile -->
    <persistence xmlns="http://java.sun.com/xml/ns/persistence" 
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
                 version="1.0">
    
       <persistence-unit name="TestApp15PU" transaction-type="RESOURCE_LOCAL">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>java:comp/env/MyData</non-jta-data-source>
          <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
             <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
             <property name="hibernate.show_sql" value="true"/>
             <property name="hibernate.format_sql" value="true"/>
             <property name="hibernate.default_catalog" value="TestDB2"/>
    
          </properties>
       </persistence-unit>
    </persistence>
  11. We are using NON JTA data source instead of default JTA, we are not using any Caching provider from Hibernate so remove Caching provider if any.
  12. From WebContents/WEB-INF folder, open “components.xml”, make following changes:
    <?xml version="1.0" encoding="UTF-8"?>
    <components xmlns="http://jboss.com/products/seam/components"
                xmlns:core="http://jboss.com/products/seam/core"
                xmlns:persistence="http://jboss.com/products/seam/persistence"
         xmlns:tx="http://jboss.com/products/seam/transaction"
                xmlns:drools="http://jboss.com/products/seam/drools"
                xmlns:bpm="http://jboss.com/products/seam/bpm"
                xmlns:security="http://jboss.com/products/seam/security"
                xmlns:mail="http://jboss.com/products/seam/mail"
                xmlns:web="http://jboss.com/products/seam/web"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation=
                    "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                     http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.2.xsd
         http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.1.xsd 
                     http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.2.xsd
                     http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.2.xsd
                     http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
                     http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
                     http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.2.xsd
                     http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
            <core:init />
       <core:manager concurrent-request-timeout="500"
                     conversation-timeout="120000"
                     conversation-id-parameter="cid"
                     parent-conversation-id-parameter="pid"/>
       <!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
       <web:hot-deploy-filter url-pattern="*.seam"/>
       <!-- If you are still using JBoss 4, uncomment this to have your PU started -->
    <!--   <persistence:entity-manager-factory name="entityManagerFactory"-->
    <!--                      persistence-unit-name="TestApp15"/>-->
       <!-- If you are still using JBoss 4, uncomment this to have the entityManagerFactory ysed -->
    <!--   <persistence:managed-persistence-context name="entityManager" auto-create="true"-->
    <!--                          entity-manager-factory="#{entityManagerFactory}"/>-->
            <tx:entity-transaction entity-manager="#{entityManager}" auto-create="true"/>
      <persistence:managed-persistence-context 
                   name="entityManager" 
                   auto-create="true"
                   entity-manager-factory="#{entityManagerFactory}"/>
      <persistence:entity-manager-factory 
                   name="entityManagerFactory" 
                   auto-create="true" 
                   persistence-unit-name="TestApp15PU"/>
       <drools:rule-base name="securityRules">
          <drools:rule-files><value>/security.drl</value></drools:rule-files>
       </drools:rule-base>
       <security:rule-based-permission-resolver security-rules="#{securityRules}"/>
       <security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
       <event type="org.jboss.seam.security.notLoggedIn">
          <action execute="#{redirect.captureCurrentView}"/>
       </event>
       <event type="org.jboss.seam.security.loginSuccessful">
          <action execute="#{redirect.returnToCapturedView}"/>
       </event>
       <mail:mail-session host="localhost" port="25"/>
       <!-- For use with jBPM pageflow or process management -->
       <!--
       <bpm:jbpm>
          <bpm:process-definitions></bpm:process-definitions>
          <bpm:pageflow-definitions></bpm:pageflow-definitions>
       </bpm:jbpm>
       -->
    </components>
  13. Run application in Tomcat.

NOTE: You may download Video screen cast for the above demo at my box account

How to create WebService in JBoss AS7 using eclipse.

JBoss Application Server 7.1 comes bundled with JBossWS component. This component is based on Apache CXF. So those people who know Apache CXF, you will love JBoss AS.

First of all, you need to have few basic requirements:

JDK 1.7 (JDK 1.6 is sufficient, but using newest one is recommended)

eclipse indigo (Java EE developer) from eclipse.org

JBoss AS7

JBoss Tools:

You cannot immediately start developing applications for JBoss AS7. You need to get Plugins for your eclipse.

Open eclipse –> Help –> Install new software

add following URL :  http://download.jboss.org/jbosstools/updates/development/indigo

now expand “JBoss Web and JavaEE development”

select following components:

  • JBossAS Tools
  • JBoss WebServices Tools
  • Hibernate Tools
  • JBoss JAX-RS Tools

Now, install all these components.

Once installation in complete, you need to restart eclipse.

Now, add JBoss AS7 as WebServer to your eclipse workspace.

Now, click finish to add JBossAS7 to your eclipse workspace.

Create new Dynamic Web Project:

now, click on “Modify” button to change configuration, select “JBoss Web Services Core”

Click OK –> next –> Generate Web.xml = true –> Next

Image

Select “Server Supplied JBossWS runtime”

click Finish.

Create new class: Calculator

Image

NOTE: This step can be safely SKIPPED!

Create new WebService:

click on WebService Runtime: Apache Axix (in configuration section above) select JBossWS

Click OK

Image

Click Next

Select both option –> Next

Click on “Start Server” –> Wait for Server startup –> Next –> Finish

Now, right click on your project name (My project name is “MyServiceApp1” –>Run as –> Run on Server

change URL in web-browser to include your service name eg. http://localhost:8080/MyServiceApp1/Calculator?wsdl

(Please change port no and application name if they are different)

I you get to see wsdl for newly created web services then you are done!

You can now test this web service using eclipse:

goto Run menu –> Lauch web services explorer

Image

click on “WSDL page” button in top-right  corner

Image

Once you click on “Go” button, you will be presented a page where you can test this Service

Image

now, click on link to method “sum”

enter two value and click go..

Image

It’s done….

JSF sample app: part 3

JSF 2.0 Sample application – part3

in last post, I gave you DAO Components, now it’s time to explore JSF!

all JSF application requires one XML file …. faces-config.xml
I have stored this file under /WEB-INF folder.

<faces-config 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-facesconfig_2_0.xsd"
version="2.0">
<navigation-rule>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">listusers</span></from-outcome>
<to-view-id>/faces/users/list.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">listmovies</span></from-outcome>
<to-view-id>/faces/movies/list.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">listreviews</span></from-outcome>
<to-view-id>/faces/reviews/list.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">addreviews</span></from-outcome>
<to-view-id>/faces/reviews/add.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">listallreviews</span></from-outcome>
<to-view-id>/faces/reviews/listall.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">adduser</span></from-outcome>
<to-view-id>/faces/users/add.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/faces/login.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">edituser</span></from-outcome>
<to-view-id>/faces/users/edit.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome><span style="text-decoration:underline;">addmovie</span></from-outcome>
<to-view-id>/faces/movies/add.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>home</from-outcome>
<to-view-id>/default.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<application>
<locale-config>
<default-locale><span style="text-decoration:underline;">en</span></default-locale>
<supported-locale><span style="text-decoration:underline;">en</span></supported-locale>
<!--<span style="text-decoration:underline;">Uncomment</span> following line once translation is done
<supported-<span style="text-decoration:underline;">locale</span>><span style="text-decoration:underline;">mr</span></supported-<span style="text-decoration:underline;">locale</span>>
-->
</locale-config>
</application>
</faces-config>

Backing beans: package=com.mahendra.actions

AuthenticationBean:            responsible for User authentication (login) and logout events


import javax.faces.bean.ManagedBean;

import javax.faces.bean.SessionScoped;

import javax.faces.context.FacesContext;

import com.mahendra.dao.UserDAO;

import com.mahendra.models.Users;

import com.mahendra.utils.MessageBox;

@ManagedBean

@SessionScoped

public class AuthenticationBean {

private UserDAO dao;

private String uname, upass;

private boolean loggedIn = false;

private Users user;

public AuthenticationBean() {

dao = new UserDAO();

}

public String login(){

return "login";

}

public String verifyUser(){

try{

user =  dao.getUser(getUname());

if(user!=null){

if(user.getPassword().equals(upass)){

loggedIn=true;

}

else

MessageBox.show("Invalid password");

}

}catch(RuntimeException ex){

MessageBox.show(ex.getMessage());

return null;

}

System.out.println("user[authentication]: "+user.getUsername());

if(!loggedIn)

return null;

return "home";

}

public String logout(){

loggedIn = false;

user = null;

FacesContext.getCurrentInstance().getExternalContext().invalidateSession();

System.out.println("Session destroyed!");

return "home";

}

public String signup(){

return "adduser";

}

public void setLoggedIn(boolean loggedIn) {

this.loggedIn = loggedIn;

}

public boolean isLoggedIn() {

return loggedIn;

}

public void setUpass(String upass) {

this.upass = upass;

}

public String getUpass() {

return upass;

}

public void setUname(String uname) {

this.uname = uname;

}

public String getUname() {

return uname;

}

public Users getUser() {

return user;

}

public void setUser(Users user) {

this.user = user;

}

}

MovieBean:              Beacking bean for all pages where movie details are either listed and edited


import java.util.List;

import javax.faces.bean.ManagedBean;

import javax.faces.bean.SessionScoped;

import com.mahendra.dao.MovieDAO;

import com.mahendra.models.Movies;

@ManagedBean

@SessionScoped

public class MovieBean {

private MovieDAO dao;

private Movies movie;

private List<Movies> moviesList;

public void setMovie(Movies movie) {

this.movie = movie;

}

public Movies getMovie() {

return movie;

}

public MovieBean() {

dao = new MovieDAO();

}

public List<Movies> getMoviesList() {

return dao.getAllMovies();

}

public String add() {

setMovie(new Movies());

return "addmovie";

}

public String save() {

dao.create(getMovie());

return "listmovies";

}

public String list() {

return "listmovies";

}

public void setMoviesList(List<Movies> moviesList) {

this.moviesList = moviesList;

}

}

ReviewsBean: backing bean for all review pages:


import java.util.List;

import javax.faces.bean.*;

import javax.faces.component.html.HtmlDataTable;

import javax.faces.event.ActionEvent;

import com.mahendra.dao.ReviewsDAO;

import com.mahendra.models.Movies;

import com.mahendra.models.Reviews;

import com.mahendra.utils.MovieReviewCount;

@ManagedBean

@SessionScoped

public class ReviewsBean {

private ReviewsDAO dao;

private Reviews review;

@ManagedProperty(value = "#{movieBean.movie}")

private Movies movie;

@ManagedProperty(value = "#{authenticationBean}")

private AuthenticationBean authentication;

private List<MovieReviewCount> counts;

private List<Reviews> reviewList;

private HtmlDataTable topMovies;

public ReviewsBean() {

dao = new ReviewsDAO();

}

// public void getReviewsForMovie(){

// setReviewList(dao.getReviewsForMovie(movie.getMovieId()));

// }

//

// public void getAllReviews(){

// setReviewList(dao.getAll());

// }

public Movies getMovie() {

return movie;

}

public void setMovie(Movies movie) {

this.movie = movie;

}

// public List<Reviews> getReviewsForUser(){

// return dao.getReviewsByUser(user.getUserid());

// }

public String add() {

setReview(new Reviews());

return "addreviews";

}

public String save() {

// if(getUser()==null){

// MessageBox.show("Your session has expired!");

// return "login";

// }

review.setUser(getAuthentication().getUser());

review.setMovie(movie);

dao.create(review);

System.out.println("user : "

+ getAuthentication().getUser().getUsername());

return listall();

}

public String listall() {

setReviewList(dao.getAll());

return "listallreviews";

}

public String list() {

setReviewList(dao.getReviewsForMovie(movie.getMovieId()));

return "listreviews";

}

public void setReview(Reviews review) {

this.review = review;

}

public Reviews getReview() {

return review;

}

public void setReviewList(List<Reviews> reviewList) {

this.reviewList = reviewList;

}

public List<Reviews> getReviewList() {

return reviewList;

}

public List<MovieReviewCount> getCounts() {

List<MovieReviewCount> list = null;

list = dao.getReviewCount();

return list;

}

public void showAll(ActionEvent event) {

topMovies.setRows(0);

}

public void showTop(ActionEvent event) {

topMovies.setRows(5);

}

public void setAuthentication(AuthenticationBean authentication) {

this.authentication = authentication;

}

public AuthenticationBean getAuthentication() {

return authentication;

}

public void showMy() {

setReviewList(dao.getReviewsByUser(getAuthentication().getUser()

.getUserid()));

}

public void setTopMovies(HtmlDataTable topMovies) {

this.topMovies = topMovies;

}

public void showPublic() {

setReviewList(dao.getAll());

}

public HtmlDataTable getTopMovies() {

return topMovies;

}

}

UserBean: backing bean for User pages


import java.util.List;

import javax.faces.application.FacesMessage;

import javax.faces.bean.ManagedBean;

import javax.faces.bean.ManagedProperty;

import javax.faces.bean.SessionScoped;

import javax.faces.context.FacesContext;

import com.mahendra.dao.UserDAO;

import com.mahendra.models.Users;

@ManagedBean

@SessionScoped

public class UserBean {

private UserDAO dao = null;

private String oldpass,newpass1,newpass2;

@ManagedProperty(value="#{authenticationBean.user}")

private Users user = null;

private List<Users> userList;

public void setUser(Users user) {

this.user = user;

}

public Users getUser() {

return user;

}

public String addUser(){

setUser(new Users());

return "adduser";

}

public String editUser(){

return "edituser";

}

public String saveUser(){

dao.create(user.getUsername(), user.getPassword());

return "home";

}

public UserBean() {

dao = new UserDAO();

}

public String updateUser(){

if(getOldpass().equals(user.getPassword())){

if(getNewpass1().equals(getNewpass2())){

dao.changePassword(user.getUserid(), getNewpass1());

return "home";

}

else{

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("new password doesn't match!!"));

return "edituser";

}

}

else

{

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Invalid old password!"));

return "edituser";

}

}

public List<Users> getUserList() {

userList =dao.getAllUsers();

return userList;

}

public void setOldpass(String oldpass) {

this.oldpass = oldpass;

}

public String getOldpass() {

return oldpass;

}

public void setNewpass1(String newpass1) {

this.newpass1 = newpass1;

}

public String getNewpass1() {

return newpass1;

}

public void setNewpass2(String newpass2) {

this.newpass2 = newpass2;

}

public String getNewpass2() {

return newpass2;

}

}

Localization: this application is localized for english language, I am planning to add another language (Marathi). I will post it later….

you can save this in “src” folder or in new source folder in same eclipse project.

LocalizationResources_en.properties:


#messages

welcomeMessage=Welcome to Mahendra's Online Movie reviews

welcomeLine2=From this <span style="text-decoration: underline;">website</span> you can view / add reviews for movies

welcomeLine3=Adding reviews is available to only registered users

top5=Top 5 Movies (# of reviews received)

userRequired=Please enter <span style="text-decoration: underline;">username</span>

passRequired=Please enter password

homePage=Home Page

appTitle=Mahendra's Online Movie Reviews

showAllReviews=Showing ALL Reviews

noReviews=No Reviews found!

userPrompt=Enter <span style="text-decoration: underline;">Username</span>:

passPrompt=Enter Password:

loginTitle=Log In page

#links

linkHome=Home

linkAddMovie=Add New Movie

linkLogIn=Log In

linkLogOut=Log out

linkSignUp=Sign up

linkChangePass=Change Password

linkAllMovies=All Movies

linkAllReviews=All Reviews

linkTop5=Top 5 Only

linkAll=Show All

linkShowMy=Show MY reviews only

linkShowAll=Show ALL

#screenTips

tipShowAll=Show me ALL user's reviews

tipShowMy=Show me ONLY MY reviews

tipShow5=Show TOP 5 Only

#column headings

chTitle=Movie Title

chMessage=Message/Review

chCount=No of Reviews

chAverage=Average Ratings

chTime=Recorded at

chRatings=Ratings

chAuthor=Written By

chNo=Sr No

chTotal=Total Reviews Received

Your “web.xml” needs modification to support JSF


<?xml version=<em>"1.0"</em> encoding=<em>"UTF-8"</em>?>

<web-app xmlns:xsi=<em>"http://www.w3.org/2001/XMLSchema-instance"</em>

xmlns=<em>"http://java.sun.com/xml/ns/javaee"</em> xmlns:web=<em>"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</em>

xsi:schemaLocation=<em>"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</em>

id=<em>"WebApp_ID"</em> version=<em>"2.5"</em>>

<display-name>MovieReviews</display-name>

<welcome-file-list>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<servlet>

<servlet-name>Faces <span style="text-decoration: underline;">Servlet</span></servlet-name>

<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>Faces <span style="text-decoration: underline;">Servlet</span></servlet-name>

<url-pattern>/faces/*</url-pattern>

</servlet-mapping>

<session-config>

<session-timeout>15</session-timeout>

</session-config>

<error-page>

<error-code>404</error-code>

<location>/default.jsp</location>

</error-page>

<error-page>

<exception-type>javax.faces.application.ViewExpiredException</exception-type>

<location>/default.jsp</location>

</error-page>

</web-app>

Now, finally  xhtml pages to render VIEW (UI) for entire web-application.

the entire structure for pages (under “webContents” folder in eclipse project)

default.jsp:                               placeholder page. This is defined as “welcome-page” in web.xml.

It will redirect users to “index.xhtml”

<%@ page language=<em>"java"</em> contentType=<em>"text/html; charset=ISO-8859-1"</em>

pageEncoding=<em>"ISO-8859-1"</em>%>

<%@taglib uri=<em>"http://java.sun.com/jsp/jstl/core"</em>  prefix=<em>"c"</em>%>

<c:redirect url=<em>"/faces/index.xhtml"</em>/>

template.xhtml:     JSF template page to create Common layout


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em>

xmlns:h=<em>"http://java.sun.com/jsf/html"</em>

xmlns:f=<em>"http://java.sun.com/jsf/core"</em>

xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<head>

<f:loadBundle var=<em>"msg"</em> basename=<em>"LocalizationResources"</em> />

<meta http-equiv=<em>"Content-Type"</em> content=<em>"text/html; charset=ISO-8859-1"</em> />

<link type=<em>"text/css"</em> rel=<em>"stylesheet"</em>

href=<em>"#{facesContext.externalContext.requestContextPath}/res/main-style.css"</em> />

<title>#{msg.appTitle} <ui:insert name=<em>"title"</em>>#{msg.homePage}</ui:insert>

</title>

</head>

<body>

<table border=<em>"1"</em> cellspacing=<em>"0"</em> cellpadding=<em>"5"</em> width=<em>"100%"</em>>

<tr <span style="text-decoration: underline;">height</span>=<em>"120px;"</em> bgcolor=<em>"#efd5ab"</em>>

<td><h:form>

<h1>#{msg.welcomeMessage}</h1>

<div style="float: <em>right</em>">

<h:outputText value=<em>"Welcome #{authenticationBean.user.username}"</em>

rendered=<em>"#{authenticationBean.loggedIn}"</em> />

</div>

<h:commandLink value=<em>"#{msg.linkHome}"</em> action=<em>"home"</em> />

<h:commandLink value=<em>"#{msg.linkAllMovies}"</em>

action=<em>"#{movieBean.list}"</em> />

<h:commandLink value=<em>"#{msg.linkAllReviews}"</em>

action=<em>"#{reviewsBean.listall}"</em> />

<h:commandLink value=<em>"#{msg.linkLogIn}"</em>

action=<em>"#{authenticationBean.login}"</em>

rendered=<em>"#{!authenticationBean.loggedIn}"</em> />

<h:commandLink value=<em>"#{msg.linkLogOut}"</em>

action=<em>"#{authenticationBean.logout}"</em>

rendered=<em>"#{authenticationBean.loggedIn}"</em> />

<h:commandLink value=<em>"#{msg.linkChangePass}"</em>

action=<em>"#{userBean.editUser}"</em>

rendered=<em>"#{authenticationBean.loggedIn}"</em> />

</h:form></td>

</tr>

<tr <span style="text-decoration: underline;">height</span>=<em>"400px"</em> valign=<em>"top"</em>>

<td><ui:insert name=<em>"content"</em>>Contents for page</ui:insert></td>

</tr>

<tr bgcolor=<em>"#c5dde6"</em>>

<td><ui:insert name=<em>"footer"</em>>NO Copyrights &copy; 2011 : <span style="text-decoration: underline;">Mahendra</span> <span style="text-decoration: underline;">Shinde</span></ui:insert>

</td>

</tr>

</table>

</body>

</html>

index.xhtml:             The REAL homepage


<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em>

xmlns:h=<em>"http://java.sun.com/jsf/html"</em>

xmlns:f=<em>"http://java.sun.com/jsf/core"</em>

xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>#{msg.homePage}</ui:define>

<ui:define name=<em>"content"</em>>

#{msg.welcomeMessage}<br />

#{msg.welcomeLine2}<br />

<b><i>#{msg.welcomeLine3}</i>

</b>

<h3>#{msg.top5}</h3>

<h:dataTable value=<em>"#{reviewsBean.counts}"</em> var=<em>"m"</em> rows=<em>"5"</em>

styleClass=<em>"dtable"</em> binding=<em>"#{reviewsBean.topMovies}"</em>

rowClasses=<em>"odd,even"</em>>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chTitle}"</em> />

</f:facet>

<h:outputText value=<em>"#{m.title}"</em> />

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chTotal}"</em> />

</f:facet>

<h:outputText value=<em>"#{m.count}"</em> />

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chAverage}"</em> />

</f:facet>

<h:outputText value=<em>"#{m.average}"</em> />

</h:column>

</h:dataTable>

<h:form>

<h:commandLink accesskey=<em>"A"</em> value=<em>"#{msg.linkShowAll}"</em>

actionListener=<em>"#{reviewsBean.showAll}"</em> title=<em>"#{msg.tipShowAll}"</em> />

<h:commandLink accesskey=<em>"t"</em> value=<em>"#{msg.linkTop5}"</em>

actionListener=<em>"#{reviewsBean.showTop}"</em> title=<em>"#{msg.tipShow5}"</em> />

</h:form>

<h:outputText value=<em>"#{msg.noReviews}"</em>

rendered=<em>"#{empty reviewsBean.counts}"</em> />

</ui:define>

</ui:composition>

</html>

login.xhtml:              page for log-in


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em>

xmlns:h=<em>"http://java.sun.com/jsf/html"</em>

xmlns:f=<em>"http://java.sun.com/jsf/core"</em>

xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>#{msg.loginTitle}</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h:messages />

<h:panelGrid columns=<em>"2"</em>>

<h:outputText value=<em>"#{msg.userPrompt}"</em> />

<h:inputText value=<em>"#{authenticationBean.uname}"</em> required=<em>"true"</em>

requiredMessage=<em>"username can not be blank!"</em> />

<h:outputText value=<em>"#{msg.passPrompt}"</em> />

<h:inputSecret value=<em>"#{authenticationBean.upass}"</em> required=<em>"true"</em>

requiredMessage=<em>"password cannot be blank!"</em> />

<h:commandButton value=<em>"#{msg.linkLogIn}"</em>

action=<em>"#{authenticationBean.verifyUser}"</em> />

</h:panelGrid>

</h:form>

</ui:define>

</ui:composition>

</html>

users/add.xhtml:   page to add new user (signup)


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em>

xmlns:h=<em>"http://java.sun.com/jsf/html"</em>

xmlns:f=<em>"http://java.sun.com/jsf/core"</em>

xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>User Registration</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h:panelGrid columns=<em>"3"</em>>

<h:outputText value=<em>"Enter username: "</em> />

<h:inputText value=<em>"#{userBean.user.username}"</em> id=<em>"uname"</em>

required=<em>"true"</em> requiredMessage=<em>"*"</em> />

<h:message for=<em>"uname"</em> />

<h:outputText value=<em>"Enter password: "</em> />

<h:inputSecret value=<em>"#{userBean.user.password}"</em> id=<em>"upass"</em>

required=<em>"true"</em> requiredMessage=<em>"*"</em> />

<h:message for=<em>"upass"</em> />

<h:commandButton value=<em>"Save"</em> type=<em>"submit"</em>

action=<em>"#{userBean.saveUser}"</em> />

<h:commandButton value=<em>"Reset"</em> type=<em>"reset"</em> />

</h:panelGrid>

</h:form>

</ui:define>

</ui:composition>

</html>

users/edit.xhtml:   page to change password


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em>

xmlns:h=<em>"http://java.sun.com/jsf/html"</em>

xmlns:f=<em>"http://java.sun.com/jsf/core"</em>

xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>Change Password</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h:panelGrid columns=<em>"2"</em>>

<h:outputText value=<em>"Enter old password: "</em> />

<h:inputSecret value=<em>"#{userBean.oldpass}"</em> required=<em>"true"</em>

requiredMessage=<em>"Old password is missing!"</em> id=<em>"oldpass"</em> />

<h:outputText value=<em>"Enter new password: "</em> />

<h:inputSecret value=<em>"#{userBean.newpass1}"</em> id=<em>"newpass1"</em>

required=<em>"true"</em> requiredMessage=<em>"New password is missing!"</em> />

<h:outputText value=<em>"Repeate new password: "</em> />

<h:inputSecret value=<em>"#{userBean.newpass2}"</em> id=<em>"newpass2"</em>

required=<em>"true"</em> requiredMessage=<em>"Re-enter new password"</em>>

</h:inputSecret>

<h:commandButton value=<em>"change"</em> type=<em>"submit"</em>

action=<em>"#{userBean.updateUser}"</em> />

<h:messages showSummary=<em>"true"</em> />

</h:panelGrid>

</h:form>

</ui:define>

</ui:composition>

</html>

reviews/add.xhtml


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em>

xmlns:h=<em>"http://java.sun.com/jsf/html"</em>

xmlns:f=<em>"http://java.sun.com/jsf/core"</em>

xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>Add new review</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>Adding

new review for #{reviewsBean.movie.title} <h:panelGrid columns=<em>"3"</em>>

<h:outputText value=<em>"Enter Message: "</em> />

<h:inputTextarea rows=<em>"5"</em> cols=<em>"35" </em>                        value=<em>"#{reviewsBean.review.message}"</em> id=<em>"message"</em> required=<em>"true"</em>

requiredMessage=<em>"*"</em> />

<h:message for=<em>"message"</em> />

<h:outputText value=<em>"Select Ratings: "</em> />

<h:selectOneRadio id=<em>"ratings"</em> required=<em>"true"</em> requiredMessage=<em>"*"</em>

layout=<em>"lineDirection"</em> value=<em>"#{reviewsBean.review.ratings}"</em>>

<f:selectItem itemValue=<em>"1"</em> itemLabel=<em>"*"</em> />

<f:selectItem itemValue=<em>"2"</em> itemLabel=<em>"**"</em> />

<f:selectItem itemValue=<em>"3"</em> itemLabel=<em>"***"</em> />

<f:selectItem itemValue=<em>"4"</em> itemLabel=<em>"****"</em> />

<f:selectItem itemValue=<em>"5"</em> itemLabel=<em>"*****"</em> />

</h:selectOneRadio>

<h:message for=<em>"ratings"</em> />

<h:commandButton value=<em>"Save"</em> type=<em>"submit"</em>

action=<em>"#{reviewsBean.save}"</em>

rendered=<em>"#{authenticationBean.loggedIn}"</em> />

<h:commandButton value=<em>"Reset"</em> type=<em>"reset"</em> />

</h:panelGrid>

</h:form>

</ui:define>

</ui:composition>

</html>

reviews/list.xhtml  : list of reviews for selected movie


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em> xmlns:h=<em>"http://java.sun.com/jsf/html"</em> xmlns:f=<em>"http://java.sun.com/jsf/core"</em> xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>Reviews for #{reviewsBean.movie.title}</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h3>Showing  reviews for <b>#{reviewsBean.movie.title}(#{reviewsBean.movie.realsedIn})</b> directed by <i>#{reviewsBean.movie.director}</i></h3>

<h:dataTable id=<em>"data1"</em> value=<em>"#{reviewsBean.reviewList}"</em> var=<em>"review"</em> styleClass=<em>"dtable"</em> rowClasses=<em>"odd,even"</em>>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"Sr. No."</em>/>

</f:facet>

<h:outputText value=<em>"#{review.reviewId}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"user"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.user.username}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"ratings"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.ratings}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"message"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.message}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"time"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.recordtime}"</em>/>

</h:column>

</h:dataTable>

<h:commandLink value=<em>"new review"</em> action=<em>"#{reviewsBean.add}"</em> rendered=<em>"#{authenticationBean.loggedIn}"</em>>

</h:commandLink>

<h:outputText value=<em>"Be FIRST to review!"</em> rendered=<em>"#{empty reviewsBean.reviewList}"</em>/>

</h:form>

</ui:define>

</ui:composition>

</html>

reviews/listall.xhtml             list of all reviews


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em> xmlns:h=<em>"http://java.sun.com/jsf/html"</em> xmlns:f=<em>"http://java.sun.com/jsf/core"</em> xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>#{msg.showAllReviews}</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h3>#{msg.showAllReviews} <i></i></h3>

<h:dataTable id=<em>"data1"</em> value=<em>"#{reviewsBean.reviewList}"</em> var=<em>"review"</em> styleClass=<em>"dtable"</em> rowClasses=<em>"odd,even"</em>>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chNo}"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.reviewId}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chTitle}"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.movie.title}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chAuthor}"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.user.username}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chRatings}"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.ratings}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"#{msg.chMessage}"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.message}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"time"</em>/>

</f:facet>

<h:outputText value=<em>"#{review.recordtime}"</em>>

<f:convertDateTime type=<em>"both"</em> timeStyle=<em>"medium"</em> timeZone=<em>"IST"</em>/>

</h:outputText>

</h:column>

</h:dataTable>

<h:panelGroup rendered=<em>"#{authenticationBean.loggedIn}"</em>>

<h:commandLink  accesskey=<em>"A"</em> value=<em>"#{msg.linkAll}"</em> actionListener=<em>"#{reviewsBean.showPublic}"</em> title=<em>"#{msg.tipShowAll}"</em>/>

<h:commandLink accesskey=<em>"M"</em> value=<em>"#{msg.linkShowMy}"</em> actionListener=<em>"#{reviewsBean.showMy}"</em> title=<em>"#{msg.tipShowMy}"</em>/>

</h:panelGroup>

</h:form>

</ui:define>

</ui:composition>

</html>

movies/add.xhtml page to add new movie


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em> xmlns:h=<em>"http://java.sun.com/jsf/html"</em> xmlns:f=<em>"http://java.sun.com/jsf/core"</em> xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>Add new movie</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h:panelGrid columns=<em>"3"</em>>

<h:outputText value=<em>"Enter title: "</em>/>

<h:inputText value=<em>"#{movieBean.movie.title}"</em> id=<em>"title"</em> required=<em>"true"</em> requiredMessage=<em>"*"</em>/>

<h:message for=<em>"title"</em>/>

<h:outputText value=<em>"Enter director: "</em>/>

<h:inputText value=<em>"#{movieBean.movie.director}"</em> id=<em>"director"</em> required=<em>"true"</em> requiredMessage=<em>"*"</em>/>

<h:message for=<em>"director"</em>/>

<h:outputText value=<em>"Select Category: "</em>/>

<h:selectOneRadio id=<em>"category"</em> required=<em>"true"</em> requiredMessage=<em>"*"</em> layout=<em>"pageDirection"</em> value=<em>"#{movieBean.movie.category}"</em>>

<f:selectItem itemValue=<em>"comedy"</em> itemLabel=<em>"Comedy"</em>/>

<f:selectItem itemValue=<em>"action"</em> itemLabel=<em>"Action"</em>/>

<f:selectItem itemValue=<em>"comedy-action"</em> itemLabel=<em>"Comedy with action"</em>/>

<f:selectItem itemValue=<em>"sci-fi"</em> itemLabel=<em>"Science Fictions"</em>/>

<f:selectItem itemValue=<em>"thriller"</em> itemLabel=<em>"Thrillers"</em>/>

<f:selectItem itemValue=<em>"horror"</em> itemLabel=<em>"Horror"</em>/>

</h:selectOneRadio>

<h:message for=<em>"category"</em>/>

<h:outputText value=<em>"Enter length (minutes): "</em>/>

<h:inputText value=<em>"#{movieBean.movie.duration}"</em> id=<em>"length"</em> required=<em>"true"</em> requiredMessage=<em>"*"</em>/>

<h:message for=<em>"length"</em>/>

<h:outputText value=<em>"Enter year of release: "</em>/>

<h:inputText value=<em>"#{movieBean.movie.realsedIn}"</em> id=<em>"ryear"</em> required=<em>"true"</em> requiredMessage=<em>"*"</em>/>

<h:message for=<em>"ryear"</em>/>

<h:commandButton value=<em>"Save"</em> type=<em>"submit"</em> action=<em>"#{movieBean.save}"</em> rendered=<em>"#{authenticationBean.loggedIn}"</em>/>

<h:commandButton value=<em>"Reset"</em> type=<em>"reset"</em>/>

</h:panelGrid>

</h:form>

</ui:define>

</ui:composition>

</html>

movies/list.xhtml   page to list all movies


<?xml version=<em>"1.0"</em> encoding=<em>"ISO-8859-1"</em> ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=<em>"http://www.w3.org/1999/xhtml"</em> xmlns:h=<em>"http://java.sun.com/jsf/html"</em> xmlns:f=<em>"http://java.sun.com/jsf/core"</em> xmlns:ui=<em>"http://java.sun.com/jsf/facelets"</em>>

<ui:composition template=<em>"/WEB-INF/layout/template.xhtml"</em>>

<ui:define name=<em>"title"</em>>List of Movies</ui:define>

<ui:define name=<em>"content"</em>>

<h:form>

<h:dataTable id=<em>"data1"</em> value=<em>"#{movieBean.moviesList}"</em> var=<em>"movie"</em> styleClass=<em>"dtable"</em> rowClasses=<em>"odd,even"</em>>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"Sr. No."</em>/>

</f:facet>

<h:outputText value=<em>"#{movie.movieId}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"TITLE"</em>/>

</f:facet>

<h:outputText value=<em>"#{movie.title}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"DIRECTOR"</em>/>

</f:facet>

<h:outputText value=<em>"#{movie.director}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"CATEGORY"</em>/>

</f:facet>

<h:outputText value=<em>"#{movie.category}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"LENGTH"</em>/>

</f:facet>

<h:outputText value=<em>"#{movie.duration}"</em>/>

</h:column>

<h:column>

<f:facet name=<em>"header"</em>>

<h:outputText value=<em>"Reviews"</em>/>

</f:facet>

<h:commandLink value=<em>"read reviews"</em> action=<em>"#{reviewsBean.list}"</em>>

<f:setPropertyActionListener target=<em>"#{reviewsBean.movie}"</em> value=<em>"#{movie}"</em>/>

</h:commandLink>

</h:column>

</h:dataTable>

<h:commandLink value=<em>"Add movie"</em> action=<em>"#{movieBean.add}"</em> rendered=<em>"#{authenticationBean.loggedIn}"</em>></h:commandLink>

</h:form>

</ui:define>

</ui:composition>

</html>

res/main-style.css  CSS stylesheet for entire application


@CHARSET <em>"ISO-8859-1"</em>;

<strong>body</strong>

{

margin:<em>10px</em>;

background-color: <em>#ddeedd</em>;

}

<strong>a</strong>

{

display: <em>inline-block</em>;

padding:<em>4px</em>;

color:<em>#ff0033</em>;

font-family: <em>Tahoma</em>;

font-size: <em>11pt</em>;

}

<strong>a</strong><em>:hover</em>{

background-color: <em>#793900</em>;

color:<em>white</em>;

text-decoration: <em>none</em>;

}

<em>.dtable</em>

{

font-family: <em>Arial</em>;

font-size: <em>11pt</em>;

padding: <em>5px</em>;

cellpadding:<em>10px</em>;

border:<em>2px</em> <em>solid</em> <em>black</em>;

}

<em>.dtable</em> <strong>thead</strong>

{

background-color: <em>#cc9c6c</em>;

color:<em>#770000</em>;

}

<em>.dtable</em> <em>.odd</em>

{

background-color: <em>#fedea3</em>;

border-bottom-color: <em>darkred</em>;

}

<em>.dtable</em> <strong>tbody</strong> <strong>tr</strong> <strong>td</strong> {

border-top: <em>1px</em> <em>solid</em> <em>#cc9c6c</em>;

border-bottom: <em>1px</em> <em>solid</em> <em>#cc9c6c</em>;

}

<em>.dtable</em> <em>.even</em>

{

background-color: <em>#fede49</em>;

border-bottom: <em>1px</em> <em>solid</em> <em>darkred</em>;

}

<em>.dtable</em> <strong>th,td</strong>

{

padding: <em>5px</em>;

}

<em>.dtable</em> <strong>tbody</strong> <strong>tr</strong><em>:hover</em> <strong>td</strong>

{

border-top: <em>0px</em> <em>solid</em> <em>darkred</em>;

background-color:<em>#9fcc86</em>;

border-bottom: <em>2px</em> <em>solid</em> <em>darkred</em>;

}

<strong>h1,h2,h3</strong>

{

font-family: <em>Tahoma</em>;

text-shadow: <em>2px</em> <em>3px</em> <em>orange</em>;

}

JSF 2.0 with hibernate 3.0 tutorial, Online Movie Reviews web-app part 2

JSF 2.0 with hibernate 3.0 tutorial, Online Movie Reviews web-app part 2

in last post, you have seen all model classes, hibernate configuration and mappings.

in this post I will show you Data Access Objects (DAO components: data access layer)

for each Model class, I have created a separate DAO class:

com.mahendra.dao.MovieDAO


package com.mahendra.dao;
import java.util.List;
import org.hibernate.*;
import com.mahendra.models.Movies;
import com.mahendra.utils.HibernateUtils;

public class MovieDAO {

SessionFactory fact = null;

public MovieDAO() {
fact = HibernateUtils.getSessionFactory();
}

public void create(Movies m) {

Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
session.save(m);
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}

}

public Movies getMovie(String title) {
Session session = fact.getCurrentSession();
Transaction t = null;
Movies m = null;
try {
t = session.beginTransaction();
m = (Movies) session.createQuery("from Movies where title=:title")
.setString("title", title).list().get(0);
t.commit();
} catch (HibernateException he) {

if (t != null)
t.rollback();
he.printStackTrace();
}

return m;
}

public Movies getMovie(int id) {
Session session = fact.getCurrentSession();
Transaction t = null;
Movies m = null;
try {
t = session.beginTransaction();
m = (Movies) session.get(Movies.class, id);
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}

return m;
}

public List<Movies> getAllMovies() {
List<Movies> list = null;
Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
list = session.createQuery("from Movies").list();
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}

return list;
}

}

com.mahendra.dao.ReviewsDAO:

package com.mahendra.dao;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.*;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.transform.Transformers;
import com.mahendra.models.Movies;
import com.mahendra.models.Reviews;
import com.mahendra.utils.HibernateUtils;
import com.mahendra.utils.MovieReviewCount;

public class ReviewsDAO {

private SessionFactory fact;

public ReviewsDAO() {
fact = HibernateUtils.getSessionFactory();
}

public void create(Reviews review) {
Session session = fact.getCurrentSession();

Transaction t = null;
try {
t = session.beginTransaction();
session.save(review);
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}
}

@SuppressWarnings("unchecked")

public List<Reviews> getReviewsForMovie(int id) {
List<Reviews> list = null;
Session session = fact.getCurrentSession();
Transaction t = null;

try {
t = session.beginTransaction();
list = session
   .createQuery("from Reviews where movie.movieId=:movieid")
   .setInteger("movieid", id).list();
t.commit();

} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}

return list;
}

public Reviews getReview(int id) {
Session session = fact.getCurrentSession();
Reviews review = null;
Transaction t = null;
try {
t = session.beginTransaction();
review = (Reviews) session.get(Reviews.class, id);
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}

return review;
}

public List<Reviews> getReviewsByUser(int userid) {
List<Reviews> list = null;
Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
list = session.createQuery("from Reviews where userid = :userid")
.setInteger("userid", userid).list();
t.commit();
} catch (HibernateException he) {

if (t != null)
t.rollback();
he.printStackTrace();
}

return list;
}

public List<Reviews> getAll() {
List<Reviews> list = null;
Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
list = session.createQuery("from Reviews").list();
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();
}

return list;
}

public Movies getTopper() {
Movies m = null;
Session session = fact.getCurrentSession();

Transaction t = null;
try {
t = session.beginTransaction();
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();

}

return m;
}

public List<MovieReviewCount> getReviewCount() {

List<MovieReviewCount> list = new ArrayList<MovieReviewCount>();
Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
SQLQuery q = session
.createSQLQuery("select m.title as title,count(r.message) as count, avg(r.ratings) as average  from app.movies m join app.reviews"
+ " r on (m.movie_id=r.movie_id) group by m.title"
+ " order by count(r.message) desc");
q.addScalar("title")
.addScalar("count")
.addScalar("average")
.setResultTransformer(
Transformers.aliasToBean(MovieReviewCount.class));
list = q.list();
t.commit();

} catch (HibernateException he) {
if (t != null)
t.rollback();
System.out.println("Error: ");
he.printStackTrace();
}

return list;
}

}

com.mahendra.dao.UserDAO:


package com.mahendra.dao;

import java.util.List;
import org.hibernate.*;
import com.mahendra.models.Users;
import com.mahendra.utils.HibernateUtils;

public class UserDAO {

SessionFactory fact = null;

public UserDAO() {
fact = HibernateUtils.getSessionFactory();
}

public void create(String username, String password) {

Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
Users user = new Users();
user.setUsername(username);
user.setPassword(password);
Object obj = session.save(user);
System.out.println(obj);
t.commit();
System.out.println("record!");
} catch (HibernateException he) {

if (t != null)
t.rollback();
he.printStackTrace();
}
}

public List<Users> getAllUsers() {

Session session = fact.getCurrentSession();
Transaction t = null;
List<Users> users = null;
try {
t = session.beginTransaction();
users = (List<Users>) session.createQuery("from Users").list();
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
System.out.println("Error: " + he.getMessage());
}

return users;

}

public void delete(int userid) {
Session session = fact.getCurrentSession();
Transaction t = null;
try {
t = session.beginTransaction();
Users user = (Users) session.get(Users.class, userid);
if (user == null)
throw new HibernateException("Record not found!");
session.delete(user);
t.commit();
} catch (HibernateException he) {
if (t != null)
t.rollback();
System.out.println("Error: " + he.getMessage());
}

}

public Users getUser(String username) {

Session session = fact.getCurrentSession();
Transaction t = null;
Users user = null;
try {
t = session.beginTransaction();
Query q = session.createQuery("from Users where username = :uname");
q.setString("uname", username);
List<Users> list = q.list();
if (list == null || list.isEmpty())
throw new RuntimeException("user '" + username
+ "' doesnot exists!");
user = list.get(0);
t.commit();

} catch (HibernateException he) {
if (t != null)
t.rollback();
he.printStackTrace();

}

return user;
}

public void changePassword(int userid, String newpass) {

Session session = fact.getCurrentSession();
Transaction t = null;
try {

t = session.beginTransaction();
Users user = (Users) session.get(Users.class, userid);
if (user == null)
throw new HibernateException("Record not found!");

user.setPassword(newpass);
session.update(user);
t.commit();

} catch (HibernateException he) {
if (t != null)
t.rollback();

System.out.println("Error: " + he.getMessage());
}

}

public Users getUser(int userid) {

Session session = fact.getCurrentSession();
Transaction t = null;
Users user = null;
try {
t = session.beginTransaction();
user = (Users) session.get(Users.class, userid);
if (user == null)
throw new HibernateException("Record not found!");
t.commit();
} catch (HibernateException he) {

if (t != null)
t.rollback();
he.printStackTrace();
}

return user;
}

}

next post… JSF configaration & navigation

Simple Blog type web-application using Struts+Hibernate+MySql

  1. Create table in database “mahendra”

create table blogEntry

(

blogid int primary key auto_increment,

username varchar(35)not null,

emailid varchar(60)not null,

message varchar(1000),

edate timestamp default now()

);

  1. Create new Dynamic Web Application using eclipse.
  2. Add required libraries into “lib” folder.
  3. Modify “web.xml” fileà add following lines:

<filter>

<filter-name>mahendra</filter-name>

<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

</filter>

<filter-mapping>

<filter-name>mahendra</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

  1. Create new JSP page inside “WebContent”à index.jsp
  2. Run your application for testing
  3. Create new “Source Folder” with name : “resources”
  4. Add new File with name: log4j.properties with following contents:

log4j.rootLogger = DEBUG, CA, FA

log4j.appender.CA = org.apache.log4j.ConsoleAppender

log4j.appender.CA.layout = org.apache.log4j.PatternLayout

log4j.appender.CA.ConversionPattern=%-5p %c %x {%m} %n

log4j.appender.FA = org.apache.log4j.FileAppender

log4j.appender.FA.layout = org.apache.log4j.PatternLayout

log4j.appender.FA.File=./sample.log

log4j.appender.FA.ConversionPattern=%-4r [%t] %-5p %c %x – %m%n

  1. Add new XML file with name “struts.xml” with following contents

<!DOCTYPE struts PUBLIC

“-//Apache Software Foundation//DTD Struts Configuration 2.0//EN”

http://struts.apache.org/dtds/struts-2.0.dtd&#8221;

>

<struts>

<package name=“default” extends=“struts-default” namespace=“”>

<action name=“review” class=“com.mahendra.ReviewsAction” method=“list”>

<result>/WEB-INF/pages/reviews.jsp</result>

<result name=“error”>/WEB-INF/pages/reviews.jsp </result>

</action>

<action name=“add_review” class=“com.mahendra.ReviewsAction” method=“add”>

<result name=“success” type=“chain”>review</result>

<result name=“error”>/WEB-INF/pages/reviews.jsp </result>

</action>

</package>

</struts>

  1. Create new class called “Reviews” (Model component)

package com.mahendra;

import java.sql.Timestamp;

import javax.persistence.*;

@Entity

@Table(name=”blogentry”)

public class Reviews implements java.io.Serializable{

private static final long serialVersionUID = 1L;

private int blogid;

private String username;

private String emailid;

private String message;

private Timestamp edate;

@Id

@GeneratedValue

public int getBlogid() {

return blogid;

}

public void setBlogid(int blogid) {

this.blogid = blogid;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getEmailid() {

return emailid;

}

public void setEmailid(String emailid) {

this.emailid = emailid;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public Timestamp getEdate() {

return edate;

}

public void setEdate(Timestamp edate) {

this.edate = edate;

}

public Reviews(int blogid, String username, String emailid, String message

) {

super();

this.blogid = blogid;

this.username = username;

this.emailid = emailid;

this.message = message;

}

public Reviews() {

super();

}

}

  1. Create new class called “HibernateUtils” :

package com.mahendra;

import org.hibernate.*;

import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtils {

private static SessionFactory sessionFactory = buildFactory();

private static SessionFactory buildFactory(){

try{

return new AnnotationConfiguration().configure().buildSessionFactory();

}catch(Exception ex){

throw new ExceptionInInitializerError(“Unable to initialize session factory”);

}

}

public static SessionFactory getSessionFactory(){

return sessionFactory;

}

public static Session getSession()

{

return sessionFactory.getCurrentSession();

}

}

  1. Create new class “ReviewsManager”

package com.mahendra;

import java.util.List;

import org.hibernate.HibernateException;

import org.hibernate.*;

public class ReviewsManager {

@SuppressWarnings(“unchecked”)

public List<Reviews> getAllReviews(){

Session session = HibernateUtils.getSession();

List<Reviews> list = null;

Transaction tran = null;

try{

tran = session.beginTransaction();

list = (List<Reviews>)session.createQuery(“from Reviews”).list();

tran.commit();

}catch(HibernateException he){

tran.rollback();

throw new MyException(“Unable to retrieve list of Reviews”,he.getMessage());

}

return list;

}

public void addReview(Reviews review){

Session session = HibernateUtils.getSession();

Transaction tran = null;

try{

tran = session.beginTransaction();

session.save(review);

tran.commit();

}catch(HibernateException he){

throw new MyException(“Unable to add your review.”,he.getMessage());

}

}

}

  1. Create new Exception with name “MyException”

package com.mahendra;

public class MyException extends RuntimeException {

String technicalDetails;

public MyException() {

// TODO Auto-generated constructor stub

}

public MyException(String arg0) {

super(arg0);

// TODO Auto-generated constructor stub

}

public MyException(String arg0, String arg1) {

super(arg0);

technicalDetails = arg1;

}

public String getTechnicalDetails(){

return technicalDetails;

}

}

  1. Create “ReviewAction” (Action compoenet)

package com.mahendra;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class ReviewsAction extends ActionSupport{

private static final long serialVersionUID = 1L;

private ReviewsManager rman = null;

private Reviews review = null;

private List<Reviews> reviewList = null;

public ReviewsAction(){

rman = new ReviewsManager();

}

public String list()

{

try{

reviewList = rman.getAllReviews();

return “success”;

}catch(ExceptionInInitializerError ex){

addActionMessage(“Could not connect with database”);

addActionError(“ERROR: “+ex.getMessage());

return “error”;

}catch(MyException me){

addActionMessage(me.getMessage());

addActionError(me.getTechnicalDetails());

return “error”;

}

}

public String add(){

try{

rman.addReview(getReview());

return “success”;

}catch(MyException me){

addActionMessage(me.getMessage());

addActionError(me.getTechnicalDetails());

return “error”;

}

}

public Reviews getReview() {

return review;

}

public void setReview(Reviews review) {

this.review = review;

}

public List<Reviews> getReviewList() {

return reviewList;

}

public void setReviewList(List<Reviews> reviewList) {

this.reviewList = reviewList;

}

}

  1. Create new JSP page :  /WEB-INF/pages/reviews.jsp

<%@ page language=“java” contentType=“text/html; charset=ISO-8859-1”

pageEncoding=“ISO-8859-1”%>

<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”&gt;

<%@taglib uri=http://java.sun.com/jsp/jstl/core&#8221;  prefix=“c”%>

<%@taglib uri=“/struts-tags”  prefix=“s”%>

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1”>

<title>Insert title here</title>

</head>

<body>

list of reviews

<c:if test=${reviewList != null }>

<c:forEach items=${reviewList} var=“review”>

<table border=“1” width=“300” align=“right”>

<tr>

<td width=“100”>${review.blogid}</td>

<td>by ${review.username}</td>

<td>EMail: ${review.emailid}</td>

</tr>

<tr>

<td>Message: </td>

<td colspan=“2”>

${review.message }

</td>

</tr>

<tr>

<td colspan=“3” align=“right”>

recorder at : ${review.edate}

</td>

</tr>

</table> <br/>

</c:forEach>

</c:if>

<c:if test=“{reviewList is empty}”>

No reviews found!<br/>

Be First to add review..!

</c:if>

<s:form action=“add_review” method=“POST”>

<s:textfield name=“review.username” label=“Your name: “>

</s:textfield><br/>

<s:textfield name=“review.emailid” label=“Your Email ID:”></s:textfield><br/>

<s:textarea name=“review.message” label=“Your views:” rows=“4” cols=“40”>

</s:textarea><br/>

<s:submit value=“Submit”></s:submit>

</s:form>

<s:actionmessage/>

<font face=“Tahoma” size=“2” color=“red”>

<s:actionerror/>

</font>

</body>

</html>

  1. Create new JSP page index.jsp

<%@ page language=“java” contentType=“text/html; charset=ISO-8859-1”

pageEncoding=“ISO-8859-1”%>

<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”&gt;

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1”>

<title>Home page: Mahendra’s Blog</title>

</head>

<body>

<h2>Some topic…..</h2>

<p>

Some details here…..

</p>

<a href=“reviews”>View / Add Reviews</a>

</body>

</html>