Monday 5 December 2011

Eclipse Glassfish EE example

Hi, this is a simple ear application that demonstrates how to use eclipse with glassfish to build enterprise applications (J2EE). It combines the standard hello example of J2EE examples from NetBeans with the calculator example of web services example of NetBeans again. There is a simple trick in the web.xml of the war file to run the two examples seperately from the IE command line.


1.1 Create an Enterprise Application (name=ServletStatelessARSEAR)
1.2 Say OK to create an ejbClient (name = ServletStatelessARS-ejbClient)
1.3 Leave the rest as it is, you will add the EJB and war projects later on.
As seen in the picture.



2.1 Create under ejbModule an interface file at the ServletStatelessARS-ejbClient client application (loc/name=enterpriseARS.servlet_stateless_ejbClient/StatelessSessionARS.java)

package enterpriseARS.servlet_stateless_ejbClient;

public interface StatelessSessionARS {

public String sayHelloARS(String name);
public int add2Parms(int parm1, int parm2);

}





2.2 Create an EJB application (name=ServletStatelessARS-ejb) and attach it to the Enterprise application using the related creation option.
2.3 Create under ejbModule (loc/name=enterpriseARS.servlet_stateless_ejb/StatelessSessionARSBean.java)
package enterpriseARS.servlet_stateless_ejb;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jws.WebService;

import enterpriseARS.servlet_stateless_ejbClient.StatelessSessionARS;

@WebService (only for diagnostic purposes, to be used for Glassfish endpoint testing)
@Stateless
public class StatelessSessionARSBean
implements StatelessSessionARS {

public String sayHelloARS(String name) {
return "HelloARS, " + name + "!\n";
}

public int add2Parms(int parm1, int parm2){
return(parm1+parm2);
}

}
3.1 Create a dynamic web application (name=ServletStatelessARS-war) and attach it to the Enterprise application using the related creation option.





3.2 Web/index.jsp should be:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>GlassFish JSP Page</title>
</head>
<body>
<h1>Calculator Service</h1>
<form name="Submit" action="Servlet2ParmsAddARS">
<input type="text" name="value1" value="2" size="3"/>+
<input type="text" name="value2" value="2" size="3"/>=
<input type="submit" value="Get Result" name="getResult" />
</form>
</body>

</html>
3.3 Web.xml should be:
<?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">
<display-name>ServletStatelessARS</display-name>
<distributable/>
<servlet>
<servlet-name>Servlet2StatelessARS</servlet-name>
<servlet-class>enterpriseARS.servlet_stateless_war.Servlet2StatelessARS</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet2StatelessARS</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Servlet2ParmsAddARS</servlet-name>
<servlet-class>enterpriseARS.servlet_stateless_war.Servlet2ParmsAddARS</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet2ParmsAddARS</servlet-name>
<url-pattern>/Servlet2ParmsAddARS</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
index.jsp
servlet
</welcome-file>
</welcome-file-list>
</web-app>

3.4 In the Java Resources/src/enterpriseARS.servlet_stateless_war package,
Create Servlet2ParmsAddARS.java

package enterpriseARS.servlet_stateless_war;
import java.io.*;

import javax.ejb.EJB;

import javax.servlet.*;
import javax.servlet.http.*;

import javax.naming.*;

import enterpriseARS.servlet_stateless_ejbClient.*;

// Though it is perfectly fine to declare the dependency on the bean
// at the type level, it is not required for stateless session bean
// Hence the next two lines are commented and we rely on the
// container to inject the bean.
// @EJB(name="StatelessSession", beanInterface=StatelessSession.class)

public class Servlet2ParmsAddARS
extends HttpServlet {

// Using injection for Stateless session bean is still thread-safe since
// the ejb container will route every request to different
// bean instances. However, for Stateful session beans the
// dependency on the bean must be declared at the type level

@EJB
private StatelessSessionARS sless;

public void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

resp.setContentType("text/html");
PrintWriter out = resp.getWriter();

try {

out.println("<h2>Servlet ClientServlet at " + req.getContextPath () + "</h2>");

int i = Integer.parseInt(req.getParameter("value1"));
int j = Integer.parseInt(req.getParameter("value2"));

int result = sless.add2Parms(i,j);

out.println("<br/>");
out.println("Result:");
out.println("" + i + " + " + j + " = " + result);

} catch (Exception ex) {
ex.printStackTrace();
System.out.println("webclient servlet test failed");
throw new ServletException(ex);
}
}

}
3.5 create Servlet2StatelessARS.java at the same package location.

package enterpriseARS.servlet_stateless_war;

import java.io.*;

import javax.ejb.EJB;

import javax.servlet.*;
import javax.servlet.http.*;

import javax.naming.*;

import enterpriseARS.servlet_stateless_ejbClient.*;
public class Servlet2StatelessARS
extends HttpServlet {
@EJB
private StatelessSessionARS sless;

public void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

resp.setContentType("text/html");
PrintWriter out = resp.getWriter();

try {

out.println("<HTML> <HEAD> <TITLE> Servlet Output </TITLE> </HEAD> <BODY BGCOLOR=white>");
out.println("<CENTER> <FONT size=+1> Servlet2Stateless:: Please enter your name </FONT> </CENTER> <p> ");
out.println("<form method=\"POST\">");
out.println("<TABLE>");
out.println("<tr><td>Name: </td>");
out.println("<td><input type=\"text\" name=\"name\"> </td>");
out.println("</tr><tr><td></td>");
out.println("<td><input type=\"submit\" name=\"sub\"> </td>");
out.println("</tr>");
out.println("</TABLE>");
out.println("</form>");
String val = req.getParameter("name");

if ((val != null) && (val.trim().length() > 0)) {
out
.println("<FONT size=+1 color=red> Greeting from StatelessSessionBean: </FONT> "
+ sless.sayHelloARS(val) + "<br>");
}
out.println("</BODY> </HTML> ");

} catch (Exception ex) {
ex.printStackTrace();
System.out.println("webclient servlet test failed");
throw new ServletException(ex);
}
}

}

