Sunday, February 6, 2011

SNMP4J Introduction

SNMP (Simple Network Management Protocol) is a protocol which is used to manage and monitor the network of elements. Elements can be any of kind such as routers, switches, printers, workstations, modems, hubs and many more. SNMP4J is an open source API implemented in java. It supports different versions of SNMP such v1/v2c and v3.

To see the SNMP4J API and license details click on snmp4j.

The following section will describe how to retrieve data from a managed object.


import java.util.Vector;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;


public class Snmp4jExample {

/**
* @param args
*/
public static void main(String[] args) {
try {
Address targetAddress = GenericAddress.parse("udp:10.31.88.93/161");
TransportMapping transport = new DefaultUdpTransportMapping();
PDU pdu = new PDU();
Snmp snmp = new Snmp(transport);
CommunityTarget target = new CommunityTarget();
target.setVersion(SnmpConstants.version2c);
target.setAddress(targetAddress);

target.setCommunity(new OctetString("public"));
transport.listen();

pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.2.0")));
pdu.setType(PDU.GET);

ResponseEvent response = snmp.get(pdu, target);
PDU pduResponse = response.getResponse();
System.out.println("pdu response:::"+pduResponse);
Vector vbs = pduResponse.getVariableBindings();
System.out.println("Variable Bindings:::"+vbs);
}catch(Exception e) {
e.printStackTrace();
}

}
}

This example uses snmpv2c to sysobjectid from the switch. The following steps describes in detail.

1) Create an address object with the ip address.
2)

Show process id in windows

Many people might have faced issues with the processes and first thing comes to your mind to solve the issue is to know about the process identifier (simply PID). The procedure to find it is different for different Operating systems. In linux ps -ef |grep process_name. But when it comes to windows it is different. To view the PID in windows follow the below steps.

1) Right click on the taskbar -> select Task Manager.
2) Click on View -> Select Columns.
3) Select the PID (Process Identifier) and click OK.
4) You can choose many other options from Select Columns.

The screenshot shows the process id.



Thursday, November 8, 2007

Configuring SSL Certificates on Tomcat or Jboss

There are a few web pages that describe configuring Secure Socket Layer (SSL) for JBoss, but most gloss over some of the details.

Deep inside the guts of JBoss is an instance of another server called Tomcat, and when it comes to using SSL and HTTPS, JBoss delegates all the implementation stuff to that bundled Tomcat installation. As a result, some of the instructions for implementing SSL come directly from Tomcat documentation. For example, I used this document to start figuring out how to enable SSL.

Before starting, there are two things to ascertain:

1. where JBoss is installed on your machine; and
2. that there's a version of the Java Developer's Kit on the JBoss machine.

For the purposes of this write-up, we will describe setting up JBoss to use a temporary, self-signed SSL Certificate. Also, we'll assume that you're installing under Windows.

There are essentially three steps:

1. create the self-signed certificate;
2. move the self-signed certificate to a JBoss directory; and
3. edit the Tomcat configuration file to turn on SSL.

Creating the Self-Signed Certificate

The Java Developer's Kit includes a utility to create certificates. Go to a command line and type the following:

keytool -genkey -alias tomcat -keyalg RSA

This command tells Java to generate a key. Actually, it does two things:

1. it creates a new key; and
2. if necessary, it creates a collection of keys (called a "key store") to put the key in.

There are some prompts that look like this:



Notice that there are two prompts for the password. That's because there's one password for the keystore, and one password for the actual key.
Moving the Keystore

One of the things that the tool isn't very good about is telling you where it created that keystore. By default, the keygen tool puts information in the "Documents and Settings" directory for your userid. In the example, above, we'd find that they keystore has been created as a file called:

C:\Documents and Settings\mcgradyt\.keystore

That location isn't very helpful. Try copying it to the conf directory of your JBoss installation. For example:

C:\Program Files\jboss-4.0.3\server\default\conf

