Wednesday, August 4, 2010

Java Proxy Pattern - Caching proxy



Proxy pattern applied to enable caching - a very simple Web Application



Recently I switched to work for another customer (Bank\Trading) and one of the first activities, in order to offer a more structured and well-designed product to users, was to reduce the overhead and the Database accesses. Considering that I am working on a web portal with 2 millions of contacts per month and hundreds of user accounts, designed and developed more than 10 years ago, it is very difficult to adopt any Java Framework and, in general, to implement whatever big modification. I studied several solutions to optimize the system’s performances. One of the pattern that comes to help in my work is the Proxy Pattern. I’m going to show you some aspects of this pattern, related to caching objects and data. This article is divided into two parts, one for each solution that I found to this issue. We’ll go into a very simple web application: NO dependency injection this time, NO Spring, NO Frameworks, only very simple code. We’ll create a simple web app that on home page will print the timestamp of last created instance of cached object. Consider that this object may be a complex data structure from a database, or a big image or something very painful for server. For our purpose, things are simplified. Well, we can summarize: 1. user requires an object 2. system check: an instance of this object already is created? 3. If no, it create a new instance, otherwise it give back the already made instance. 4. The user, transparently, receives the object. Let’s go! Configure Eclipse. Just create a New Dynamic Web Project, I called proxycacheapp. I used this project for both solutions that I’m going to implement. UML Class Diagram of a classical Proxy pattern from original GoF book, is:



 

And, briefly: the JSP contains the code for execute the request, that is wrapped by Servlet Filter (declared in web.xml as I hope you already know), Servlet Filter calls our ProxyService to achieve what user wants. ProxyService is only a surrogate, if the object required is ready and already created, it give back to user the cached instance, otherwise Proxy calls concrete RealService and require to create a new one. Object (either brand new or cached) is sent to output of ServletFilter, that incapsulate it into HttpRequest and, later Jsp prints it on Web page. Simple. This is a general scenario, but pragmatic implementation, can be made using two different solutions. Solution 1 Plain, classical, proxy pattern applied. This solution uses only diagrams and the previous explanation, no more complication. Domain Object It is very useless here, but I want to show you that it is possible to use any custom Object in this approach. Let’s create a new object, a POJO, with an ID and a timestamp..later we’ll print timestamp on JSP. Create new Java Class on Eclipse and write th wolling code (I use it.nickg.utils package):

package it.nickg.utils;

public class Timestamp {
 private long id;
 private String timestamp;

 public long getId() {
  return id;
 }

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

 public String getTimestamp() {
  return timestamp;
 }

 public void setTimestamp(String timestamp) {
  this.timestamp = timestamp;
 }
}


This is our Domain object. Now let’s implement the Proxy Pattern, first create a new interface (package is it.nickg.services):
package it.nickg.services;

import it.nickg.utils.Timestamp;

public interface TimestampService {

 /**
  * retrieve an istance of Timestamp object
  * 
  * @return Timestamp object
  */
 public Timestamp getTimestamp();

}








Then let’s write the Real implementation of Service, that creates instance of our Domain Object, it implements our previously created interface:
package it.nickg.services;

import it.nickg.utils.Timestamp;

import java.util.Date;

public class TimestampServiceReal implements TimestampService {

 @Override
 public Timestamp getTimestamp() {

  Date time = new Date();
  Timestamp timestamp = new Timestamp();

  timestamp.setId(time.getTime());
  timestamp.setTimestamp(time.toString());

  return timestamp;
 }

}




Not best solution for getting a timestamp, I know, but it is only for a learning purpose. Look at the concept.
package it.nickg.services;

import it.nickg.utils.Timestamp;

public class TimestampServiceProxy implements TimestampService {

 private TimestampServiceReal timestampServiceReal;
 public Timestamp timestamp;

 @Override
 public Timestamp getTimestamp() {

  // Proxy checks if a real instance of service (and of timestamp object)
  // already is created
  if (timestampServiceReal == null) {
   timestampServiceReal = new TimestampServiceReal();
   timestamp = timestampServiceReal.getTimestamp();
  }

  // return required object
  return timestamp;
 }
}



Now, It’s time to code our front-end!
Most of the work is done through a Servlet Filter that wraps request, calls our services and sets a parameter in HttpResponse, with results.