4.1 It will give IDE and compile error for the EJB because currently the dynamic web application does not see the EJB application.
4.2 Right click on the dynamic web application and check that Project references indicates ejb and ejbClient applications as referred.
4.3 Go to the Java Build Path and click on the Projects tab. Add the ejb and ejbClient applications.
4.4 The IDE – compile error for the EJB disappears.
5. You may also check yhe ear application for the same items but they are done automatically for it.
6. Make sure you test the application in an orderly manner. Build the EAR application and also build the others if necessary. When you run the war application the calculator works as default. If you run
http://localhost:8080/ServletStatelessARS-war/servlet then the hello message works.








7. If you experience any problems export the ear application to a war file at the
C:\Program Files\glassfish-3.1\glassfish\domains\domain1\autodeploy
Autodeploy directory of Glassfish. Then restart Glassfish, everything will be OK.


It is free of charge to request a copy of the source files. I am sometimes hecticly busy but I promise to respond in a couple of hours.

Cheers.

Ali R+ SARAL








Sunday 4 December 2011

Referring to another project using Eclipse

There are two seperate projects. Main project calls a method in the ReferredProject.


ReferredProject has
referredProjectPackage/ReferenceClass.java
package referredProjectPackage;

public class ReferenceClass {
public void sayHello(){
System.out.println("Hello from the reference class.");
}
}
MainProject has
mainPackage/MainClass.java
package mainPackage;
import referredProjectPackage.*;

public class MainClass {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("MainClass works.");
ReferenceClass rc = new ReferenceClass();
rc.sayHello();
}

}
It gives error:



Right Click on the MainProject in the PackageExplorer. Select properties at the bottom. Properties for the MainProject window opens. Select JAVA build path and then select the Projects tab.



Select ReferredProject and then click OK. The errors disappear and the program works.
But to be on the safe side, do not forget to do also:
Right click on the MainProject, select Project References, select ReferredProject and click OK.




Saturday 3 December 2011

How to use Eclipse with GlassFish server(2)

13- Right Click on the application name and slide to the bottom and select ‘properties’ for our web app TestEclipseGlassFishARS.

14- Select libraries and observe the source of the problem.




15- Select JRE System Library and click the edit button on the right.






16- Click the Add button the Installed JREs window.





17- Select Standard VM on the JRE type window.




18- The JRE Definition window opens. Select JRE Home using the directory button and go to the JDK 1.6 installation directory.




19- Your choice fills in all the necessary fields on the JRE Definition window. Click the finish button.



20- Installed JRE’s window appears again with the newly added JDK 1.6 directory.



21- Select JDK 1.6 and return back to the JRE System Library window which also has the new addition as seen in the picture. Select JDK 1.6 as Alternate JRE and then click Finish.




22- JRE System Library is now changed to JDK 1.6 as required by GlassFish.




23- Try once more to run the test web app. It works. Don’t g’ve up! You will make it.



Cheers.

Ali R+ SARAL

Note: I know that the picture quality may not prove to be good. If you like you may obtain a Word format of this tutorial for free from arsaral(at)yahoo.com. Sometimes I may be hecticly busy but I promise a response with in a couple of hours.






How to use Eclipse with GlassFish server (1)


I am going to explain how to use Eclipse with Glassfish as a server. This tutorial uses a very simple, picture based approach. So trust me and take my advises you will make it to the end for sure.
1- Create a dynamic web project:
Open eclipse, file, new, [web], dynamic web project









2- Create a new server
Go to bottom right frame, select servers, right click in the frame content area, server, new






3- If GlassFish connection has been made for your Eclipse installation previously you will get this picture. But in your case, GlassFish will not appear.



4- Click ‘Download additional web servers’. It will open ‘ install new extension’ window and begin searching the internet. This will take a long time.



5- Be patient and wait till the end when finally it finds GlassFish and Jboss.






6- Select GlassFish and see that the previous window has the GlassFish items now.






7- Select GlassFish 3.1 and a new screen taht asks for the location of Glassfish on your computer opens. It also calls for your choice of jre.


8- Then you are asked for the admin directory and the admin password which happens to be adminadmin









9- Now it is time to try the very simple dynamic web program that we have created.




Do not forget to put index.jsp as a welcome file in the web.xml.
Index.jsp is on the picture.





10. Run the webapp on the new server.





11- Select Glassfish






12- ERROR: Glassfish requires JDK 1.6 and not a JRE.






You can request a better printed World version of this tutorial from arsaral(at)yahoo.com

The pictures are much better and scripts can be easily read in that version.






































Sunday 25 September 2011

Struts2 Hibernate Spring Tutorial

Struts - Hibernate - Spring Application

This is a tutorial that explains how Struts2 , Hibernate and Spring(IoC) is mixed together and used in the same application.

I based my work on the examples given in Vaan Nila Struts2 tutorial. Vaan Nila gives the Struts2Example14 for Struts2 - Spring and Struts2Example17 for Struts2 - Hibernate.

My trick is: I took the Struts2Example17 project and added it the lib/jars of the Struts2Example14. Then I changed the struts.xml from:

/register.jsp

to: (my StrutsHibernateSpring application)

/register.jsp


Similar Struts2Example14 's WEB-INF/applicationContext.xml:





I did WEB-INF/applicationContext.xml in StrutsHibernateSpring:





I also added the Spring listener to the web.xml in StrutsHibernateSpring :

org.springframework.web.context.ContextLoaderListener

which is similar to the Struts2Example14 web.xml.

It worked.

Here is the code:


struts.xml
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">




listUser



/register.jsp





hibernate.config.xml

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">


org.hsqldb.jdbcDriver
jdbc:hsqldb:hsql://localhost
sa

