先按照文档,做一次:
1,建立WEB.XML:
<?
xml version="1.0" encoding="UTF-8"
?>
< web-app >
< display-name > Struts Blank </ display-name >
< filter >
< filter-name > struts2 </ filter-name >
< filter-class > org.apache.struts2.dispatcher.FilterDispatcher </ filter-class >
</ filter >
< filter-mapping >
< filter-name > struts2 </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< welcome-file-list >
< welcome-file > index.html </ welcome-file >
</ welcome-file-list >
</ web-app >
< web-app >
< display-name > Struts Blank </ display-name >
< filter >
< filter-name > struts2 </ filter-name >
< filter-class > org.apache.struts2.dispatcher.FilterDispatcher </ filter-class >
</ filter >
< filter-mapping >
< filter-name > struts2 </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< welcome-file-list >
< welcome-file > index.html </ welcome-file >
</ welcome-file-list >
</ web-app >
文档中有一个org.apache.struts2.dispatcher.FilterDispatcher的filter
还有org.springframework.web.context.ContextLoaderListener
2.建SPRING的BEAN配置文件:applicationContext.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans default-autowire ="autodetect" >
<!-- add your spring beans here -->
</ beans >
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans default-autowire ="autodetect" >
<!-- add your spring beans here -->
</ beans >
3.建struts配置文件:
<!
DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd" >
< struts >
< include file ="example.xml" />
<!-- Add packages here -->
</ struts >
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd" >
< struts >
< include file ="example.xml" />
<!-- Add packages here -->
</ struts >
演示了一下配置文件分块的方法,下面这个才起作用:
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
< struts >
< package name ="example" namespace ="/example" extends ="struts-default" >
< action name ="HelloWorld" class ="example.HelloWorld" >
< result > /example/HelloWorld.jsp </ result >
</ action >
< action name ="Login!*" method ="{1}" class ="example.Login" >
< result name ="input" > /example/Login.jsp </ result >
< result type ="redirect-action" > Menu </ result >
</ action >
< action name ="*" class ="example.ExampleSupport" >
< result > /example/{1}.jsp </ result >
</ action >
<!-- Add actions here -->
</ package >
</ struts >
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
< struts >
< package name ="example" namespace ="/example" extends ="struts-default" >
< action name ="HelloWorld" class ="example.HelloWorld" >
< result > /example/HelloWorld.jsp </ result >
</ action >
< action name ="Login!*" method ="{1}" class ="example.Login" >
< result name ="input" > /example/Login.jsp </ result >
< result type ="redirect-action" > Menu </ result >
</ action >
< action name ="*" class ="example.ExampleSupport" >
< result > /example/{1}.jsp </ result >
</ action >
<!-- Add actions here -->
</ package >
</ struts >
4,录入验证:Login-validation.xml
这个很象struts1.x
<!
DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd" >
< validators >
< field name ="username" >
< field-validator type ="requiredstring" >
< message key ="requiredstring" />
</ field-validator >
</ field >
< field name ="password" >
< field-validator type ="requiredstring" >
< message key ="requiredstring" />
</ field-validator >
</ field >
</ validators >
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd" >
< validators >
< field name ="username" >
< field-validator type ="requiredstring" >
< message key ="requiredstring" />
</ field-validator >
</ field >
< field name ="password" >
< field-validator type ="requiredstring" >
< message key ="requiredstring" />
</ field-validator >
</ field >
</ validators >
5.建立资源文件package.properties,这个也很象struts1.x
HelloWorld.message
=
Struts is up and running
requiredstring = ${getText(fieldName)} is required.
password = Password
username = User Name
Missing.message = This feature is under construction. Please try again in the next interation.
requiredstring = ${getText(fieldName)} is required.
password = Password
username = User Name
Missing.message = This feature is under construction. Please try again in the next interation.
6.搞个action类,和WW2一模一样:
package
example;
public class Login extends ExampleSupport {
public String execute() throws Exception {
if (isInvalid(getUsername())) return INPUT;
if (isInvalid(getPassword())) return INPUT;
return SUCCESS;
}
private boolean isInvalid(String value) {
return (value == null || value.length() == 0 );
}
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this .username = username;
}
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this .password = password;
}
}
public class Login extends ExampleSupport {
public String execute() throws Exception {
if (isInvalid(getUsername())) return INPUT;
if (isInvalid(getPassword())) return INPUT;
return SUCCESS;
}
private boolean isInvalid(String value) {
return (value == null || value.length() == 0 );
}
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this .username = username;
}
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this .password = password;
}
}
7.搞个helloworld类,也和WW2一样:
这里调用了资源文件中的 message, 这里比struts1.X类似功能要直接,会好用一些
package
example;
/**
* <code>Set welcome message.</code>
*/
public class HelloWorld extends ExampleSupport {
public String execute() throws Exception {
setMessage(getText(MESSAGE));
return SUCCESS;
}
/**
* Provide default valuie for Message property.
*/
public static final String MESSAGE = " HelloWorld.message " ;
/**
* Field for Message property.
*/
private String message;
/**
* Return Message property.
*
* @return Message property
*/
public String getMessage() {
return message;
}
/**
* Set Message property.
*
* @param message Text to display on HelloWorld page.
*/
public void setMessage(String message) {
this .message = message;
}
}
/**
* <code>Set welcome message.</code>
*/
public class HelloWorld extends ExampleSupport {
public String execute() throws Exception {
setMessage(getText(MESSAGE));
return SUCCESS;
}
/**
* Provide default valuie for Message property.
*/
public static final String MESSAGE = " HelloWorld.message " ;
/**
* Field for Message property.
*/
private String message;
/**
* Return Message property.
*
* @return Message property
*/
public String getMessage() {
return message;
}
/**
* Set Message property.
*
* @param message Text to display on HelloWorld page.
*/
public void setMessage(String message) {
this .message = message;
}
}
8。搞个父类出来,这里只是演示用,所以空的
ExampleSupport.java
package
example;
import com.opensymphony.xwork2.ActionSupport;
/**
* Base Action class for the Tutorial package.
*/
public class ExampleSupport extends ActionSupport {
}
import com.opensymphony.xwork2.ActionSupport;
/**
* Base Action class for the Tutorial package.
*/
public class ExampleSupport extends ActionSupport {
}
9。可以测试一下了:
package
example;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import java.util.Map;
import java.util.Collection;
import java.util.List;
public class LoginTest extends ConfigTest {
public void FIXME_testLoginConfig() throws Exception {
ActionConfig config = assertClass( " example " , " Login!input " , " example.Login " );
assertResult(config, ActionSupport.SUCCESS, " Menu " );
assertResult(config, ActionSupport.INPUT, " /example/Login.jsp " );
}
public void testLoginSubmit() throws Exception {
Login login = new Login();
login.setUsername( " username " );
login.setPassword( " password " );
String result = login.execute();
assertSuccess(result);
}
// Needs access to an envinronment that includes validators
public void FIXME_testLoginSubmitInput() throws Exception {
Login login = new Login();
String result = login.execute();
assertInput(result);
Map errors = assertFieldErrors(login);
assertFieldError(errors, " username " , " Username is required. " );
assertFieldError(errors, " password " , " Password is required. " );
}
}
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import java.util.Map;
import java.util.Collection;
import java.util.List;
public class LoginTest extends ConfigTest {
public void FIXME_testLoginConfig() throws Exception {
ActionConfig config = assertClass( " example " , " Login!input " , " example.Login " );
assertResult(config, ActionSupport.SUCCESS, " Menu " );
assertResult(config, ActionSupport.INPUT, " /example/Login.jsp " );
}
public void testLoginSubmit() throws Exception {
Login login = new Login();
login.setUsername( " username " );
login.setPassword( " password " );
String result = login.execute();
assertSuccess(result);
}
// Needs access to an envinronment that includes validators
public void FIXME_testLoginSubmitInput() throws Exception {
Login login = new Login();
String result = login.execute();
assertInput(result);
Map errors = assertFieldErrors(login);
assertFieldError(errors, " username " , " Username is required. " );
assertFieldError(errors, " password " , " Password is required. " );
}
}
package
example;
import com.opensymphony.xwork2.ActionSupport;
import junit.framework.TestCase;
public class HelloWorldTest extends TestCase {
public void testHelloWorld() throws Exception {
HelloWorld hello_world = new HelloWorld();
String result = hello_world.execute();
assertTrue( " Expected a success result! " ,
ActionSupport.SUCCESS.equals(result));
assertTrue( " Expected the default message! " ,
hello_world.getText(HelloWorld.MESSAGE).equals(hello_world.getMessage()));
}
}
import com.opensymphony.xwork2.ActionSupport;
import junit.framework.TestCase;
public class HelloWorldTest extends TestCase {
public void testHelloWorld() throws Exception {
HelloWorld hello_world = new HelloWorld();
String result = hello_world.execute();
assertTrue( " Expected a success result! " ,
ActionSupport.SUCCESS.equals(result));
assertTrue( " Expected the default message! " ,
hello_world.getText(HelloWorld.MESSAGE).equals(hello_world.getMessage()));
}
}
package
example;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.config.RuntimeConfiguration;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import java.util.Map;
import java.util.List;
import org.apache.struts2.StrutsTestCase;
public class ConfigTest extends StrutsTestCase {
protected void assertSuccess(String result) throws Exception {
assertTrue( " Expected a success result! " ,
ActionSupport.SUCCESS.equals(result));
}
protected void assertInput(String result) throws Exception {
assertTrue( " Expected an input result! " ,
ActionSupport.INPUT.equals(result));
}
protected Map assertFieldErrors(ActionSupport action) throws Exception {
assertTrue(action.hasFieldErrors());
return action.getFieldErrors();
}
protected void assertFieldError(Map field_errors, String field_name, String error_message) {
List errors = (List) field_errors.get(field_name);
assertNotNull( " Expected errors for " + field_name, errors);
assertTrue( " Expected errors for " + field_name, errors.size() > 0 );
// TODO: Should be a loop
assertEquals(error_message,errors.get( 0 ));
}
protected void setUp() throws Exception {
super .setUp();
XmlConfigurationProvider c = new XmlConfigurationProvider( " struts.xml " );
configurationManager.addConfigurationProvider(c);
configurationManager.reload();
}
protected ActionConfig assertClass(String namespace, String action_name, String class_name) {
RuntimeConfiguration configuration = configurationManager.getConfiguration().getRuntimeConfiguration();
ActionConfig config = configuration.getActionConfig(namespace, action_name);
assertNotNull( " Mssing action " , config);
assertTrue( " Wrong class name: [ " + config.getClassName() + " ] " ,
class_name.equals(config.getClassName()));
return config;
}
protected ActionConfig assertClass(String action_name, String class_name) {
return assertClass( "" , action_name, class_name);
}
protected void assertResult(ActionConfig config, String result_name, String result_value) {
Map results = config.getResults();
ResultConfig result = (ResultConfig) results.get(result_name);
Map params = result.getParams();
String value = (String) params.get( " actionName " );
if (value == null )
value = (String) params.get( " location " );
assertTrue( " Wrong result value: [ " + value + " ] " ,
result_value.equals(value));
}
public void testConfig() throws Exception {
assertNotNull(configurationManager);
}
}
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.config.RuntimeConfiguration;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.ResultConfig;
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import java.util.Map;
import java.util.List;
import org.apache.struts2.StrutsTestCase;
public class ConfigTest extends StrutsTestCase {
protected void assertSuccess(String result) throws Exception {
assertTrue( " Expected a success result! " ,
ActionSupport.SUCCESS.equals(result));
}
protected void assertInput(String result) throws Exception {
assertTrue( " Expected an input result! " ,
ActionSupport.INPUT.equals(result));
}
protected Map assertFieldErrors(ActionSupport action) throws Exception {
assertTrue(action.hasFieldErrors());
return action.getFieldErrors();
}
protected void assertFieldError(Map field_errors, String field_name, String error_message) {
List errors = (List) field_errors.get(field_name);
assertNotNull( " Expected errors for " + field_name, errors);
assertTrue( " Expected errors for " + field_name, errors.size() > 0 );
// TODO: Should be a loop
assertEquals(error_message,errors.get( 0 ));
}
protected void setUp() throws Exception {
super .setUp();
XmlConfigurationProvider c = new XmlConfigurationProvider( " struts.xml " );
configurationManager.addConfigurationProvider(c);
configurationManager.reload();
}
protected ActionConfig assertClass(String namespace, String action_name, String class_name) {
RuntimeConfiguration configuration = configurationManager.getConfiguration().getRuntimeConfiguration();
ActionConfig config = configuration.getActionConfig(namespace, action_name);
assertNotNull( " Mssing action " , config);
assertTrue( " Wrong class name: [ " + config.getClassName() + " ] " ,
class_name.equals(config.getClassName()));
return config;
}
protected ActionConfig assertClass(String action_name, String class_name) {
return assertClass( "" , action_name, class_name);
}
protected void assertResult(ActionConfig config, String result_name, String result_value) {
Map results = config.getResults();
ResultConfig result = (ResultConfig) results.get(result_name);
Map params = result.getParams();
String value = (String) params.get( " actionName " );
if (value == null )
value = (String) params.get( " location " );
assertTrue( " Wrong result value: [ " + value + " ] " ,
result_value.equals(value));
}
public void testConfig() throws Exception {
assertNotNull(configurationManager);
}
}
哦,测试通过!
10。看看表示层是如何用的?
HelloWorld.jsp
<%
@ page contentType
=
"
text/html; charset=UTF-8
"
%>
<% @ taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
< title >< s:text name ="HelloWorld.message" /></ title >
</ head >
< body >
< h2 >< s:property value ="message" /></ h2 >
< h3 > Languages </ h3 >
< ul >
< li >
< s:url id ="url" action ="HelloWorld" >
< s:param name ="request_locale" > en </ s:param >
</ s:url >
< s:a href ="%{url}" > English </ s:a >
</ li >
< li >
< s:url id ="url" action ="HelloWorld" >
< s:param name ="request_locale" > es </ s:param >
</ s:url >
< s:a href ="%{url}" > Espanol </ s:a >
</ li >
</ ul >
</ body >
</ html >
<% @ taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
< title >< s:text name ="HelloWorld.message" /></ title >
</ head >
< body >
< h2 >< s:property value ="message" /></ h2 >
< h3 > Languages </ h3 >
< ul >
< li >
< s:url id ="url" action ="HelloWorld" >
< s:param name ="request_locale" > en </ s:param >
</ s:url >
< s:a href ="%{url}" > English </ s:a >
</ li >
< li >
< s:url id ="url" action ="HelloWorld" >
< s:param name ="request_locale" > es </ s:param >
</ s:url >
< s:a href ="%{url}" > Espanol </ s:a >
</ li >
</ ul >
</ body >
</ html >
Login.jsp
<%
@ page contentType
=
"
text/html; charset=UTF-8
"
%>
<% @ taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
< title > Sign On </ title >
</ head >
< body >
< s:form action ="Login" >
< s:textfield label ="%{getText('username')}" name ="username" />
< s:password label ="%{getText('password')}" name ="password" />
< s:submit />
</ s:form >
</ body >
</ html >
<% @ taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
< title > Sign On </ title >
</ head >
< body >
< s:form action ="Login" >
< s:textfield label ="%{getText('username')}" name ="username" />
< s:password label ="%{getText('password')}" name ="password" />
< s:submit />
</ s:form >
</ body >
</ html >
恭喜你! 现在您现在已经可以用STRUTS2进行开发了!