Servlet Filter must be declared in web.xml:
(complete web.xml code)
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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">
 <filter>
  <filter-name>TimestampFilter</filter-name>
  <filter-class>it.nickg.servlets.TimestampFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>TimestampFilter</filter-name>
  <url-pattern>/index.jsp</url-pattern>
 </filter-mapping>

 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
</web-app>


Here Servlet Filter code:
package it.nickg.servlets;

import it.nickg.services.TimestampService;
import it.nickg.services.TimestampServiceProxy;
import it.nickg.utils.Timestamp;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class TimestampFilter implements Filter {
 TimestampService tsService = new TimestampServiceProxy();

 public TimestampFilter() {
  // TODO Auto-generated constructor stub
 }

 @Override
 public void destroy() {
  // TODO Auto-generated method stub

 }

 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
   ServletException {

  Timestamp timestamp = null;

  // retrieve a timestamp from service
  timestamp = tsService.getTimestamp();
  request.setAttribute("timestamp", timestamp);

  // forward output
  chain.doFilter(request, response);
 }

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  // TODO Auto-generated method stub

 }

}



Last step is about editing index.jsp, and let display the creation’s timestamp of Domain Object:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@page import="it.nickg.utils.Timestamp"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>Proxy Pattern Example</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
  
  <body>
    <h3>Domain object is created:</h3><br>
    <%
     Timestamp timestamp = (Timestamp)request.getAttribute("timestamp");
     out.print(timestamp.getTimestamp());
     %>
  </body>
</html>




I HATE to use scriplet and Java code in JSPs, use jstl, struts taglib, any other technology. Especially in production code.

That’s all, now run our server inside Eclipse (I use tomcat)
Right click on project -> Run as  -> Server Application.

Now on welcome page, it displays first creation timestamp of the object and if you refresh the page, the timestamp doesn’t change:
It is cached!!







Simple, isn’t?

Well, It’s time for more complicated issues.



Solution 2

A more experienced reader can found my previous solution a bit like “reinventing the wheel” and it’s in part true, because java offers a Proxy class:

java.lang.reflect.Proxy

Using Java reflection it is possible to implement a more elegant representation of Proxy Pattern.

For a cleaner implementation, we define a TimestampServiceFactory:

package it.nickg.services;

import java.lang.reflect.Proxy;

public class TimestampServiceFactory {
 public TimestampService createService() {
  return (TimestampService) Proxy.newProxyInstance(
   TimestampService.class.getClassLoader(),
   new Class[] { TimestampService.class },
   new TimestampReflectProxy(new TimestampServiceReal()));
 }
}



Here we use Proxy.newProxyInstance() to call a proxy. It returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler(TimestampReflectProxy).

And an interface CacheIFace:
package it.nickg.services;

public interface CacheIFace {

 /**
  * Retrieve object from cache
  * 
  * @param key
  * @return cached object
  */
 public Object getCache(Object key);

 /**
  * Put a new object in cache
  * 
  * @param key
  * @param value
  */
 public void putCache(Object key, Object value);
}



and an implementation class Cache:
package it.nickg.services;

import java.util.HashMap;
import java.util.Map;

public class Cache implements CacheIFace {
 private Map<Object, Object> values;

 public Cache() {
  this.values = new HashMap<Object, Object>(8);
 }

 public Object getCache(Object key) {
  return values.get(key);
 }

 public void putCache(Object key, Object value) {
  values.put(key, value);
 }
}



These comes to let us perform caching feature through an HashMap:
HashMap IS the cache.

Create a new Java Class named TimestampReflectProxy that implements InvocationHandler:
package it.nickg.services;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;

public class TimestampReflectProxy implements InvocationHandler {

 private final Object obj;
 private CacheIFace caches;
 private static final Object NullKey = new Object();

 public TimestampReflectProxy(Object toProxy) {
  this.obj = toProxy;
  this.caches = new Cache();
 }

 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

  CacheIFace cache = (CacheIFace) caches.getCache(method);

  if (cache == null) {
   caches.putCache(method, cache = new Cache());
  }

  Object argsList = args != null ? Arrays.asList(args) : NullKey;
  Object cacheValue = cache.getCache(argsList);

  if (cacheValue == null) {
   cache.putCache(argsList, cacheValue = method.invoke(obj, args));
  }
  return cacheValue;
 }
}



And, finally, here is the ServletFilter modified:
package it.nickg.servlets;