When I do this, I usually change the name to "chap8.keystore" because that's the default name used in the next step.
Update the Configuration File

First up, you should probably shut down the JBoss server as you do this step.

In the JBoss directory, there should be a file called server.xml:

C:\Program Files\jboss-4.0.3\server\default\deploy\jbossweb-tomcat55.sar\server.xml

This file includes information about what web features to turn on when the server starts up. Inside this file, there should be a part that looks like this:



Make the following changes:

1. Uncomment the block
2. Change the port to 443
3. Change the keystore password to the password used, above ("changeit")

The end result should look something like this:


maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
emptySessionPath="true"
scheme="https" secure="true" clientAuth="false"
keystoreFile="${jboss.server.home.dir}/conf/chap8.keystore"
keystorePass="changeit" sslProtocol = "TLS" />


Now start up the server, and if all went according to plan, SSL should now be enabled.
Installing an SSL Certificate

We purchased an SSL Certificate from Verisign. The company offers excellent documentations and instructions on how to install the certificate on their website. Once you purcahse the certificate Verisign we email the you the certificate only after you go through the process of getting all the information they require to verify the web server and wesite.

Below I included a screenshot of the installation process. It is a simply as using one of the java apache tools to install the certificate in the keystore file.


Configuring sslext plugin for Struts framework

The SSL Extension to Struts (SSLEXT) is an open-source plug-in for Struts. This software was created and is maintained by Steve Ditlinger (and others). It is hosted at SourceForge, http://sslext.sourceforge.net. It is the recommended approach for integrating Struts with SSL processing. Its features include:

* The ability to declaratively specify in the Struts configuration file whether or not an action mapping should be secure. This feature allows your application to switch protocols between actions and JSP pages.
* Extensions of the Struts JSP tags that can generate URLs that use the https protocol.

SSLEXT consists of a plug-in class for initialization, a custom extension to the Struts RequestProcessor, and a custom extension of the Struts ActionMapping. In addition, custom JSP tags, which extend the Struts tags, are provided for protocol-specific URL generation. SSLEXT also includes an additional JSP tag that lets you specify whether an entire JSP page is secure. SSLEXT depends on the Java Secure Socket Extension (JSSE), which is included with JDK 1.4 and later. Finally, you need to enable SSL for your application server. For Tomcat, this can be found in the Tomcat SSL How-To documentation.

SSLEXT works by intercepting the request in its SecureRequestProcessor. If the request is directed toward an action that is marked as secure, the SecureRequestProcessor generates a redirect. The redirect changes the protocol to https and the port to a secure port (e.g., 443 or 8443). This sounds simple enough; however, a request in a Struts application usually contains request attributes. These attributes are lost on a redirect. SSLEXT solves this problem by temporarily storing the request attributes in the session.

SSLEXT does not include a lot of documentation but it comes with a sample application that demonstrates its use and features. To try SSLEXT, you can modify Mini HR to use it by changing the login behavior so that the LoginAction occurs over HTTPS. Once logged in, the protocol should be switched back to HTTP. Take the following steps to set up SSLEXT for the Mini HR application:

1. Copy the sslext.jar file into the MiniHR19\WEB-INF\lib folder.
2. Copy the sslext.tld file into the MiniHR19\WEB-INF\tlds folder.
3. Add a taglib declaration in the web.xml for the sslext tag library as follows:


/WEB-INF/tlds/sslext.tld
/WEB-INF/tlds/sslext.tld location>


Now, make the following changes to the struts-config.xml file:

1. Add the type attribute to the action-mappings element to specify the custom secure action mapping class as follows:


2. Add the controllerelement configured to use the SecureRequestProcessor. If you are already using a custom request processor, change it to extend the SecureRequestProcessor.

processorClass="org.apache.struts.action.
SecureRequestProcessor"/>
3. Add the plug-indeclaration to load the SSLEXT code:

className="org.apache.struts.action.SecurePlugIn">