1
org.hibernate.dialect.HSQLDialect
true
create





com.vaannila.dao
UserDAO.java
package com.vaannila.dao;

import java.util.List;
import com.vaannila.domain.User;

public interface UserDAO {

public void saveUser(User user);
public List listUser();
}

UserDAOImpl.java
package com.vaannila.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.googlecode.s2hibernate.struts2.plugin.annotations.SessionTarget;
import com.googlecode.s2hibernate.struts2.plugin.annotations.TransactionTarget;
import com.vaannila.domain.User;

public class UserDAOImpl implements UserDAO {

@SessionTarget
Session session;
@TransactionTarget
Transaction transaction;

@SuppressWarnings("unchecked")
@Override
public List listUser() {
List courses = null;
try {
courses = session.createQuery("from User").list();
} catch (Exception e) {
e.printStackTrace();
}
return courses;
}

@Override
public void saveUser(User user) {
try {
session.save(user);
} catch (Exception e) {
transaction.rollback();
e.printStackTrace();
}
}

}

com.vaannila.domain
User.java
package com.vaannila.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="USER")
public class User {

private Long id;
private String name;
private String password;
private String gender;
private String country;
private String aboutYou;
private Boolean mailingList;

@Id
@GeneratedValue
@Column(name="USER_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

@Column(name="USER_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@Column(name="USER_PASSWORD")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

@Column(name="USER_GENDER")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}

@Column(name="USER_COUNTRY")
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}

@Column(name="USER_ABOUT_YOU")
public String getAboutYou() {
return aboutYou;
}
public void setAboutYou(String aboutYou) {
this.aboutYou = aboutYou;
}

@Column(name="USER_MAILING_LIST")
public Boolean getMailingList() {
return mailingList;
}
public void setMailingList(Boolean mailingList) {
this.mailingList = mailingList;
}

}

WebContent
WEB-INF
lib
application-Context.xml







web.xml


StrutsHibernateSpringARS

struts2

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter



org.springframework.web.context.ContextLoaderListener