import it.nickg.services.TimestampService;
import it.nickg.services.TimestampServiceFactory;
import it.nickg.utils.Timestamp;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class TimestampFilter implements Filter {
 // TimestampService tsService = new TimestampServiceProxy();
 TimestampServiceFactory tsFactory = new TimestampServiceFactory();
 TimestampService tsService = tsFactory.createService();

 public TimestampFilter() {
  // TODO Auto-generated constructor stub
 }

 @Override
 public void destroy() {
  // TODO Auto-generated method stub

 }

 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
   ServletException {

  Timestamp timestamp = null;

  // retrieve a timestamp from service
  timestamp = tsService.getTimestamp();
  request.setAttribute("timestamp", timestamp);

  // forward output
  chain.doFilter(request, response);
 }

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  // TODO Auto-generated method stub

 }
}

I try to explain this magic trick.
Our TimestampReflectProxy class has two private attributes, obj and caches.
When user requires the page, the TimestampFilter acts as wrapper, it catches the request and calls TimestampServiceFactory and TimestampService that requires to create the service.

First time, it passes TimestampServiceReal as Object to  TimestampReflectProxy ‘s constructor, so:
- obj is an instance of TimestampServiceReal;
- a new instance of Cache is created;

Then the filter calls getTimestamp() method and this call is caught with reflection:
- it enters in invoke() method,
- it checks if an occurrence of method is already present in caches,
- there isn’t the required occurrence and so cache is null,
- it puts a new entry in cache;
- then retrieve the args list and checks if there is an entry in cache with given key;
- if not, it create a new one invoking method;

From this time, every time the user refreshs the web page, the application using reflection, finds existing entries in cache, skips checks, and gives back to him.

Here the results, if you try to refresh the page, display doesn’t change:







While this second solution seems very interesting, advanced, elegant and cool..there are several drawbacks:
(cut and paste from Sun)

Performance Overhead
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
Security Restrictions
Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.
Exposure of Internals
Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

Some interesting discussions are linked above between references.

Enough to avoid it in my particular use case.

Last thing I want to show.
Perhaps more careful of you have observed that when an instance of an object is created, it can live forever!
(Well, I know, it’s impossible, but “undefined” and “forever” are both unacceptable in my opinion).

Best way to give the capability of periodical refresh of object, is implementing a TimeToLive Strategy. (Other possible solutions are LRU and LFU).
I’ll not describe here now, but give you some input:
Into our Cache class, it is necessary to code a thread that periodically cleans the cache and you can use whatever policy you want.

That’s all folks!

Please, feel free to add comment and critics to my article, they are very useful.







References:

About Reflection:

About reflection performances:

Saturday, July 17, 2010

Busy!!

Hi there,
I wish to publish some new articles here, but, believe, it is a bad period for me.. a lot of troubles that have the ability to come always together prevent me from post new stuff.
BUT..
Don't worry! I'm spoilt for choice about arguments.
As soon as possible, new comings! ;)

Sunday, May 23, 2010

Spring, Struts 2 - part 2

Adding database management.

According to previous article, now I am going to show how to manage a database within our previous created web application.
The result is a very simple application, but I hope it will be useful to understand the way to perform similar tasks.

For this purpose, I will use:

* HSQLDB, a data leading SQL relational database engine written in Java, I think I'll write an article about it as soon as possible..It is very interesting and powerful.
* Hibernate, ORM that no needs presentations!
* Spring Framework, especcialy Transaction Manager, I think that it is an underestimated feature of framework.


Our application will retrieve from database some records containing strings that will be printed in a jsp (they will print a classical Hello World message).

First Step: configuring HSQLDB database

Download latest version of hsqldb database, currently is 2.0.0 (rc9). Then I follow instructions from website and report here:

depending on platform you use (Windows or Linux or whatever you prefer) the procedure to be followed is almost the same.

* uncompress the zip folder downloaded from website;
* start HSQLDB server: under installation folder type 'cd data' and then '@java -classpath ../lib/hsqldb.jar org.hsqldb.server.Server %1 %2 %3 %4 %5 %6 %7 %8 %9' (wait for completion of boot process);
* run an SQL client to connect to database server. I use MyEclipse IDE, but anyone can be used, the default connection parameters (if you just downloaded hsqldb package) are: connection URL jdbc:hsqldb:hsql://localhost/ , username SA , password ; for further configuration issues, I suggest to read HSQLDB wiki, it is very helpful and quick.
* Create new table with name HELLO, columns are: ID, PHRASE (ID must be set as numeric primary key, not nullable and incrementable, while PHRASE is a VARCHAR(15));
* Insert new records in that table (follow my same order): ID:1 - PHRASE:'Hello ', ID:2 - PHRASE:'World! ', ID:3 - PHRASE:'This data ', ID:4 - PHRASE:'is stored ', ID:5 - PHRASE:'in database ';