4. Set the secureproperty to true for the login action mapping by adding the following element


5. Finally, you need to configure the index.jsppage to always run on http, not https. Otherwise, after you log in, the protocol will remain on https. Add the following taglib directive and custom tag to the index.jsp page (after the existing taglib directives):

<%@ taglib uri="/WEB-INF/tlds/sslext.tld" prefix="sslext"%>


This tag is only needed for those JSP pages that are not accessed through your actions.

Now all you need to do is rebuild and redeploy the application. When you click the login link, the protocol will switch to https and the port will switch to 8443. After you log in, you should be redirected back to the index.jsp page and the protocol and port should switch back to http and 8080.You should experiment with using the tag to create links to secure actions. You will find that using SSLEXT is much easier than using the user-data-constraint subelement of the web.xml file. It gives you fine-grained control where you need it through the tags. At the same time, it leverages the struts-config.xml file to enable simple declarative configuration for secure request processing.

Wednesday, August 1, 2007

Ant taks for schema and database creation

name="schemaexport">

name="schemaexport" classname="org.hibernate.tool.hbm2ddl.SchemaExportTask" classpathref="master-classpath"/>

properties="hibernate.properties" quiet="yes" text="yes" drop="no" delimiter=";" output="schema-export.sql">

dir="src">

name="**/*.hbm.xml"/>

This script will generate the schema for the ORM files(.hbml and pojo files).

Paramters:

text: This property is to display the text in the output file.

quiet: This is to show the output schema in console.

The following tag is to create database structure in database. Here, there are some hard-coded values. Those needs to be get from property file.

name="addbaseschema" depends="">

message="Adding base schema objects..." />

driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/gangadb" userid="root" password="root" autocommit="yes" rdbms="mysql" onerror="continue" keepformat="yes" delimitertype="row" delimiter="/" output="mylog.log" print="false" showheaders="false">

src="src/schema-export.sql" />

refid="master-classpath" />




Some short notes on Hibernate tools.

Running the tool

The SchemaExport tool writes a DDL script to standard out and/or executes the DDL statements.

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaExport options mapping_files

SchemaExport Command Line Options

Option Description

You may even embed SchemaExport in your application:

Configuration cfg = ....;

new SchemaExport(cfg).create(false, true);

Properties

Database properties may be specified

• as system properties with -D

• in hibernate.properties

• in a named properties file with --properties

The needed properties are:

SchemaExport Connection Properties

Property Name Description

hibernate.connection.driver_class jdbc driver class

hibernate.connection.url jdbc url

hibernate.connection.username database user

hibernate.connection.password user password

hibernate.dialect dialect

Using Ant

You can call SchemaExport from your Ant build script:

Incremental schema updates

The SchemaUpdate tool will update an existing schema with "incremental" changes. Note that SchemaUpdate

depends heavily upon the JDBC metadata API, so it will not work with all JDBC drivers.

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaUpdate options mapping_files

SchemaUpdate Command Line Options

Option Description

--quiet don't output the script to stdout

--text don't export the script to the database

--naming=eg.MyNamingStrategy select a NamingStrategy

--properties=hibernate.properties read database properties from a file

--config=hibernate.cfg.xml specify a .cfg.xml file

You may embed SchemaUpdate in your application:

Configuration cfg = ....;

new SchemaUpdate(cfg).execute(false);

Using Ant for incremental schema updates

You can call SchemaUpdate from the Ant script:

Schema validation

The SchemaValidator tool will validate that the existing database schema "matches" your mapping documents.

Note that SchemaValidator depends heavily upon the JDBC metadata API, so it will not work with all JDBC drivers. This tool is extremely useful for testing.

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaValidator options mapping_files

SchemaValidator Command Line Options

Option Description

--naming=eg.MyNamingStrategy select a NamingStrategy

--properties=hibernate.properties read database properties from a file

--config=hibernate.cfg.xml specify a .cfg.xml file

You may embed SchemaValidator in your application:

Configuration cfg = ....;

new SchemaValidator(cfg).validate();

Using Ant for schema validation

You can call SchemaValidator from the Ant script:


Saturday, July 21, 2007

Calling C functions in java using JNI API

JNI Example:
The ability to write just one set of code in Java and have it run on every system with a Java run-time is one of Java's primary strengths. But this platform independence has one key drawback: What do we do with the vast amount of existing code? The trick is to use the so-called native method interface.

Writing native methods involves importing C code into your Java application. In this tip I'll walk you through the basic recipe for creating native methods and using them in a Java application.

Seven steps to native method nirvana The steps to creating native methods are as follows:

  • Write Java code
  • Compile Java code
  • Create C header (.h file)
  • Create C stubs file
  • Write C code
  • Create shared code library (or DLL)
  • Run application

Our exercise is to write some text to the console from inside the native method. The specifics of this example will be geared toward a Unix-like system, specifically Linux. I'll point out the couple of spots where the details differ for other platforms.

Write Java code

Write your Java code as you normally would. To use native methods in your Java code, you must do two things. First, write a native method declaration for each native method that you want to use. This is just like writing the declaration of a normal Java method interface, but you must specify the native keyword, as follows:

public native void printText ();

The second hoop to jump through is you must explicitly load the native code library. (We will create this later.) We do this by loading the library in a class static block:

static
    {
    System.loadLibrary ("happy");
    }

To put these pieces together for our example, create a file called Happy.java with the following contents:

class Happy
    {
    public native void printText ();
    static
   {
   System.loadLibrary ("happy");   /* Note lowercase of classname! */
   }
    public static void main (String[] args)
   {
   Happy happy = new Happy ();
   happy.printText ();
   }
 }

Compile Java code

Compile the Happy.java file:

% javac Happy.java

Create a C header file

There are various magic incantations that must be made available so that our C code can be used as a native method. The javah functionality of the Java compiler will generate the necessary declarations and such from our Happy class. This will create a Happy.h file for us to include in our C code:

% javah Happy

Create a C stubs file

In a manner reminiscent of the mangling that C++ translators do to the names of C++ methods, the Java compiler has a similar madness. To ease the pain of having to write a lot of tedious code so that our C code can be invoked from the Java run-time system, the Java compiler can generate the necessary trampoline code automatically for us:

% javah -stubs Happy

Write C code

Now, let's write the actual code to print out our greeting. By convention we put this code in a file named after our Java class with the string "Imp" appended to it. This results in HappyImp.c. Place the following into HappyImp.c:

#include <StubPreamble.h>      /* Standard native method stuff. */
#include "Happy.h"         /* Generated earlier. */
#include <stdio.h>         /* Standard C IO stuff. */
void Happy_printText (struct HHappy *this)
    {
    puts ("Happy New Year!!!");
    } 

In interfacing your C code with Java, many other aspects are involved -- such as how to pass and return the myriad types. For more information, see the Java tutorial or the Hermetica Native Methods Paper (see the Resources section for URLs).

Create a shared library

This section is the most system-dependent. It seems like every platform and each compiler/linker combination has a different method of creating and using shared libraries. For folks using any of the various Microsoft Windows platforms, check the documentation for your C compiler for the nitty-gritty details.

For you Linux folks, here's how to create a shared library using GCC. First, compile the C source files that we have already created. You have to tell the compiler where to find the Java native method support files, but the main trick here is that you have to explicitly tell the compiler to produce Position Independent Code:

% gcc -I/usr/local/java/include -I/usr/local/java/include/genunix -fPIC -c Happy.c HappyImp.c

Now, create a shared library out of the resulting object (.o) files with the following magical incantation:

% gcc -shared -Wl,-soname,libhappy.so.1 -o libhappy.so.1.0 Happy.o HappyImp.o

Copy the shared library file to the standard short name:

% cp libhappy.so.1.0 libhappy.so