struts2
/*



index.jsp



WebContent
hs.bat
set classpath=.\WEB-INF\lib\hsqldb.jar;%classpath%
java org.hsqldb.Server
hs2.bat
java -cp ./WEB-INF/lib/hsqldb.jar org.hsqldb.util.DatabaseManager




I went one step further and I did a DAO dependency injection in my application StrHibSprARS2.
applicationContext.xml in src together with hibernate.cfg.xml and struts.xml









(It would be wiser to change the name of the applicationContext.xml to beans.xml.)
UserAction.java would change to:
...
//private UserDAO userDAO = new UserDAOImpl();

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
private UserDAO userDAO = (UserDAOImpl) factory.getBean("userDAOImplClass");
...
(again the name applicationContext.xml gets mixed with the real one in the WEB-INF. I tried
successfully to clean up the unnecessary entries in these two applicationContext files, namely
I deleted id="userActionClass" item from the src beans.xml and vise versa. No problem.)

Tuesday 13 September 2011

Some notes about VaanNila's Hibernate Tutorial Examples

This note explains how to run the hibernate examples given
in VaanNila's Hibernate Tutorial.
http://www.vaannila.com/hibernate/hibernate-tutorial/hibernate-tutorial.html

ERRORS MESSAGES AND THE SOLUTIONS:


Initial SessionFactory creation failed.java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.vaannila.util.HibernateUtil.(HibernateUtil.java:14)


add commons-logging-1.1.1
------------------------------------
12.Eyl.2011 20:08:36 org.hibernate.cfg.Environment
INFO: Hibernate 3.2.5
12.Eyl.2011 20:08:36 org.hibernate.cfg.Environment
INFO: hibernate.properties not found
12.Eyl.2011 20:08:36 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: Bytecode provider name : cglib

...
INFO: building session factory
Initial SessionFactory creation failed.java.lang.NoClassDefFoundError: net/sf/cglib/proxy/CallbackFilter
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.vaannila.util.HibernateUtil.(HibernateUtil.java:14)

cglib problem
add cglib.jar
-------------------------------
12.Eyl.2011 20:10:55 org.hibernate.impl.SessionFactoryImpl
INFO: building session factory
Initial SessionFactory creation failed.java.lang.NoClassDefFoundError: org/objectweb/asm/Type

cglib needs asm.jar
-------------------------------


INFO: exporting generated schema to database
12.Eyl.2011 20:12:25 org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: schema export complete
Hibernate: insert into COURSES (COURSE_ID, COURSE_NAME) values (null, ?)
Hibernate: call identity()
Hibernate: insert into COURSES (COURSE_ID, COURSE_NAME) values (null, ?)
Hibernate: call identity()
Hibernate: insert into COURSES (COURSE_ID, COURSE_NAME) values (null, ?)
Hibernate: call identity()
Hibernate: select course0_.COURSE_ID as COURSE1_0_, course0_.COURSE_NAME as COURSE2_0_ from COURSES course0_
Physics
Chemistry
Maths
Hibernate: select course0_.COURSE_ID as COURSE1_0_0_, course0_.COURSE_NAME as COURSE2_0_0_ from COURSES course0_ where course0_.COURSE_ID=?
Hibernate: update COURSES set COURSE_NAME=? where COURSE_ID=?
Hibernate: select course0_.COURSE_ID as COURSE1_0_0_, course0_.COURSE_NAME as COURSE2_0_0_ from COURSES course0_ where course0_.COURSE_ID=?
Hibernate: delete from COURSES where COURSE_ID=?
Hibernate: select course0_.COURSE_ID as COURSE1_0_, course0_.COURSE_NAME as COURSE2_0_ from COURSES course0_
Physics
Mathematics

It works...
-----------
Directory of C:\Users\ars\Desktop\VN_Hibernate\HibernateExample1\lib

antlr-2.7.6.jar
asm.jar
cglib-2.2.jar
commons-collections-3.2.1.jar
commons-logging-1.1.1.jar
dom4j-1.6.1.jar
hibernate3.jar
hibernate-annotations
hibernate-commons-annotations
hsqldb.jar
javassist-3.4.GA.jar
jta-1.1.jar
slf4j-api-1.6.2.jar
slf4j-simple-1.6.2.jar

Friday 9 September 2011

Some notes about VaanNila's Spring Hibernate Integration Tutorial

Some notes about Vaanilla's Spring Hibernate Integration Tutorial
http://www.vaannila.com/spring/spring-hibernate-integration-1.html

SpringExample17 indicates the below list as necessary dependecies.

01.antlr-2.7.6
02.antlr-runtime-3.0
03.commons-collections-3.1
04.commons-dbcp
05.commons-logging-1.0.4
06.commons-pool
07.dom4j-1.6.1
08.ejb3-persistence
09.hibernate3
10.hibernate-annotations
11.hibernate-commons-annotations
12.hsqldb
13.javassist-3.4.GA
14.jstl
15.jta-1.1
16.org.springframework.asm-3.0.0.M3
17.org.springframework.beans-3.0.0.M3
18.org.springframework.context-3.0.0.M3
19.org.springframework.context.support-3.0.0.M3
20.org.springframework.core-3.0.0.M3
21.org.springframework.expression-3.0.0.M3
22.org.springframework.jdbc-3.0.0.M3
23.org.springframework.orm-3.0.0.M3
24.org.springframework.transaction-3.0.0.M3
25.org.springframework.web-3.0.0.M3
26.org.springframework.web.servlet-3.0.0.M3
27.slf4j-api-1.5.6
28.slf4j-simple-1.5.6
29.standard

I used the below list of dependecies:
Directory of C:\Users\ars\Desktop\Str_Hib_Spr\SpringExample17\WebContent\WEB-INF\lib

antlr-2.7.6.jar
antlr-runtime-3.0.jar
asm.jar
cglib-2.2.jar
commons-collections.jar
commons-dbcp.jar
commons-logging.jar
commons-pool.jar
dom4j-1.6.1.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
hibernate3.jar
hsqldb.jar
javassist-3.4.GA.jar
javax.persistence.jar
javax.servlet_2.4.0.v200706111738.jar
jstl.jar
jta-1.1.jar
org.springframework.asm-3.1.0.M2.jar
org.springframework.beans-3.1.0.M2.jar
org.springframework.context-3.1.0.M2.jar
org.springframework.context.support-3.1.0.M2.jar
org.springframework.core-3.1.0.M2.jar
org.springframework.expression-3.1.0.M2.jar
org.springframework.jdbc-3.1.0.M2.jar
org.springframework.orm-3.1.0.M2.jar
org.springframework.transaction-3.1.0.M2.jar
org.springframework.web-3.1.0.M2.jar
org.springframework.web.servlet-3.1.0.M2.jar
slf4j-api-1.6.2.jar
slf4j-simple-1.6.2.jar
standard.jar

I had to add asm.jar and cglib-2.2.jar because of the problems listed below.


exception

org.springframework.web.util.NestedServletException: Request processing failed;
nested exception is org.springframework.jdbc.UncategorizedSQLException: Hibernate operation:
Cannot open connection; uncategorized SQLException for SQL [???]; SQL state [null]; error code [0];
Cannot create PoolableConnectionFactory (socket creation error);
nested exception is org.apache.commons.dbcp.SQLNestedException:
Cannot create PoolableConnectionFactory (socket creation error)

root cause

org.springframework.jdbc.UncategorizedSQLException: Hibernate operation:
Cannot open connection; uncategorized SQLException for SQL [???];
SQL state [null]; error code [0];
Cannot create PoolableConnectionFactory (socket creation error);
nested exception is org.apache.commons.dbcp.SQLNestedException:
Cannot create PoolableConnectionFactory (socket creation error)

SOLUTION:
Vaanilla assumes that you know how to run HSQLDB :-)
add hs.bat :
set classpath=.\web-inf\lib\hsqldb.jar;%classpath%
java org.hsqldb.Server

OUTPUT:
C:\Users\ars\Desktop\Str_Hib_Spr\SpringExample17\WebContent>set classpath=.\web-
inf\lib\hsqldb.jar;

C:\Users\ars\Desktop\Str_Hib_Spr\SpringExample17\WebContent>java org.hsqldb.Serv
er
[Server@6ac2a132]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@6ac2a132]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@6ac2a132]: Startup sequence initiated from main() method
[Server@6ac2a132]: Loaded properties from [C:\Users\ars\Desktop\Str_Hib_Spr\Spri
ngExample17\WebContent\server.properties]
[Server@6ac2a132]: Initiating startup sequence...
[Server@6ac2a132]: Server socket opened successfully in 358 ms.
[Server@6ac2a132]: Database [index=0, id=0, db=file:test, alias=] opened sucessf
ully in 156 ms.
[Server@6ac2a132]: Startup sequence completed in 514 ms.
[Server@6ac2a132]: 2011-09-09 20:21:26.494 HSQLDB server 1.8.0 is online
[Server@6ac2a132]: To close normally, connect and execute SHUTDOWN SQL
[Server@6ac2a132]: From command line, use [Ctrl]+[C] to abort abruptly
----------------

exception
...
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mySessionFactory' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]:
Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError:
net/sf/cglib/proxy/CallbackFilter
...
SEVERE: Servlet /SpringExample17 threw load() exception
java.lang.ClassNotFoundException: net.sf.cglib.proxy.CallbackFilter

SOLUTION:
add cglib.jar
--------------------

exception

root cause

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'mySessionFactory' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]:
Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError:
Could not initialize class net.sf.cglib.proxy.Enhancer

SOLUTION:
cglib depends on asm.jar:

add asm.jar
---------------------------


If there are any problems related to antlr add:
antlr-2.7.5H3

If there are still any more problems:
arsaral [at] yahoo [dot] com

Cheers.

Ali R+


Thursday 31 March 2011

Struts2 JQuery AjaxFORMS-4

Here comes some button set examples. It is so simple that it can not be explained. The AJAX-JSON call has to be pondered a bit.

The AJAX submit activates the jsonsample action. the data structures that are defined in the jsonsample and updated in the execute method can be accessed at AjaxForms10.jsp's
...
<sj:checkboxlist
...
list="languageList"
...
So, when the JsonSample.java works the list of the checkbox is set.

struts.xml has the below entry for jsonsample:
...
<action name="jsonsample" class="ARS.JsonSample" method="execute">
<result type="json"></result>
</action>
...

The full code is below:

AjaxForms10.jsp
---------------
<%--
Buttonset / Checkboxes

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
Buttonset that was populated from a List with String values.
<s:form id="form" action="echo" theme="xhtml">
<sj:checkboxlist
id="checkboxbuttonset"
tooltip="Choose your Friends"
label="Friends"
list="{'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}"
name="echo"/>
<sj:submit
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
</s:form>
<br/>
Buttonset that was populated from AJAX JSON Result.
<s:form id="form2" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample"/>
<sj:checkboxlist
href="%{remoteurl}"
id="remoteCheckboxlist"
name="echo"
list="languageList"
label="Language"
/>
<sj:submit
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
</s:form>

<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/></body>
</html>

JsonSample.java
---------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package ARS;

import com.opensymphony.xwork2.Action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

public class JsonSample extends ActionSupport{

private static final long serialVersionUID = -2223948287805083119L;
private List<String> languageList;
private List<ListValue> languageObjList;
private Map<String, String> languageMap;

// @Actions({
// @Action(
// value="/jsonsample",
// results={
// @Result(name="success",type="json")
// })
// })
public String execute() {

languageList = new ArrayList<String>();
languageObjList = new ArrayList<ListValue>();
languageMap = new HashMap<String, String>();

languageList.add("Java");
languageList.add("PHP");
languageList.add("C++");

languageMap.put("J", "Java");
languageMap.put("P", "PHP");
languageMap.put("C", "C++");

languageObjList.add(new ListValue("J", "Java"));
languageObjList.add(new ListValue("P", "PHP"));
languageObjList.add(new ListValue("C", "C++"));

return SUCCESS;
}

public String getJSON(){
return execute();
}

public List<String> getLanguageList()
{
return languageList;
}

public Map<String, String> getLanguageMap()
{
return languageMap;
}

public List<ListValue> getLanguageObjList()
{
return languageObjList;
}

public class ListValue {
private String myKey;
private String myValue;

public ListValue(String myKey, String myValue) {
super();
this.myKey = myKey;
this.myValue = myValue;
}

public String getMyKey()
{
return myKey;
}

public void setMyKey(String myKey)
{
this.myKey = myKey;
}

public String getMyValue()
{
return myValue;
}

public void setMyValue(String myValue)
{
this.myValue = myValue;
}
}
}

Almost the same...

AjaxForms11.jsp
---------------
<%--
Buttonset / Radio Buttons

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<strong>Result Div :</strong>
<div id="formResult" class="result ui-widget-content ui-corner-all">Submit form bellow.</div>

<strong>Buttonset that was populated from a List with String values.</strong>
<s:form id="form" action="echo" theme="simple">
<label for="echo">Choose your Friend: </label>
<sj:radio
id="radiobuttonset"
list="{'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}"
name="echo"
onChangeTopics="submitForm1"
/>
<br/>
<sj:submit
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
listenTopics="submitForm1"
cssStyle="display:none;"
/>
</s:form>
<br/>
<strong>Buttonset that was populated from AJAX JSON Result with onChangeTopic.</strong>
<s:form id="form2" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample"/>
<sj:radio
href="%{remoteurl}"
id="remoteRadiobuttons"
name="echo"
list="languageMap"
label="Language"
onChangeTopics="submitForm2"
/>
<sj:submit
id="form2button"
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
listenTopics="submitForm2"
cssStyle="display:none;"
/>
</s:form>

<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</html>

AJAX select examples.

AjaxForms12.jsp
---------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<s:form id="formSelectOne" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form populated by a String List</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="jsonsample"/>
<sj:select
href="%{remoteurl}"
id="echo"
name="echo"
list="languageList"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-button">
<sj:submit
targets="result1"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div 1 :</strong>
<div id="result1" class="result ui-widget-content ui-corner-all">Submit form above.</div>

<s:form id="formSelectTwo" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form populated by a Map</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="jsonsample"/>
<sj:select
href="%{remoteurl}"
id="echo2"
name="echo"
list="languageMap"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-button">
<sj:submit
targets="result2"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..." style="display:none"
/>
</div>
</fieldset>
</s:form>

<strong>Result Div 2 :</strong>
<div id="result2" class="result ui-widget-content ui-corner-all">Submit form above.</div>

<s:form id="formSelectThree" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form populated by a List with Objects</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="jsonsample"/>
<sj:select
href="%{remoteurl}"
id="echo3"
name="echo"
list="languageObjList"
listKey="myKey"
listValue="myValue"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-button">
<sj:submit
targets="result3"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div 3 :</strong>
<div id="result3" class="result ui-widget-content ui-corner-all">Submit form above.</div>
</body>
</html>

This example uses jsonsample2. There is a slight difference with the previous one here. The difference comes because of the levels. The second select has to be set according to the first selection. This is reflected in the JsonSample2.java code.

AjaxForms13.jsp
---------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
Reload example with two select boxes.
<s:form id="formSelectReload" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="language">Language: </label>
<s:url id="remoteurl" action="jsonsample2"/>
<sj:select
href="%{remoteurl}"
id="language"
onChangeTopics="reloadsecondlist"
name="language"
list="languageObjList"
listKey="myKey"
listValue="myValue"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-text">
<label for="echo">Framework: </label>
<s:url id="remoteurl" action="jsonsample2"/>
<sj:select
href="%{remoteurl}"
id="selectWithReloadTopic"
formIds="formSelectReload"
reloadTopics="reloadsecondlist"
name="echo"
list="reloadList"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Framework"
/>
</div>
<div class="type-button">
<sj:submit
id="submitFormSelectReload"
targets="result"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"
/>
</div>
</fieldset>
</s:form>
<br/>
Reload example with one select box and an buttonset.
<s:form id="formSelectCheckBox" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample2"/>
<sj:select
href="%{remoteurl}"
id="languageSelect"
onChangeTopics="reloadcheckboxes"
name="language"
list="languageObjList"
listKey="myKey"
listValue="myValue"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
label="Language"
required="true"
/>
<s:url id="remoteurl" action="jsonsample2"/>
<sj:checkboxlist
href="%{remoteurl}"
id="frameworkCheckboxes"
formIds="formSelectCheckBox"
reloadTopics="reloadcheckboxes"
name="echo"
list="reloadList"
label="Framework"
required="true"
onChangeTopics="submitCheckboxForm"
/>
<sj:submit
id="submitFormSelectCheckBox"
listenTopics="submitCheckboxForm"
targets="result"
value="AJAX Submit"
indicator="indicator2"
cssStyle="display : none;"
/>
</s:form>
<img id="indicator2"
src="images/indicator.gif"
alt="Loading..."
style="display:none"
/>

<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">Submit a form.</div>
</body>
</html>

JsonSample2.java
----------------
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package ARS;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;


public class JsonSample2 extends ActionSupport {

private static final long serialVersionUID = -2223948287805083119L;
private static final Log log = LogFactory.getLog(JsonSample2.class);
private List<String> languageList;
private List<ListValue> languageObjList;
private Map<String, String> languageMap;
private List<String> reloadList;
private String language;

public String execute()
{

log.info("build json lists language : " + language);

languageList = new ArrayList<String>();
languageObjList = new ArrayList<ListValue>();
languageMap = new HashMap<String, String>();

languageList.add("Java");
languageList.add("PHP");
languageList.add("C#");

languageMap.put("J", "Java");
languageMap.put("P", "PHP");
languageMap.put("C", "C#");

languageObjList.add(new ListValue("J", "Java"));
languageObjList.add(new ListValue("P", "PHP"));
languageObjList.add(new ListValue("C", "C#"));

reloadList = new ArrayList<String>();
if (language != null && language.equalsIgnoreCase("J"))
{
reloadList.add("Struts2");
reloadList.add("MyFaces");
reloadList.add("Tapestry");
}
else if (language != null && language.equalsIgnoreCase("P"))
{
reloadList.add("CakePHP");
reloadList.add("Symfony");
reloadList.add("Zend");
}
else if (language != null && language.equalsIgnoreCase("C"))
{
reloadList.add("NStruts");
reloadList.add("ProMesh.NET");
reloadList.add("Websharp");
}

return SUCCESS;
}

public String getJSON()
{
return execute();
}

public List<String> getLanguageList()
{
return languageList;
}

public Map<String, String> getLanguageMap()
{
return languageMap;
}

public List<ListValue> getLanguageObjList()
{
return languageObjList;
}

public List<String> getReloadList()
{
return reloadList;
}

public void setLanguage(String language)
{
this.language = language;
}
}

ListValue.java
--------------
/**
*
*/
package ARS;