Second Step: configuring Hibernate project

This step is simple for me, making use of MyEclipse and I hope also for you, guessing the procedure to follow is similar.

First of all I create an external (referred in main one) project that will be used as Hibernate's project, from my IDE I click on "Create new Java Project" and once it is created, I right-click on it and then "Add Hibernate Capability". I give it the name: "hibernate-mapping".

Libraries:



Typically, in creation window, the IDE ask to user for innformation about database, here you have to put connection url, username etc etc. Let to create SessionFactory.
Now is time to create mapping between database and POJO. With MyEclipse this thing is very simple:
Just, right-click on table you want to map (in our case is HELLO) -> Hibernate Reverse Engineering ->
In popup window select previously created project's source folder (Hibernate project), select only "Create POJO", select "Java Data Object" -> Finish.

Now you should have something similar to this:




Now we create a new Web Application (it is the same used in previous posted article, with a few of modifies) and import the hibernate project as dependency of this project.
This is our main project.
Main project integrates Struts2 and Spring and for this reason I suggest to read this to full understand the code shown below.
Action code:

package it.nickg.webapp.web.actions;

import it.nickg.webapp.services.HelloService;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class HelloAction extends ActionSupport {

private HelloService helloService;
private List words;

public List getWords() {
return words;
}

public void setWords(List words) {
this.words = words;
}

public HelloService getHelloService() {
return helloService;
}

public void setHelloService(HelloService helloService) {
this.helloService = helloService;
}

@Override
public String execute() throws Exception {

words = helloService.getWords();
return SUCCESS;
}
}
Business service interface:

package it.nickg.webapp.services;

import java.util.List;

public interface HelloService {

public abstract List getWords();
}


Business service implementation:

package it.nickg.webapp.services.impl;

import it.nickg.hibernate.mapping.Hello;
import it.nickg.webapp.DAO.HelloDAO;
import it.nickg.webapp.services.HelloService;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

@Transactional
public class HelloServiceImpl implements Serializable, HelloService {

private HelloDAO helloDao;

public void setHelloDao(HelloDAO helloDao) {
this.helloDao = helloDao;
}

public List getWords() {

List

phrases = (List) helloDao.getPhrases(); List words = new ArrayList(); for (Iterator

iterator = phrases.iterator(); iterator.hasNext();) { String word = ((Hello) iterator.next()).getPhrase(); words.add(word); } return words; } }

DAO Interface:
package it.nickg.webapp.DAO;

import java.util.Collection;

import org.hibernate.SessionFactory;

public interface HelloDAO {

public abstract void setSessionFactory(SessionFactory sessionFactory);

public abstract Collection

getPhrases(); }

DAO Implementation:
package it.nickg.webapp.DAO.impl;

import it.nickg.hibernate.mapping.Hello;
import it.nickg.webapp.DAO.HelloDAO;

import java.util.Collection;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class HelloDaoImpl implements HelloDAO {
private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

public Collection

getPhrases() { Collection

phrases; Session session = this.sessionFactory.getCurrentSession(); phrases = session.createCriteria(Hello.class).list(); return phrases; } }

At this point, the essential point of integration, applicationContext.xml file. Adding this lines lets Spring to manage datasource:






Then define Hibernate's SessionFactory, within Spring management:




it/nickg/hibernate/mapping/Hello.hbm.xml




hibernate.dialect=org.hibernate.dialect.HSQLDialect
       


Now, let's define Dependency Injection, briefly: inject SessionFactory into DAO, DAO into Service, Service into Action and applicationContext.xml will look as shown below:













it/nickg/hibernate/mapping/Hello.hbm.xml




hibernate.dialect=org.hibernate.dialect.HSQLDialect
       














BUT, if you try to run application an Hibernate exception will prevent it from working, because Transaction Management misses. There are many choices for Transaction management, I prefer to use the annotation-base approach, which requires to add this lines at applicationContext.xml:




Final applicationContext.xml will be:
>












it/nickg/hibernate/mapping/Hello.hbm.xml




hibernate.dialect=org.hibernate.dialect.HSQLDialect
       


















and to add @Transactional over each (concrete) classes that make use of transaction; in our case these are the services' ones. NOTE: at this point hibernate.cfg.xml can be deleted! Datasource definition and links are defined and handled through Spring configuration file, there is no more need of another external xml file. Add '@Transactional' on top of HelloServiceImpl:
@Transactional
public class HelloServiceImpl implements Serializable, HelloService {

private HelloDAO helloDao;

public void setHelloDao(HelloDAO helloDao) {
this.helloDao = helloDao;
}

public List getWords() {

List

phrases = (List) helloDao.getPhrases(); List words = new ArrayList(); for (Iterator

iterator = phrases.iterator(); iterator.hasNext();) { String word = ((Hello) iterator.next()).getPhrase(); words.add(word); } return words; } }

JSPs, as explained in previous posted article, work in this way: index.jsp redirects to hellopage.action that, in turn, redirects to success.jsp. index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


success.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<%@ taglib prefix="s" uri="/struts-tags"%>


Result shown on web page is this:
I hope this article will be usefule to someone, for me

Monday, April 19, 2010

Struts 2 - Spring integration

An introduction and web application example

Recently, There has been a lot of noise about Dependency Injection and Inversion of Control based frameworks, most of this due to this article of Uncle Bob.
I consider article of Martin Fowler about above-mentioned pattern somewhat like a "manifest" of Inversion Control\Dependency Injection, so I invite you to accurately read it.
But now, what about real, pragmatic, occupational impact of this technology on a Java developer?
What I can see is a broad diffusion of Spring framework, that is a great tool in my opinion, but a giant apart universe, too. Spring gives to team of developers the ability to decoupling entire project in separate parts, each one independent from each other and several sub-teams can work singly, without or with very poor knowledge about work of collegues on other parts.
Typically, each team work on a single level of a classic three-tiers architecture:
  • Presentation layer
  • Business Logic layer
  • Physical layer

But this rule is not written anywhere. Spring framework gives great support on integration and decoupling of project shares, but it has a price! 
Gigantic overall configuration work (expecially if you integrate more frameworks\technologies), giant and multiple xml\properties files writing..well, in my humble opinion.. it seems a pachyderm to manage. Furthermore, code injected via xml is often difficult to debug. I am very sceptical that it is the panacea of all ills, the jolly to be used in every circumstance.
However, Spring helps very much in some cases, I never dream for a moment to criticize this wonderful product and the amazing work performed by community of developers.
My questions are: It is really helpful to you? Do you really save time and resources using that? How big your project is to justify that configuration and xml-read working?

For most project I worked on, Spring would involve to many resource and time to be spent and my response to above questions is No for all three  cases, BUT I am a very curious person and I like challenges; further more it is so required on market, that, sooner or later, I will massively use in professional environment. As they say on official documentation preface: "Spring is modular, allowing you to use only those parts that you need". Moreover I am very bewitched from Spring's Transaction Manager, that I think, in general, is a survival module for every web application project.


Anyway, this is not an article on Spring, neither on Dependency Injection. I am going to show how to integrate two useful frameworks: Struts 2 and Spring.
I assume that the reader knows both technologies, one is a MVC Framework (most used for web development), the other is a "lightweight solution" to develop java enterprise applications.
Googling I found several workarounds and some of that they works only with specific version of above frameworks.
I tried out almost all the most published solutions to take this task and I found this one, that I'm going to explain in this article, the more efficient and easy to implement.
I know, a service locator can be used for this purpose instead of dependency injection or, better, we can do all the work within Spring framework, using Web Flow, but I think Struts 2 is a great tool for developing presentation tier of web applications and I prefer to use it over Web Flow.

Let's go into practical side!

Wait wait!! ..marginal note: I switched to MyEclipse IDE since two months, I never loved Eclipse as IDE, too many configuration settings, not intuitive user interaction, very mnemonic use required, everywhere you click-right, a big menu will be open.. But MyEclipse rocks! Explosed deployment and plugins (dependency) management are features useful enough to motivate my emphasis on this tool.

Steps to be followed to configure your project for Spring and Struts2 support are simple in MyEclipse:
    just Right-click on project --> MyEclipse --> then first add Struts Capability, then Spring Capability. 
Remember to select version 2.1 of Struts core libraries and spring plugin (servlet default specification will be 2.5) and for Spring add 3.0 Core libraries and Web libraries specify the path where to put applicationContext.xml file: WEB-INF (but you can always manually move in future).