Finally, you may need to tell your dynamic linker where to find this new shared library file. Using the bash shell:

% export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

Execute the application

Run the Java application as usual:

% java Happy

Saturday, July 14, 2007

Configuring Datasource in Jboss using MySQL and Oracle

MySQL Datasource Configuration in Jboss App Server:

MySQL is an open source database used by many open source projects and small organizations. To use JBoss 4.0 with MySQL, we first need to put the MySQL driver classes into the CLASSPATH. Copy the .jar file mysql-connector-java-3.0.9-stable-bin.jar to the /server/default/lib directory.
To use the MySQL data source, copy /docs/examples/jca/mysql-ds.xml to the /server/default/deploy directory. Modify the mysql-ds.xml configuration file by setting to com.mysql.jdbc.Driver and to jdbc:mysql:///, where is the MySQL host server and is the MySQL database.
Next, we need to set the and elements in the standardjaws.xml or jaws.xml file:

java:/MySqlDS
mySQL

We also need to set the and elements in the standardjbosscmp-jdbc.xml or jbosscmp-jdbc.xml file:

java:/MySqlDS
mySQL

Finally, we modify login-config.xml with MySQL database settings. Add the following element to login-config.xml:

sa
sa

jboss.jca:service=LocalTxCM,name=MySqlDS

By modifying the mysql-ds.xml, standardjaws.xml, standardjbosscmp-jdbc.xml, and login-config.xml files, the JBoss 4.0 server is configured to be used with a MySQL database.

In Client:

Hashtable ht=new Hashtable();
ht.put(InitialContext.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
ht.put(InitialContext.PROVIDER_URL,"jnp://localhost:1099");
ht.put(InitialContext.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
initialContext = new InitialContext(ht);
javax.sql.DataSource ds = (javax.sql.DataSource) initialContext.lookup("java:MySqlDS");
java.sql.Connection conn = ds.getConnection();
// do the necessary database operations on connection.



Troubleshooting:
---------------------

javax.naming.NamingException: MySql not bound.

Then make sure that you have following entry in mySql-ds.xml:

false


Similarly for configuring oracle datasource in jboss:
----------------------------------------------------------------

Oracle Configuration

Oracle is a very popular enterprise database used for its performance and reliability. To configure JBoss 4.0 with Oracle, we first need to put Oracle's driver classes in the CLASSPATH. Copy Oracle's JDBC driver .zip file /jdbc/lib/classes12.zip to the server/default/lib directory.
To use Oracle's transactional (XA) data source, copy /docs/examples/jca/oracle-xa-ds.xml to the /server/default/deploy directory. To configure with the non-XA data source, copy /docs/examples/jca/oracle-ds.xml instead, to /server/default/deploy dir.
Next, we need to modify the oracle-ds.xml configuration file. The and settings for Oracle are as follows:

Oracle OCI Type 2 Driver
Class: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:oci8:@
Oracle OCI Thin Type 4 Driver
Class: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:thin:@::
Oracle OCI XA Type 2 Driver
Class: oracle.jdbc.xa.client.OracleXADataSource
URL: jdbc:oracle:thin:@::
Oracle OCI Type 2 Driver
Class: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:oci8:@

In the Connection URL setting, is the HOST value specified in the /network/ADMIN/tnsnames.ora file, and is the PORT value specified in the tnsnames.ora file, and is the database name.
Next, we modify the standardjaws.xml or jaws.xml configuration file. Set the and elements as follows:


java:/OracleDS
Oracle8


Next, we modify the standardjbosscmp-jdbc.xml or jbosscmp-jdbc.xml configuration file, setting the and elements to use Oracle:



java:/OracleDS
Oracle8



Finally, we need to modify login-config.xml to use Oracle. Add the following element to login-config.xml:




sa
sa


jboss.jca:service=LocalTxCM,name=OracleDS





By modifying the oracle-ds.xml, standardjaws.xml, standardjbosscmp-jdbc.xml, and login-config.xml files, the JBoss 4.0 server is configured to be used with a Oracle database.




Integrating Struts and Spring framework

Integrating Struts and Spring:

Like Struts, Spring can also function as an MVC implementation. Both frameworks have their merits and drawbacks, although most would agree that Struts is still king when it comes to MVC. Many development teams have learned to rely on Struts as the foundation for building quality software under strict deadlines. With so much momentum behind Struts, even development teams that would like to integrate features of the Spring framework don't want to switch to Spring MVC. The good news is that you don't have to. The Spring architecture allows you to connect Struts as your Web framework to Spring-based business and persistence layers. The end result is that you can have your cake and eat it too!
In the recipes that follow, you'll learn three ways to integrate Struts MVC into the Spring framework. I'll expose the cons of each recipe as well as its comparative advantages. Once you've seen all three in action, I'll show you an exciting application of the approach I like best.


Three little recipes
Each of the following integration techniques (or recipes) has its merits, as well as its own particular quirks. I'm partial to only one of them, but knowing them all will deepen your understanding of both Struts and Spring. It will also provide you with a broad range of options for dealing with various scenarios. The recipes are as follows:
1. Use Spring's ActionSupport class to integrate Struts
2. Override the Struts RequestProcessor with Spring's DelegatingRequestProcessor
3. Delegate Struts Action management to the Spring framework

Loading the application context:
No matter which technique you use, you will need to use the Spring ContextLoaderPlugin to load the Spring application context for the Struts ActionServlet. Simply add the plug-in to your struts-config.xml file as you would any other plug-in, as shown here:


As previously mentioned, you'll find the complete source for the three fully functional example applications in the Download section. Each example presents a different approach to combining Struts and Spring for a book-search application. You can follow the basics of the examples here, but download the applications to see all the nitty-gritty details!

Recipe 1. Use Spring's ActionSupport:

Creating a Spring context manually is the most intuitive way to integrate Struts with Spring. To make it even easier, Spring offers a little help. The org.springframework.web.struts.ActionSupport class provides a getWebApplicationContext() method to easily obtain a Spring context. All you need to do is extend your action from Spring's ActionSupport instead of the Struts Action class, as shown in Listing 1:Listing 1. Using ActionSupport to integrate Struts

package ca.nexcel.books.actions;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import org.springframework.context.ApplicationContext;
import org.springframework.web.struts.ActionSupport;
import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;
public class SearchSubmit extends ActionSupport { (1)
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
DynaActionForm searchForm = (DynaActionForm) form;
String isbn = (String) searchForm.get("isbn");

//the old fashion way
//BookService bookService = new BookServiceImpl();

ApplicationContext ctx =
getWebApplicationContext(); (2)
BookService bookService =
(BookService) ctx.getBean("bookService"); (3)

Book book = bookService.read(isbn.trim());
if (null == book) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError
("message.notfound"));
saveErrors(request, errors);
return mapping.findForward("failure") ;
}
request.setAttribute("book", book);
return mapping.findForward("success");
}
}
Let's quickly consider what's happening here. At (1), I create an Action by extending from the Spring ActionSupport class rather than the Struts Action class. At (2), I use the getWebApplicationContext() method to obtain an ApplicationContext. To obtain the business service, I use the context obtained at (2) to look up a Spring bean at (3).
This technique is simple and easy to understand. Unfortunately, it couples the Struts action to the Spring framework. If you ever decide to replace Spring, you would have to rewrite the code. Moreover, because the Struts action isn't under Spring's control, it can't reap the benefits of Spring AOP. This technique may be useful when using multiple independent Spring contexts, but for the most part it's not as desirable a solution as the other two choices.

Recipe 2. Override the RequestProcessor:

Decoupling Spring from the Struts action is a much smarter design choice. One way to do this is to override the Struts RequestProcessor processor with the org.springframework.web.struts.DelegatingRequestProcessor class, as shown in Listing 2:
Listing 2. Integration via Spring's DelegatingRequestProcessor

