先按照文档,做一次:

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 >

文档中有一个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 >

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 >

演示了一下配置文件分块的方法,下面这个才起作用:

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

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 >

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.


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

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

8。搞个父类出来,这里只是演示用,所以空的

ExampleSupport.java

package  example;   
  
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. " );   
    }   
  
}
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()));   
    }   
}
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);   
    }   
  
}  

哦,测试通过!

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 >

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 >

恭喜你! 现在您现在已经可以用STRUTS2进行开发了!