public class ListValue {
private String myKey;
private String myValue;

public ListValue(String myKey, String myValue) {
super();
this.myKey = myKey;
this.myValue = myValue;
}

public String getMyKey()
{
return myKey;
}

public void setMyKey(String myKey)
{
this.myKey = myKey;
}

public String getMyValue()
{
return myValue;
}

public void setMyValue(String myValue)
{
this.myValue = myValue;
}
}

Struts2 JQuery AjaxFORMS-3

There is a text area in this example. You first write something into the text area and then you push the submit button. The AJAX call copies this text into the result area.

1. The text area takes its default value from the
...
<s:url id="remoteurl" action="ajax1"/>
...

in the struts.xml:
...
<action name="ajax1">
<result>/Ajax1.jsp</result>
</action>
...

Ajax1.jsp:
----------
testARS
(it is composed of only a single word text)

The submit button targets:
...
<sj:submit
targets="result"
...
the result area is at the bottom:
...
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
...

The submit button trigs the action echo:
...
<s:form id="formTextarea" action="echo" theme="simple" cssClass="yform">
...

in the struts.xml:
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
The code for the action echo lies in the echo.java, listed below under the
AjaxForms7.jsp's full code:

AjaxForms7.jsp
--------------
<%--
AJAX Textarea


--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>