(1)

Here, I've used the tag to override the default Struts RequestProcessor with the DelegatingRequestProcessor. My next step is to register the action in my Spring config file, as shown in Listing 3:
Listing 3. Registering an action in the Spring config file

(1)

Note that at (1), I've registered a bean using the name attribute to match the struts-config action mapping name. The SearchSubmit action exposes a JavaBean property, allowing Spring to populate the property at run time, as shown in Listing 4:Listing 4. A Struts action with a JavaBean property
package ca.nexcel.books.actions;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;
public class SearchSubmit extends Action {

private BookService bookService;
public BookService getBookService() {
return bookService;
}
public void setBookService(BookService bookService) { (1)
this.bookService = bookService;
}
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
DynaActionForm searchForm = (DynaActionForm) form;
String isbn = (String) searchForm.get("isbn");

Book book = getBookService().read(isbn.trim()); (2)
if (null == book) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
saveErrors(request, errors);
return mapping.findForward("failure") ;
}
request.setAttribute("book", book);
return mapping.findForward("success");
}
}
In Listing 4, you can see how to build the Struts action. At (1), I create a JavaBean property. This property is automatically populated by the DelegatingRequestProcessor. This design protects the Struts action from knowing it's being managed by Spring while giving you all the benefits of Spring's action management framework. Because your Struts actions are oblivious to the existence of Spring, you can swap out Spring for some other inversion of control container without refactoring your Struts code.
While the DelegatingRequestProcessor approach is definitely better than the first one, it does have some problems. If you were using a different RequestProcessor, then you would need to integrate the Spring DelegatingRequestProcessor manually. The added code would become a maintenance hassle and would also reduce your application's flexibility going forward. Moreover, there has been some talk of replacing the Struts RequestProcessor with a chain of command. Such a change would negatively impact the longevity of this solution.

Recipe 3. Delegate action management to Spring:
A much better solution is to delegate Struts action management to the Spring framework. You can do this by registering a proxy in the struts-config action mapping. The proxy is responsible for looking up the Struts action in the Spring context. Because the action is under Spring's control, it populates the action's JavaBean properties and leaves the door open to applying features such as Spring's AOP interceptors.
In Listing 5, the Action class is the same as it was in Listing 4. However, the struts-config is a little different:
Listing 5. The delegation method of Spring integration

Listing 5 is a typical struts-config.xml file, except for one small difference. Instead of declaring the action's class name, it registers the name of Spring's proxy class, as shown at (1). The DelegatingActionProxy class uses the action mapping name to look up the action in the Spring context. This is the context that was declared with ContextLoaderPlugIn.
Registering a Struts action as a Spring bean is very straightforward, as shown in Listing 6. I simply create a bean using the name of the action mapping using the tag's name attribute (in this case, "/searchSubmit"). The action's JavaBean properties are populated like any Spring bean:
Listing 6. Register a Struts action in the Spring context.

The benefits of action delegation:
The action-delegation solution is the best of the three. The Struts action has no knowledge of Spring and could be used in non-Spring applications without changing a single line of code. It's not at the mercy of a change to the RequestProcessor, and it can take advantage of Spring's AOP features.
The benefits of action delegation don't stop there, either. Once you have your Struts action under Spring's control, you can leverage Spring to give them more pizzazz. For example, without Spring, all Struts actions must be threadsafe. If you set the tag's singleton attribute to "false," however, your application will have a newly minted action object on every request. You might not need this feature, but it's nice to know you have it in your back pocket. You can also take advantage of Spring's lifecycle methods. For example, the tag's init-method attribute is used to run a method when the Struts action is instantiated. Similarly, the destroy-method attribute executes a method just before the bean is removed from the container. These methods are a great way to manage expensive objects in much the same way as the Servlet lifecycle does.



sources can be found in the original article:

http://www.ibm.com/developerworks/java/library/j-sr2.html