On other IDEs, I suppose there are other ways to add these supports to main project, the result, however, will be exactly this:



Fig. 1 Libraries included

and at the end of the file, first of tag </webapp> closing, write:

This snippet of code sets a listener to use Spring as Struts action manager.

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class> </listener>

so web.xml file will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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">
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class> </listener> </web-app>

Now, let's create a Struts action; in our example it is used to retrieve some information from a service  on business layer and push it in a jsp.
Again, I am going to show only how to integrate two frameworks, so:

 - Jsp will be very ugly;
 - Project will not be extended to physical layer (no database use and interaction);

Tutorials on these missing features will be submitted in the near future (I am writing several articles on Hibernate and JQuery).

Our application uses a Struts Action to call an interface of a concrete implementation of a service and then, through action, it whows results to a JSP.
Here the UML code:



Struts Action code:
package it.nickg.webapp.web.actions;

import it.nickg.webapp.services.HelloService;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class HelloAction extends ActionSupport {

    private HelloService helloService;
    private List words;

    public List getWords() {
        return words;
    }

    public void setWords(List words) {
        this.words = words;
    }

    public HelloService getHelloService() {
        return helloService;
    }

    public void setHelloService(HelloService helloService) {
        this.helloService = helloService;
    }

    public String execute() throws Exception {

        words = helloService.getWords();
        return SUCCESS;
    }
}


Struts2 apply dependency injection through setters, so every variable that you need to use in jsp, must have a setter (and I add getter too).

HelloService Interface code:
package it.nickg.webapp.services;

import java.util.List;

public interface HelloService {

    public abstract List getWords();

    // mandatory setter method for Spring's dependency injection
    public abstract void setWords(List words);
}

HelloServiceImpl, real service implementation:

package it.nickg.webapp.services.impl;

import it.nickg.webapp.services.HelloService;

import java.io.Serializable;
import java.util.List;

public class HelloServiceImpl implements Serializable, HelloService {

    private List words;

    public List getWords() {
        return words;
    }

    public void setWords(List words) {
        this.words = words;
    }
}

Spring applies injection to setter, too: when you need to return some variable from a method in middle-tier, just declare it as private and define a setter, then in xml spring's configuration file define values to be setted. Spring inject values and presentation tier doesn't need to know real implementation of business object.
Now edit struts.xml file to map the action created:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="default" extends="struts-default">
<action name="hello" class="helloAction">
<result type="success">/result.jsp</result>
</action>
</package>
</struts>

Crucial  note: what allows to estabilish the link between Struts and Spring is here, class parameter of action must be set as id of spring's bean calling that action.

Add this code to applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="helloService" class="it.nickg.webapp.services.impl.HelloServiceImpl">
        <property name="words">
            <list>
                <value>Hello </value>
                <value>World! </value>
                <value>This is </value>
                <value>a Struts - Spring </value>
                <value>integration example</value>
            </list>
        </property>
    </bean>
    
    <bean id="helloAction" class="it.nickg.webapp.web.actions.HelloAction">
        <property name="helloService" ref="helloService"/>
    </bean>
</beans>

Now we write JSPs. Let's give to index.jsp the role to redirect to our action:


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:redirect url="hellopage.action"/>


and write the "success.jsp" in order to display data returned from action:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <base href="<%=basePath%>">

        <title>My JSP 'success.jsp' starting page</title>

        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

    </head>

    <body>
        <h3>This is only a sample</h3>
        <br>
        
        <s:iterator value="words">
            <s:property/>
        </s:iterator>
    </body>
</html>
When you run the application, it goes to index.jsp, redirected to hellopage.action and from here to success.jsp that displays an output like this:
In the next article, I will start from this application and I will extend it to physical layer, adding a database and an ORM implementation.
Stay tuned!

Tuesday, April 13, 2010

Java is fatherless now..

It's been a long time since I wrote last post and I'm planning to publish a new article on interesting things in next days.
Unfortunately a sad announcement (among other bad news) echoes in Java community:
our father, the man who gives us this powerful and amazing "thing" named Java (as weel as providing us possibility to have a job), decides to resign from Oracle.
Here is the link to his brand new blog.
We all looking forward to his next steps.

Wednesday, January 27, 2010

Struts2 and Netbeans, configuring latest versions.

Configuring Netbeans to work with Struts2 framework



In this article I provide a workaround to let configure Netbeans Web Project, supporting Struts2 framework.
Searching on the web, with Google and not only, I found an official 
plugin for Netbeans IDE, in developing status; but, sadly, last update was on 2008.
There is a blog, whose author provides an updated version of official plugin (it is modified for netbeans 6.7 and Struts 2.1.6) and this could be useful enough for my purpose...but maybe for curiosity or obduracy, I have created this workaround for installing and configuring a development environment, always updated to latest versions of both IDE and framework.

Very quick Overview on Struts2 for those who already know Struts
Most revolutionary innovation provided by Struts2 is related, beyond a shadow of a doubt, with most important method in every Action: 
execute() method.
Unlike first version of Struts, in Struts2 this method is implemented without parameters to be passed;
and so anyone should ask: how to get the object which we need to work with?
With Struts, this is possible through Form beans, ActionForm. With Struts2, this becomes possible thanks to a specific pattern, known as 
inversion control or dependency injection.
I don't pretend to dwell on a theoric explanation about this pattern, but for most curious of you, I warmly suggest to read 
this interesting article, written by Martin Fowler.
Every way, this is the pattern which Spring framework is known for.


Struts2 complies to an advanced interpretation of MVC paradigm: pull-MVC.
The purposes of this article are far away from an exhaustive text on differences between Struts and Struts2, you can find a lot of readings about this issue, with a quick Google search.
Anyway, some of this differences between two frameworks are fundamental, in my opinion.

MVC schema













Actions play a difference role, they pass from Controller to Model and View's layers are now able to pull data directly from the actions, there is no more need of an extra object of model layer.
The framework is based on 5 main components:

Model
    - Action;

Controller    
    - Interceptors;
    - DispatcherFilter;

View
    - Result type;
    - Result view (representation of results);

    - Value stack\OGNL (modules that make possible integration between other components).

Who work with Struts knows very weel that one of the main configuration file used by framework is web.xml. References to several modules that builds the framework are defined inside that.
Let's go with practical part.


Creation of a Web Project supporting Struts2, with Netbeans
The first step is to create e new empty WebProject:
File --> New --> Project 


From Categories choose Java Web and, on the left, Web Application. Then Next.
In the next view, give a name to the project, now select an Application Server and in the last page leave unchecked the Struts2 support . Then Finish.

At this point add Struts2 libraries to the project:
right click on Libraries and  Add Jar\Folder.

Now choose which libraries to include in the project, I personally suggest to begin including only necessary ones:

struts2-core.jar
xwork.jar
ognl.jar
freemarker.jar
commons-logging.jar
--------------------
commons-io.jar
commons-fileupload.jar    


imported libraries



It seems that adding all of those it is not a good idea, because they can generate conflicts. Last two libraries listed above became essential since version 2.1 of struts, I'll investigate on that.


Creation of web.xml file.


Next step is writing web.xml file.
In particular, it is all handled through filters definition. It is necessary to add an entry for FilterDispatcher:That is the class that behaves like servlet filter, it initializes the framework and manages requets.
This file can be easily edited using the tab General, in this way:
Open it, select tab Filters --> Add Filters Element

In filter name field type: Struts2


In filter class field, we should enter the FilterDispatcher class, who handles requests filtering. But the API of this class indicates:
"Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one"

Hence, since Struts 2.1.3, in filter class, inside web.xml, you should add:


apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

The reason of this is still a mystery for me, until the official documentation on versions subsequent to 2.1.3 will not be updated.


Inside Filter Mappingapply to URL: /*


Final xml would be something like this:


    
        Struts2
        apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    
    
        Struts2
        /*
    
    
        
            30
        
    
    
        index.jsp
    

Creation of struts.xml file.


Struts.xml file, in version 2 of Struts, replace struts-config.xml. Here it is the template, very basic, for every project.
Go in Source Package directory and create a brand new xml with a simple right click, then type:
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd">

<struts>
    <package name="default" extends="struts-default">
    </package>
</struts>
I experienced several problems when deploy the application and I solved them creating a directory (manually) named classes inside the WEB-INF one (it can be done easily within Netbeans) and putting inside there the struts.xml file.




Now It is all ready to run you first application, It would be very interesting to delve into other configuring issues of Struts2, for example the properties files. But in this context, they can be left empty.
If you want to create your first Struts2 application, I refer you to documentation on the official site.




References:
An italian version of this article is available here:
Wellnet lab