<s:form id="formTextarea" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="ajax1"/>
<sj:textarea
href="%{remoteurl}"
id="echo"
name="echo"
rows="10"
cols="80"
effect="highlight"
effectDuration="1500"
loadingText="Loading content of textarea ..."
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
effect="slide"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"/>
</div>
</fieldset>
</s:form>
<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
</body>
</html>

Echo.java
---------
package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;

public class Echo extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Echo.class);

private String echo;
private boolean escape = true;

public String execute() throws Exception
{

log.info("Echo : " + echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

The result of the ecgo action is directed to echo.jsp:

echo.jsp
--------
<%@ taglib prefix="s" uri="/struts-tags"%>
<p>Echo : <s:property value="echo" escape="%{escape}"/></p>

echo.jsp puts "Echo :" and then the value of the echo request variable
(echo field on the JSP). The output of the echo.jsp is targeted to the result field on the AjaxForms7.jsp

AjaxForms8.jsp has not much new, only the text area is resizable.

AjaxForms8.jsp
--------------
<%--
AJAX Text Area / Resizable
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<s:form id="formTextareaResize" action="simpleecho" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<sj:textarea
resizable="true"
resizableGhost="true"
resizableHelper="ui-state-highlight"
id="echo"
name="echo"
rows="4"
cols="80"
onChangeTopics="submitThisForm"
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
value="AJAX Submit"
indicator="indicator"
button="true"
listenTopics="submitThisForm"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..." style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
</body>
</html>

AjaxForms8.jsp has not much new, only this time it is a text field that is resizable.

AjaxForms9.jsp
--------------
<%--
AJAX Textfield / Resizable

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<s:form id="formTextfieldResize" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="urlsimpleecho" action="simpleecho">
<s:param name="echo">remote content for textfield!</s:param>
</s:url>
<sj:textfield
href="%{urlsimpleecho}"
resizable="true"
resizableGhost="true"
resizableHelper="ui-state-highlight"
resizableMaxHeight="30"
effect="blind"
effectDuration="1500"
effectOptions="{
mode: 'show'
}"
id="echo"
name="echo"
loadingText="Loading content of textfield ..."
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
effect="highlight"
effectDuration="1500"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
</body>
</html>

Struts2 JQuery AjaxFORMS-2

AjaxForms5.jsp is a form example with validation. This example does not work in the struts2-jquery-showcase-2.5.0 version. There is a fix note from Herr Geppert on the internet about this. Some javascript has been changed at struts2-jquery-showcase-2.5.3 version. You have to add the utils.js and validation.js references also as seen below.

There is a difficulty about struts2-jquery-showcase-2.5.3. It does not run when compiled. The showcase related with the grid works though. So I copied the lib from the grid showcase of the same version. It worked.

The form activates the login action at the AJAX submit event. The AJAX submit event targets 'result' div with pulsate effect. There are two text fields, loginuser and loginpassword. These are handled at Login.java

Error processing can be done both in the Login.java or with xml validation.

AjaxForms5.jsp
--------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script type="text/javascript" src="${pageContext.request.contextPath}/struts/utils.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/struts/xhtml/validation.js"></script>
</head>
<body>
<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">Submit form bellow.</div>

<s:form id="formValidate" action="login" theme="xhtml">
<s:textfield
id="loginuser"
name="loginuser"
label="User"
required="true"
/>
<s:textfield
id="loginpassword"
name="loginpassword"
label="Password (test)"
required="true"
/>
<sj:submit
targets="result"
button="true"
validate="true"
effect="pulsate"
value="Submit"
indicator="indicator"
/>
<input type="hidden" id="struts.enableJSONValidation" name="struts.enableJSONValidation" value="true" />
</s:form>
</body>
</html>

Login.java
----------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.opensymphony.xwork2.ActionSupport;

public class Login extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Login.class);

