`
Riddick
  • 浏览: 632741 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Struts2.1.x快速入门(二)

阅读更多

------------------------------------------------------------------

本文转载自--http://yulon.iteye.com/blog/551982

------------------------------------------------------------------

六、Struts2的处理流程与Action的管理方式

       6.1struts2处理请求图

StrutsPrepareAndExecuteFilter是Struts 2框架的核心控制器(相当于strtuts1.x的ActionServlet类的作用),它负责拦截由<url-pattern>/*</url-pattern>指定的所有用户请求,当用户请求到达时,该Filter会过滤用户的请求。默认情况下,如果用户请求的路径不带后缀或者后缀以.action结尾,这时请求将被转入Struts 2框架处理,否则Struts 2框架将略过该请求的处理。当请求转入Struts 2框架处理时会先经过一系列的拦截器,然后再到Action。与Struts1不同,Struts2对用户的每一次请求都会创建一个Action,所以Struts2中的Action是线程安全的。也正因为如此,Struts2里可以定义成员变量,从而废弃了Struts1.x里的Form Bean.即Struts2的Action已具备了Struts1.x里的Form Bean的功能.

七、动态方法调用和使用通配符定义action

       7.1  动态方法调用

              如果Action中存在多个业务方法时,我们可以使用!+方法名调用指定方法。 我们在HelloWorldAction里添加两个业务方法,如下:

Java代码 复制代码
  1. public String del() {   
  2.     message = "调用del()删除方法";   
  3.     return "success";   
  4. }   
  5.   
  6. public String add() {   
  7.     message = "调用add()添加方法";   
  8.     return "success";   
  9. }  
	public String del() {
		message = "调用del()删除方法";
		return "success";
	}

	public String add() {
		message = "调用add()添加方法";
		return "success";
	}

    如果要访问action的del() 方法,我们可以这样调用:/struts2.1/test/helloworld!del    ,动态方法调用就是那么简单,它实现了跟struts1.x 的DispatchAction一样的作用.

    注意: struts2的官方文档已经不建议我们这样使用,建议我们使用另外一种方式来实现:使用通配符定义action来替代

 

        7.2   使用通配符定义action

                即用*号来表示在动态改变的字符或字符串.在struts.xml的test包中添加一个action,如下:

Xml代码 复制代码
  1. <action name="*User" class="cn.gkit.action.HelloWorldAction" method="{1}" >  
  2.         <param name="message">属性注入</param>  
  3. <result name="success">/WEB-INF/jsp/helloworld.jsp</result>    
  4. </action>  
 <action name="*User" class="cn.gkit.action.HelloWorldAction" method="{1}" >
        	<param name="message">属性注入</param>
	<result name="success">/WEB-INF/jsp/helloworld.jsp</result> 
 </action>

    此时如果要访问action的del() 方法,我们可以这样调用:/struts2.1/test/delUser 即可调用到del()方法.

    知识提示:{1}表示与第一个*号匹配,{1}不但可以在method属性上使用,还可以在其他地方使用,如在<result>使用:

Xml代码 复制代码
  1. <result name="success">/WEB-INF/jsp/{1}.jsp</result>   
<result name="success">/WEB-INF/jsp/{1}.jsp</result> 

   

 八、自定义类型转换器 

        问题引入:对于Date类型的属性,可以接收格式为2009-12-20的请求参数值,并将其自动转换成Date类型.但如果项目需求要接收形如:20091220格式的日期该怎么办,在struts1.x中我们可以通过定义类型转换器来实现,同样在Struts2.x里我们也可以定义类似的转换器,并且比struts1.x的转换器要强大,它实现了双向转换的功能.

 

      8.1   定义局部类型转换器

 

       首先在HelloWorldAction里增加一个java.util.Date 类型的birthday字段,并提供getter和setter方法.如下:

Java代码 复制代码
  1. private Date birthday;   
  2.   
  3. public Date getBirthday() {   
  4.     return birthday;   
  5. }   
  6.   
  7. public void setBirthday(Date birthday) {   
  8.     this.birthday = birthday;   
  9. }  
	private Date birthday;

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

      然后:定义Date类型转换器,定义转器有两种方式:

      第一种是继承com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter类,重写它的convertValue方法,实现如下:

 

Java代码 复制代码
  1. public class DateTypeConverter extends DefaultTypeConverter{   
  2.     @Override  
  3.     public Object convertValue(Map<String, Object> context, Object value,   
  4.             Class toType) {   
  5.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");   
  6.         try {    
  7.             if(toType == Date.class){//当字符串向Date类型转换时   
  8.                 String[] params = (String[]) value;// Request.getParameterValues()    
  9.                 return dateFormat.parse(params[0]);   
  10.             }else if(toType == String.class){//当Date转换成字符串时   
  11.                 Date date = (Date) value;   
  12.                 return dateFormat.format(date);   
  13.             }   
  14.         } catch (ParseException e) {}   
  15.         return null;   
  16.         }   
  17. }  
public class DateTypeConverter extends DefaultTypeConverter{
	@Override
	public Object convertValue(Map<String, Object> context, Object value,
			Class toType) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
		try { 
			if(toType == Date.class){//当字符串向Date类型转换时
				String[] params = (String[]) value;// Request.getParameterValues() 
				return dateFormat.parse(params[0]);
			}else if(toType == String.class){//当Date转换成字符串时
				Date date = (Date) value;
				return dateFormat.format(date);
			}
		} catch (ParseException e) {}
		return null;
		}
}

 

    第二种方式是继承org.apache.struts2.util.strutsTypeConverter类,并实现它的两个抽象方法,实现代码如下:

 

Java代码 复制代码
  1. public class DateTypeConverter extends StrutsTypeConverter {   
  2.     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");   
  3.     @Override  
  4.     public Object convertFromString(Map context, String[] value, Class toType) {   
  5.         String[] params = (String[]) value;// Request.getParameterValues()    
  6.         try {   
  7.             return dateFormat.parse(params[0]);   
  8.         } catch (ParseException e) {}   
  9.         return null;   
  10.     }   
  11.   
  12.     @Override  
  13.     public String convertToString(Map context, Object value) {   
  14.         Date date = (Date) value;   
  15.         return dateFormat.format(date);   
  16.     }   
  17. }  
public class DateTypeConverter extends StrutsTypeConverter {
	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
	@Override
	public Object convertFromString(Map context, String[] value, Class toType) {
		String[] params = (String[]) value;// Request.getParameterValues() 
		try {
			return dateFormat.parse(params[0]);
		} catch (ParseException e) {}
		return null;
	}

	@Override
	public String convertToString(Map context, Object value) {
		Date date = (Date) value;
		return dateFormat.format(date);
	}
}

    知识提示:查找StrutsTypeConverter的源码发现,它本身也继承了DefaultTypeConverter类.StrutsTypeConverter类使用的一种设计模式是模板方法设计模式。

 

        最后,配置要使用该转换器的action类

        在HelloWorldAction同一包内新建HelloWorldAction-conversion.properties文件.文件名的后半部分是固定不变的

*-conversion.properties,*表示的是对应的Action的简单类名(即不带包名),在该文件里如下定义:

Xml代码 复制代码
  1. birthday=cn.gkit.type.converter.DateTypeConverter  
birthday=cn.gkit.type.converter.DateTypeConverter

 birthday表示要转换的属性,右边对应一个转换器.

此时访问路径:/struts2.1/test/helloworld.action?birthday=20091220,Struts框架就是使用刚才定义的转换器将String类型转换成java.util.Date类型.

 

     8.2  定义全局类型转换器

           全局类型转换器的配置文件名是固定的:xwork-conversion.properties,并将该文件放到src目录,编译后会自动WEB-INF\classes目录下.在该文件里如下定义:

Java代码 复制代码
  1. java.util.Date=cn.gkit.type.converter.DateTypeConverter  
java.util.Date=cn.gkit.type.converter.DateTypeConverter

    左边定义的是要转换的类型,作用了全部Action类.

    注意: 如果同时定义了局部和全局的类型转换器,对于同一个类型,局部会覆盖全局的转换器

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics