Struts2 Convention Plugin ( struts2 零配置 )

Struts2 Convention Plugin ( struts2 零配置 )_第1张图片demo 结构图 :

 

convention-plugin 可以用来实现 struts2 的零配置。

零配置的意思并不是说没有配置,而是通过约定大于配置的方式,大量通过约定来调度页面的跳转而使得配置大大减少。

考虑到某种因素,这里采用 myeclipse 作为示例 IDE,环境 :

JDK 1.6
myeclipse 8.6.1
struts 2.1.8

web.xml

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


struts.xml

< struts >

  
< constant  name ="struts.devMode"  value ="true" />                                                                       <!--  开发模式  -->
  
< constant  name ="struts.i18n.encoding"  value ="UTF-8" />                                                         <!--  Web运用编码  -->
  
< constant  name ="struts.convention.result.path"  value ="/view/"   />                                    <!--  搜索视图资源的路径  -->
  
< constant  name ="struts.convention.action.name.separator"  value ="_"   />                       <!--  Action类名分隔符  -->
  
< constant  name ="struts.convention.classes.reload"  value ="true"   />                                   <!--  convention类重加载  -->
  
< constant  name ="struts.convention.action.suffix"  value ="Action"   />                                 <!--  Action后缀名  -->
  
< constant  name ="struts.action.extension"  value ="action,do,html,htm,php,aspx"   />   <!--  Action扩展名  -->
  
< constant  name ="struts.convention.package.locators"  value ="action,actions"   />         <!--  搜索Action资源的包路径  -->
  
</ struts >

 

convention 几项重要配置 :

Action 类后缀名 : <constant name="struts.convention.action.suffix" value="Action" />

继承了 struts2 的 ActionSupport 类的类不是一个普通的类,它具有能够处理请求和对请求作出响应的能力,

通常,开发者常常为这种特殊的类起一个后缀名,以区分一般普通的类。例如,xxAction,xxController,

这里的类名的后缀 Action,Controller 就是对应上面配置中的 value 的值,这个值会在发起 URL 请求的时候被截去。例如 : TestAction ---> test

Action类扩展名 [多项以逗号隔开]    <constant name="struts.action.extension" value="action,do,html,htm,php,aspx" />

与文件的扩展名相似的,例如 : TestAction ---> test.action 或 test.do 或 test.html 或 test.php 或 test.aspx 或 ...

注意 : 若该项被配置,则,访问所有的 Action 都需带上 Action 的扩展名,否则客户端将抛出 404 ERROR

Action类名分隔符 : <constant name="struts.convention.action.name.separator" value="_" />

若 Action 类名中出现驼峰标识的串,则用分隔符来切割串,如 HelloWorldAction ---> hello_world

搜索 Action 资源的包路径 [多项以逗号隔开] : <constant name="struts.convention.package.locators" value="action,actions" />

只有当包名含有以上配置中 value 值中至少一项时,convention plugin 才能搜索找得到该 Action,

否则就算访问的 Action 是存在的,convention plugin 也无法找得到该 Action

注意 : 若包名不是以上列出现过的串结束,则后面的串相当于该包下所有 Action 访问的命名空间 ( 以下面的 LoginAction 作为示例 )。

搜索视图资源(JSP,freemarker,等)的路径 : <constant name="struts.convention.result.path" value="/view/" />

所有的视图资源都需放在配置指定的文件夹路径下,否则,就算结果视图是真实存在的,convention plugin 也无法找得到该视图。默认值是 /WEB-INF/content/

 

 

convention 约定 :

1. [ Action 不存在的情况 ] 若 convention plugin 在包搜索路径中搜索不到与请求的 URL 相匹配的 Action,则会到视图的搜索路径下搜索

与请求的 URL 相匹配的视图资源,若还搜索不到,则抛出 no Action mapped Exception 

示例 : 

view/hello_world.jsp [ 没有与之匹配的 Action 类 ]

< html >
 
< body >
  
< h2 > Hello World!! </ h2 >
 
</ body >
</ html >




2. [ Action 的 execute 方法或动态方法调用的情况 ] 如请求 name!method.action,若 NameAction 存在,且 NameAction 中存在 method 这样一个方法,

则根据 method 方法返回的字符串,结果的视图资源名称规则 ( 视图以 JSP 文件为例 ) :

① success  ----->  name.jsp 或 name_success.jsp ; 若这两个视图同时存在,则 convention plugin 会选择 name_success.jsp 作为视图来展示

② 非 success 的任意串 string  ----->  name_string.jsp

示例 : 

package  net.yeah.fancydeepin.action;

import  com.opensymphony.xwork2.ActionSupport;
/**
 * -----------------------------------------
 * @描述  TODO
 * @作者  fancy
 * @邮箱  [email protected]
 * @日期  2012-10-26 <BR>
 * -----------------------------------------
 
*/
public   class  SayHelloAction  extends  ActionSupport{

    
private   static   final   long  serialVersionUID  =   1L ;

    
private  String message;
    
    
public  String execute(){
        
        message 
=   " Hello struts2 convention plugin! " ;
        
return  SUCCESS;
    }
    
    
public  String say(){
        
        message 
=   " SayHelloAction, say " ;
        
return   " world " ;
    }
    
    
public  String sayHello(){
        
        message 
=   " SayHelloAction, sayHello " ;
        
return   " conventionPlugin " ;
    }

    
public  String getMessage() {
        
return  message;
    }
    
}


view/say_hello.jsp

< html >
 
< body >
  
< h2 > say_hello.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >


view/say_hello_world.jsp

< html >
 
< body >
  
< h2 > say_hello_world.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >


view/say_hello_conventionPlugin.jsp

< html >
 
< body >
  
< h2 > say_hello_conventionPlugin.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >











convention 注解 :

@ParentPackage : 对应于 struts.xml 常量配置项的 <constant name="struts.convention.default.parent.package" value="xx"/> 默认值是 convention-default

@ResultPath : 对应于 struts.xml 常量配置项的 <constant name="struts.convention.result.path" value="xx" /> 默认值是 /WEB-INF/content/

@Namespace : Action 访问的命名空间,该注解一旦声明,结果的视图资源需放在 : 视图搜索目录/命名空间 ( 如 : view/simple/demo.jsp )


package  net.yeah.fancydeepin.action;

import  org.apache.struts2.convention.annotation.Namespace;
import  org.apache.struts2.convention.annotation.ParentPackage;
import  org.apache.struts2.convention.annotation.ResultPath;
import  com.opensymphony.xwork2.ActionSupport;
/**
 * -----------------------------------------
 * @描述  TODO
 * @作者  fancy
 * @邮箱  [email protected]
 * @日期  2012-10-26 <BR>
 * -----------------------------------------
 
*/
@ParentPackage(
" convention-default " )
@Namespace(
" /simple " )
@ResultPath(
" /view/ " )
public   class  DemoAction  extends  ActionSupport{

    
private   static   final   long  serialVersionUID  =   1L ;
    
private  String message;
    
    
public  String execute(){
        
        message 
=   " DemoAction " ;
        
return  SUCCESS;
    }

    
public  String getMessage() {
        
return  message;
    }
}


view/simple/demo.jsp

< html >
 
< body >
  
< h2 > demo.jsp  &rarr;  Hello World ${message}! </ h2 >
 
</ body >
</ html >




@Action

package  net.yeah.fancydeepin.action;

import  org.apache.struts2.convention.annotation.Action;
import  com.opensymphony.xwork2.ActionSupport;
/**
 * -----------------------------------------
 * @描述  TODO
 * @作者  fancy
 * @邮箱  [email protected]
 * @日期  2012-10-26 <BR>
 * -----------------------------------------
 
*/
public   class  ActionannotationAction  extends  ActionSupport{

    
private   static   final   long  serialVersionUID  =   1L ;
    
private  String message;
    
    @Action(
" invoke " )
    
public  String invokeMethod(){
        
        message 
=   " ActionannotationAction, invokeMethod " ;
        
return  SUCCESS;
    }

    
public  String getMessage() {
        
return  message;
    }
}


view/invoke.jsp

< html >
 
< body >
  
< h2 > invoke.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >





@Result,@Results

package  net.yeah.fancydeepin.action;

import  java.util.Random;
import  org.apache.struts2.convention.annotation.Action;
import  org.apache.struts2.convention.annotation.Result;
import  org.apache.struts2.convention.annotation.Results;
import  com.opensymphony.xwork2.ActionSupport;
/**
 * -----------------------------------------
 * @描述  TODO
 * @作者  fancy
 * @邮箱  [email protected]
 * @日期  2012-10-26 <BR>
 * -----------------------------------------
 
*/
@Results({@Result(name 
=   " success " , location  =   " result.jsp " )})
public   class  ResultAction  extends  ActionSupport{

    
private   static   final   long  serialVersionUID  =   1L ;
    
private  String message;
    
    
public  String execute(){
        
        message 
=   " ResultAction, execute " ;
        
return  SUCCESS;
    }
    
    @Action(value 
=   " doIt "
        results 
=  {
            @Result(name 
=   " isTrue " , location  =   " result_true.jsp " ),
            @Result(name 
=   " isFalse " , location  =   " result_false.jsp " )
        }
    )
    
public  String doExecute(){

        message 
=   " doExecute isFalse. " ;
        
if ( new  Random().nextBoolean()){
            message 
=   " doExecute isTrue. " ;
            
return   " isTrue " ;
        }
        
return   " isFalse " ;
    }

    
public  String getMessage() {
        
return  message;
    }
}


view/result.jsp

< html >
 
< body >
  
< h2 > result.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >


view/result_true.jsp

< html >
 
< body >
  
< h2 > result_true.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >


view/result_false.jsp

< html >
 
< body >
  
< h2 > result_false.jsp  &rarr;  Message : ${message} </ h2 >
 
</ body >
</ html >








The last example

 

package  net.yeah.fancydeepin.action.admin;

import  com.opensymphony.xwork2.ActionSupport;
/**
 * -----------------------------------------
 * @描述  TODO
 * @作者  fancy
 * @邮箱  [email protected]
 * @日期  2012-10-26 <BR>
 * -----------------------------------------
 
*/
public   class  LoginAction  extends  ActionSupport{

    
private   static   final   long  serialVersionUID  =   1L ;
    
private  String username;
    
private  String password;

    
public  String log(){
        
        username 
=  username.intern();
        password 
=  password.intern();
        
if (username  ==   " admin "   &&  password  ==   " fancy " ){
            
return  SUCCESS;
        }
        
return  ERROR;
    }

    
public   void  setUsername(String username) {
        
this .username  =  username;
    }

    
public   void  setPassword(String password) {
        
this .password  =  password;
    }
}


view/admin/login_success.jsp

< html >
 
< body >
  
< h2 > Welcome!! </ h2 >
 
</ body >
</ html >


view/admin/login_error.jsp

< html >
 
< body >
  
< h2 > Login Failed!! </ h2 >
 
</ body >
</ html >





转自:http://www.blogjava.net/fancydeepin/archive/2012/10/26/struts2_convention_plugin.html

 

你可能感兴趣的:(convention)