private String loginuser;
private String loginpassword;
private String echo;

public String execute() throws Exception
{
echo = "Welcome " + loginuser;
log.info(echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public String getLoginuser()
{
return loginuser;
}

public void setLoginuser(String loginuser)
{
this.loginuser = loginuser;
}

public String getLoginpassword()
{
return loginpassword;
}

public void setLoginpassword(String loginpassword)
{
this.loginpassword = loginpassword;
}
// public void validate(){
//
// if ( loginuser.length() == 0 ){
// addFieldError( "loginuser", "loginuser is required." );
// }
//
// if ( loginpassword.length() == 0 ){
// addFieldError( "loginpassword", "loginpassword is required." );
// }
// }
}


Login-validation.xml
--------------------
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<validator type="requiredstring">
<param name="fieldname">loginuser</param>
<message>loginuser is required.</message>
</validator>
<validator type="requiredstring">
<param name="fieldname">loginpassword</param>
<message>loginpassword is required.</message>
</validator>
</validators>

AjaxForms6.jsp is a custom Validation example. It still uses some js substructure though. The example works without problem.

AjaxForms6.jsp
--------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script type="text/javascript">
$(document).ready( function() {
$.subscribe('removeErrors', function(event,data) {
$('.errorLabel').html('').removeClass('errorLabel');
$('#formerrors').html('');
});
});

function customeValidation(form, errors) {

//List for errors
var list = $('#formerrors');

//Handle non field errors
if (errors.errors) {
$.each(errors.errors, function(index, value) {
list.append(''+value+'\n');
});
}

//Handle field errors
if (errors.fieldErrors) {
$.each(errors.fieldErrors, function(index, value) {
var elem = $('#'+index+'Error');
if(elem)
{
elem.html(value[0]);
elem.addClass('errorLabel');
}
});
}
}
</script>
</head>
<body>
<div id="result" class="result ui-widget-content ui-corner-all">Submit form bellow.</div>

<ul id="formerrors" class="errorMessage"></ul>
<s:form id="formValidateCustom" action="login" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form with Validation</legend>
<div class="type-text">
<label for="echo">User: <span id="loginuserError"></span></label>
<s:textfield
id="loginuser"
name="loginuser"
/>
</div>
<div class="type-text">
<label for="echo">Password: <span id="loginpasswordError"></span></label>
<s:textfield
id="loginpassword"
name="loginpassword"
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
button="true"
validate="true"
validateFunction="customeValidation"
onBeforeTopics="removeErrors"
onSuccessTopics="removeErrors"
value="Submit"
indicator="indicator"
/>
</div>
</fieldset>
</s:form>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</body>
</html>

Struts2 JQuery AjaxFORMS-1

I have taken these examples from Herr GEPPERT's showcase for Struts2-JQuery applications. My intention was to try whether they can work individually for specific purposes. The problem is you can not run struts2-jquery-showcase-2.5.3 as it is provided. There are missing files in the lib folder. But the same site provides a grid showcase which works. So, I copied the whole lib from there on to the original struts2-jquery-showcase-2.5.3 lib. It works now.

After fixing the lib problem, I returned back to the original problem I had. The examples for validation did not work healthily on struts2-jquery-showcase-2.5.0 which I had chosen to be 'safe'. So, I tried the new lib with my old problem, it worked. (I had seen Herr Geppert's note on a fix about this matter). There is also another small fix I had to do, which I will explain when I come to that matter.








web.xml
-------

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Basic_Struts2_Ant</display-name>
<welcome-file-list>
<welcome-file>/test.action</welcome-file>
</welcome-file-list>


<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>

</web-app>

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

<struts>
<constant name="struts.devMode" value="true" />

<package name="basicstruts2" extends="struts-default, json-default">
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
<action name="simpleecho" class="ARS.SimpleEcho" method="execute">
<result name="success">/simpleecho.jsp</result>
</action>
<action name="ajax1">
<result>/Ajax1.jsp</result>
</action>
<action name="jsonsample" class="ARS.JsonSample" method="execute">
<result type="json"></result>
</action>
<action name="jsonsample2" class="ARS.JsonSample2" method="execute">
<result type="json"></result>
</action>
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"><param name="root">languages</param></result>
</action>
<action name="login" class="ARS.Login" method="execute">
<interceptor-ref name="jsonValidationWorkflowStack"/>
<result name = "success">/simpleecho.jsp</result>
</action>
</package>
</struts>

AjaxForms0.jsp uses an AJAX call that targets the div formResult.
There is a field named echo of which value is copied by the
action echo to the result field.
AjaxForms0.jsp
--------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
<s:form id="form" action="echo" theme="xhtml">
Echo: <s:textfield id="echo" name="echo" value="Hello World!!!"/><br/>
</s:form>

<sj:a
id="ajaxformlink"
formIds="form"
targets="formResult"
indicator="indicator"
button="true"
buttonIcon="ui-icon-gear"
>
Submit form here
</sj:a>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</body>
</html>

The echo action trigs the echo.java of which result is fed to the result file echo.jsp. Echo.jsp is then targeted to the result field on the jsp.


Echo.java
---------
package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;

public class Echo extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Echo.class);

private String echo;
private boolean escape = true;

public String execute() throws Exception
{

log.info("Echo : " + echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

Echo.jsp
--------
<%@ taglib prefix="s" uri="/struts-tags"%>
<p>Echo : <s:property value="echo" escape="%{escape}"/></p>


This is a simple repetition in Herr Geppert's examples. simpleecho is not simpler than echo I guess.

AjaxForms1.jsp
--------------
<%--
AJAX Forms

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
<s:form id="form" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/>
</div>
<div class="type-button">
<sj:submit
id="formSubmit1"
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<s:url id="simpleecho" value="/simpleecho.action"/>
<sj:submit
id="formSubmit2"
href="%{simpleecho}"
targets="formResult"
value="AJAX Submit 2"
indicator="indicator"
button="true"
/>
</div>
</fieldset>
</s:form>
</body>
</html>

SimpleEcho.java
---------------
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package ARS;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

public class SimpleEcho extends ActionSupport {

private static final long serialVersionUID = 6999864671102333041L;
private String echo;
private boolean escape = true;

public String execute() throws Exception
{
return SUCCESS;
}

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

Addition of effects etc cosmetic changes.

AjaxForms2.jsp
--------------
<%--
AJAX Forms with Effects

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="result"></div>
<s:form id="formEffect" action="echo" theme="xhtml">
<s:textfield id="echo" name="echo" label="Echo" value="Hello World!!!"/><br/>
<sj:submit
targets="result"
effect="slide"
effectMode="blind"
onEffectCompleteTopics="hideTarget"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
</s:form>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/> </body>

</html>

AjaxForms3.jsp
--------------
<%--
AJAX Forms with Outside Button

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="result">formResult</div>
<s:form id="formOutside" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form with Button outside</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/><br/>
</div>
</fieldset>
</s:form>

<sj:submit
formIds="formOutside"
targets="result"
effect="pulsate"
value="Submit outside the Form"
indicator="indicator"
button="true"
/>
</body>
</html>

The events are interesting. It is pretty straight forward, you create the JSP and it works.

AjaxForms4.jsp
--------------
<%--
AJAX Forms with Events

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script type="text/javascript" charset="utf-8">
$.subscribe('beforeForm', function(event,data) {
var fData = event.originalEvent.formData;
alert('About to submit: \n\n' + fData[0].value + ' to target '+event.originalEvent.options.target+' with timeout '+event.originalEvent.options.timeout );
var form = event.originalEvent.form[0];
if (form.echo.value.length < 2) {
alert('Please enter a value with min 2 characters');
event.originalEvent.options.submit = false;
}
});
$.subscribe('completeForm', function(event,data) {
alert('status: ' + event.originalEvent.status + '\n\nresponseText: \n' + event.originalEvent.request.responseText +
'\n\nThe output div should have already been updated with the responseText.');
});
$.subscribe('errorStateForm', function(event,data) {
alert('status: ' + event.originalEvent.status + '\n\nrequest status: ' +event.originalEvent.request.status);
});
</script>
</head>
<body>
<div id="result">formResult</div>
<s:form id="formevent" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/>
</div>
<div class="type-button">
<sj:submit
targets="result"
value="AJAX Submit"
timeout="2500"
indicator="indicator"
onBeforeTopics="beforeForm"
onCompleteTopics="completeForm"
onErrorTopics="errorState"
button="true"
/>
</div>
</fieldset>
</s:form>

<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>

<s:form id="formeventerror" action="file-does-not-exist.html" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form with Error Result</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/>
</div>
<div class="type-button">
<sj:submit
targets="result"
value="AJAX Submit with Error"
timeout="2500"
indicator="indicator"
onBeforeTopics="beforeForm"
onCompleteTopics="completeForm"
onErrorTopics="errorState"
button="true"
/>
</div>
</fieldset>
</s:form>
</body>
</html>