Why i am writing this blog?
I faced lot of problems while creating my first application using Struts 2 on Google App Engine . So i decided to write a blog detailing how developers can create their application on Struts2 by avoiding the problems that i faced while developing my application.
Note
If you want to do FileUpload using struts 2 on google app engine please refer to this post.
Prerequisites for starting Struts2 Application on Google App Engine
Before you start building your sample application on google app engine using struts 2 you will need the following:-
- Google App Engine runs on java 5 and above so if necessary, download and install the Java SE Development Kit (JDK) for your platform and for mac users download and install the latest version.
- In this example we will be using Eclipse as our ide. So if necessary, download eclipse and google app engine plugin for eclipse.You will also need to download the google java app engine SDK. For more information you can refer to installing the java SDK for google app engine.
- Download the latest release of Struts2 framework.If you want to learn struts 2 a very good reference is struts 2 in action book.Please buy Struts 2 in Action.
Step by Step procedure to create Struts2 application on Google App Engine.
Step 1: Create a new project by clicking the New Web Application Project button in the toolbar.
Step 2 : Give the project name say login as we are going to create a simple login application. Enter package name as com.login and uncheck “Use Google Web Toolkit,” and ensure “Use Google App Engine” is checked and click the finish button.
Step3 : When you click the finish button you will get a sample HelloWorld application, which you can run going in the Run menu, select Run As > Web Application.By default application will run at port 8080, you can view the sample application at http://locahost:8080. For more information on the sample google web application created by the plugin you can refer to Google java app engine documentation .Please keep in mind that intent of this document is not to provide developers the overview of Google App engine for Java.
Step4 : By now you are ready with the google app engine infrastructure and we can move to the next step of creating a login application in Struts 2.
- for creating a struts 2 application you will need to first add the required dependencies to the login project. The required struts 2 jars are below mentioned and you can find these jars in struts2 package you downloaded inside the lib folder :-
- commons-fileupload-1.2.1.jar
- commons-io-1.3.2.jar
- commons-logging-1.1.jar
- freemarker-2.3.13.jar
- ognl-2.6.11.jar
- struts2-core-2.1.6.jar
- xwork-2.1.2.jar
- Add these dependencies in your eclipse java build path.
- Add these dependencies in the war/WEB-INF/lib folder so that these jars gets deployed along with your application.
- As you can see in the above image there are some warnings in the problems view like “commons-fileupload-1.2.1.jar’ will not be available on the server’s classpath” .To remove these warnings you need to right click on the project and select properties and then go to Google > web application and click the add button and add all the jars and then press ok.
- First step in creating a struts 2 application is configuring the web.xml (deployment descriptor) which is located in WEB-INF folder.You can remove the servlet declaration from web.xml as we will not be needing this.We need to add the FilterDispatcher declaration in web.xml because in struts2 every request goes pass through FilterDispatcher which will invoke the appropriate action corresponding to the URL mapping.So our web.xml will look like :-
01 |
xml version = "1.0" encoding = "utf-8" ?> |
02 |
< web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" |
03 |
xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" |
04 |
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee |
06 |
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" |
10 |
< filter-name >struts2 filter-name > |
11 |
< filter-class >org.apache.struts2.dispatcher.FilterDispatcher filter-class > |
14 |
< filter-name >struts2 filter-name > |
15 |
< url-pattern >/* url-pattern > |
18 |
< welcome-file >index.html welcome-file > |
- To start we will be creating a jsp login page using struts 2 tag library and we will call login page from index.html.To call the login page there are two ways first, we can directly call the login.jsp page from link second, we can calling it through struts. We will be taking the second step as this will show you how to configure actions when you dont need to invoke any action.Lets first see how our login page and index.html will look like :-
index.html
04 |
< meta http-equiv = "content-type" content = "text/html; charset=UTF-8" > |
05 |
< title >Struts2 on Google App Engine title > |
09 |
< h1 >Struts2 on Google App Engine! h1 > |
12 |
< td colspan = "2" style = "font-weight: bold;" >Available Application: td > |
15 |
< td >< a href = "/member/login" />Login td > |
login.jsp
01 |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" |
02 |
pageEncoding="ISO-8859-1"%> |
03 |
<%@ taglib prefix="s" uri="/struts-tags" %> |
04 |
http://www.w3.org/TR/html4/loose.dtd"> |
07 |
< meta http-equiv = "Content-Type" content = "text/html; charset=ISO-8859-1" > |
08 |
< title >Please login title > |
12 |
< s:form action = "home" method = "post" > |
13 |
< s:textfield name = "username" label = "UserName" > s:textfield > |
14 |
< s:textfield name = "password" label = "Password" > s:textfield > |
15 |
< s:submit name = "login" value = "login" > s:submit > |
- After creating the login.jsp we need to configure this as action in the struts.xml file which you be should put inside source folder parallel to log4j.properties file.We can configure action as mentioned below:-
01 |
xml version = "1.0" encoding = "UTF-8" ?> |
03 |
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" |
04 |
"http://struts.apache.org/dtds/struts-2.0.dtd"> |
06 |
< include file = "struts-default.xml" > include > |
07 |
< package name = "member" namespace = "/member" extends = "struts-default" > |
09 |
< result >/login.jsp result > |
- Now try running this application by right click on project run as > web application and click http://localhost:8080. You will see index.html and when you click on login you will get this exception :-
SEVERE: Unable to set parameter [location] in result of type [org.apache.struts2.dispatcher.ServletDispatcherResult]
Caught OgnlException while setting property ‘location’ on type ‘org.apache.struts2.dispatcher.ServletDispatcherResult’. – Class: ognl.OgnlRuntime
File: OgnlRuntime.java
Method: invokeMethod
Line: 508 – ognl/OgnlRuntime.java:508:-1
at com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:392)
Caused by: java.lang.IllegalAccessException: Method [public void org.apache.struts2.dispatcher.StrutsResultSupport.setLocation(java.lang.String)] cannot be accessed.
at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:508)
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:812)
at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:964)
at ognl.ObjectPropertyAccessor.setPossibleProperty(ObjectPropertyAccessor.java:75)
at ognl.ObjectPropertyAccessor.setProperty(ObjectPropertyAccessor.java:131)
at com.opensymphony.xwork2.ognl.accessor.ObjectAccessor.setProperty(ObjectAccessor.java:28)
at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:1656)
at ognl.ASTProperty.setValueBody(ASTProperty.java:101)
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:177)
at ognl.SimpleNode.setValue(SimpleNode.java:246)
at ognl.Ognl.setValue(Ognl.java:476)
at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:192)
at com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:385)
… 73 more
- In order to resolve this problem we need to create an ServletContextListner which will set OGNL security manager to null when the context is initialized.
03 |
import javax.servlet.ServletContextEvent; |
04 |
import javax.servlet.ServletContextListener; |
06 |
import ognl.OgnlRuntime; |
08 |
public class OgnlListener implements ServletContextListener { |
11 |
public void contextDestroyed(ServletContextEvent arg0) { |
17 |
public void contextInitialized(ServletContextEvent arg0) { |
18 |
OgnlRuntime.setSecurityManager( null ); |
- Also we will need to make entry in web.xml file also for OgnlListener
2 |
< listener-class >com.login.OgnlListener listener-class > |
- Now if you run the web application you will see the login page.
- You need to add this step if you are using Google App Engine 1.2.6 because when you run struts2 application on google app engine 1.2.6 you will get the following error:-
javax.servlet.ServletException: java.lang.NoClassDefFoundError: javax.swing.tree.TreeNode is a restricted class. Please see the Google App Engine developer’s guide for more details.
at org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:825)
at org.apache.jasper.runtime.PageContextImpl.access$1100(PageContextImpl.java:64)
at org.apache.jasper.runtime.PageContextImpl$12.run(PageContextImpl.java:745)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:743)
at org.apache.jsp.login_jsp._jspService(login_jsp.java:86)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
at com.google.appengine.tools.development.PrivilegedJspServlet.access$101(PrivilegedJspServlet.java:23)
at com.google.appengine.tools.development.PrivilegedJspServlet$2.run(PrivilegedJspServlet.java:59)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.appengine.tools.development.PrivilegedJspServlet.service(PrivilegedJspServlet.java)
To avoid this error you need to create a new package “freemarker.core” in your source folder and add the following class
- Next step is to create the LoginAction which will be do the business processing of whether usename and password are correct .
03 |
import com.opensymphony.xwork2.ActionSupport; |
05 |
public class LoginAction extends ActionSupport { |
07 |
private static final long serialVersionUID = 1L; |
08 |
private String username; |
09 |
private String password; |
11 |
public String login(){ |
12 |
if (username.equals( "whyjava" ) && password.equals( "password" )){ |
13 |
addActionMessage( "You are successfully logged in." ); |
16 |
addActionError( "Username and Password Combination doesnot match." ); |
20 |
public String getUsername() { |
24 |
public void setUsername(String username) { |
25 |
this .username = username; |
28 |
public String getPassword() { |
32 |
public void setPassword(String password) { |
33 |
this .password = password; |
- Next we need to modify struts.xml so that we LoginAction is configured.
01 |
xml version = "1.0" encoding = "UTF-8" ?> |
03 |
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" |
04 |
"http://struts.apache.org/dtds/struts-2.0.dtd"> |
06 |
< include file = "struts-default.xml" > include > |
07 |
< package name = "member" namespace = "/member" extends = "struts-default" > |
09 |
< result >/login.jsp result > |
11 |
< action name = "home" method = "login" class = "com.login.LoginAction" > |
12 |
< result >/home.jsp result > |
13 |
< result name = "input" >/login.jsp result > |
- finally we need to add one more jsp which is home.jsp which will be called when user is able to successfully login.
01 |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" |
02 |
pageEncoding="ISO-8859-1"%> |
03 |
<%@ taglib prefix="s" uri="/struts-tags"%> |
04 |
http://www.w3.org/TR/html4/loose.dtd"> |
07 |
< meta http-equiv = "Content-Type" content = "text/html; charset=ISO-8859-1" > |
08 |
< title >Home Page title > |
- Now try running this application by right click on project run as > web application and click http://localhost:8080.
- Now click on the login link you will be taken to the login page
- Now enter username as whyjava and password as password you will be an struts 2 action will fire and you will be taken to the home page.
I have tried to cover all the steps you will need to start of your first struts 2 project. Hope you all find this post useful.
If you need to start learning struts2 you can read Struts 2 in Action. It is a very good book to get a very good understanding of all the struts 2 concepts.
原文地址:http://whyjava.wordpress.com/2009/08/30/creating-struts2-application-on-google-app-engine-gae/