`
JavaCrazyer
  • 浏览: 3009123 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类

Struts温习(7)--自定义类型转换器

阅读更多


一、概述 

    在B/S应用中,将字符串请求参数转换为相应的数据类型,是MVC框架提供的功能,而Struts2是很好的MVC框架实现者,理所当然,提供了类型转换机制。 

    Struts2的类型转换是基于OGNL表达式的,只要我们把HTML输入项(表单元素和其他GET/POET的参数)命名为合法的OGNL表达式,就可以充分利用Struts2的转换机制。 

    除此之外,Struts2提供了很好的扩展性,开发者可以非常简单的开发自己的类型转换器,完成字符串和自定义复合类型之间的转换。总之,Struts2 的类型转换器提供了非常强大的表现层数据处理机制,开发者可以利用Struts2的类型转换机制来完成任意的类型转换。 


 WEB应用接收到表单提交的数据都是String类型的,Struts2可方便的转换为 常规类型(数值,日期) / 自定义类型(User,Point类).

  如果转换中出现异常,conversionError拦截器会自动处理该异常.


二、 常规类型的转换
  比如表单提交的信息有 用户名,生日, 年龄, Action中对应的数据类型分别是 String, Date, int.  没什么好说的, Struts2会自动完成.
  Struts2内建了常用的类型转换器,如String ,boolean,char,int,long,float,double,Date, 数组(假定元素是String类型), 集合(假定元素是String类型,用ArrayList封装)

三、页面中常用类型的OGNL表达式写法
     在html表单中的文本框里输入的不管是数值类型还是字符类型,最后都是以String类传到后台。如果后台bean的属性是int、double、Date等,Struts就会自动把字符类型转换成相应的类型。
    Struts2中默认提供了一些内置的转换器,包括8个基本类型,Date,array数组,List,Map类。也可以自定义转换器。通过实现ogln.TypeConverter接口实现它的方法就可以定义其他类型的转换,不过还要配置相应的资源文件。其实那几个内置的转换器已经足够使用了,很少会专门定义一个转换器。
    基本数据类型转换器没有什么特殊要求,只要输入的值符合基本数据类型,它都会自动转换,否则会出现错误提示。比如对于int类型,前天就不能输入跟数字无关的字符。再来就是日期类型,默认好像是YY-MM-DD,比如2008-8-8,如果写成8-8-2008提交后就会出现错误提示。

    对于Array数组,List,Map则需要配合OGNL表达式一起使用。比如后台有个属性是String [] name,在前台界面 
  <s:textfield name="names[0]" label="names"/>
   <s:textfield name="names[1]" label="names"/>
   <s:textfield name="names[2]" label="names"/> 

就会对这个数组赋值。List跟数组使用方式一样,但只针对不加泛型的基本数据类型的的List,如果加了泛型则是
<s:textfield name="users[0].username" label="Usernames"/>
<s:textfield name="users[1].username" label="Usernames"/>
<s:textfield name="users[2].username" label="Usernames"/>
比如User类中有个username属性,List<User> users这个属性对应上面的写法。

最后是Map的转换方式
<s:textfield name="maidenNames['beth']" label="Maiden Name"/>
<s:textfield name="maidenNames['sharon']" label="Maiden Name"/>
<s:textfield name="maidenNames['martha']" label="Maiden Name"/>

[]里的值对应到Map中的Key


四、自定义类型转换器
  实现TypeCoverter接口,或者继承DefaultTypeConverter实现类(该类实现了TypeCoverter接口),通过继承该实现类来实现自己的类型转换器。重写convertValue方法即可。 

    为了简化类型转换器的实现,Struts2提供了一个StrutsTypeConverter抽象类,这个抽象类是DefaultConverter的子类。实现了方法,并提供了2个不同转换方向的方法:Object 
convertToString(Map context,String[] values,Class toClass)和String convertFromString(Map context,Object o)。 

 具体使用步骤:
 1)注册应用 
    实现了自定义类型转换器之后,将该类型转换器注册在Web应用中,Struts2框架才可以正常使用该类型转换器。 
关于类型转换器的注册方式,主要有3中: 
A、注册局部类型转换器:仅仅对某个Action的属性起作用。 
B、注册全局类型转换器:对所有Action的特定类型的属性都会生效。 
C、使用JDK1.5的注释来注册类型转换器:通过注释方式来生成类型转换器。 

2)局部类型转换器 
    提供如下格式的文件 
文件名:  ActionName-conversion.properties  
内容:多个propertyName(属性名)=类型转换器类(含包名),如  date=com.aumy.DateConverter 
存放位置:和ActionName类相同路径。 

3)全局类型转换器 
    提供如下格式的文件 
文件名:  xwork-conversion.properties 
内容:   多个“复合类型=对应类型转换器”项组成,如  java.Util.Date=com.aumy.DateConverter 
存放位置:WEB-INF/classes/目录下。 


应用示例

先看几个实体类
 User.java
package com.javacrazyer.domain;

import java.util.Date;


public class User {
	private Integer id;
	private String loginname;
	private Double score;
	private Character cha;
	private Date birthday;
	private Gender gender;
	
	public User(){}
	
	public User(Integer id, String loginname, Double score, Gender gender,
			Character cha, Date birthday) {
		this.id = id;
		this.loginname = loginname;
		this.score = score;
		this.gender = gender;
		this.cha = cha;
		this.birthday = birthday;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLoginname() {
		return loginname;
	}
	public void setLoginname(String loginname) {
		this.loginname = loginname;
	}
	public Double getScore() {
		return score;
	}
	public void setScore(Double score) {
		this.score = score;
	}
	public Gender getGender() {
		return gender;
	}
	public void setGender(Gender gender) {
		this.gender = gender;
	}
	public Character getCha() {
		return cha;
	}
	public void setCha(Character cha) {
		this.cha = cha;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String toString() {
		return "User [birthday=" + birthday + ", cha=" + cha + ", gender="
				+ gender + ", id=" + id + ", loginname=" + loginname
				+ ", score=" + score+ "]";
	}
}
 Gender.java
package com.javacrazyer.domain;

public enum Gender {
	M,F;
}
 Tel.java
package com.javacrazyer.domain;


public class Tel {
	private String areaCode;
	private String phoneCode;

	public String getAreaCode() {
		return areaCode;
	}

	public void setAreaCode(String areaCode) {
		this.areaCode = areaCode;
	}

	public String getPhoneCode() {
		return phoneCode;
	}

	public void setPhoneCode(String phoneCode) {
		this.phoneCode = phoneCode;
	}

}
 
看看自定义Tel类型的转换器
package com.javacrazyer.converter;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

import com.javacrazyer.domain.Tel;

public class TelConverter extends StrutsTypeConverter {

	//把String转换成Tel类型
	//context:OGNL上下文的Map对象
	//values :需要转换的字符串数组
	//toClass:要转换的目标类型

	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
		
		if(toClass == Tel.class){
			String str = values[0];
			
			String[] strArr = str.split("-");
			
			Tel tel = new Tel();
			tel.setAreaCode(strArr[0]);
			tel.setPhoneCode(strArr[1]);
			return tel;
		}
		
		return null;
	}

	//把Tel类型转换成String类型
	//context:OGNL上下文的Map对象
	//o:需要转换的对象
	@Override
	public String convertToString(Map context, Object o) {
		if(o instanceof Tel){
			Tel tel = (Tel)o;
			return tel.getAreaCode() + "-" + tel.getPhoneCode();
		}
		return null;
	}
}
 
业务处理UserAction.java
package com.javacrazyer.web.action;


import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import com.javacrazyer.domain.Tel;
import com.javacrazyer.domain.User;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 使用注解来配置Action
 * 
 */
public class UserAction extends ActionSupport {
	private static final long serialVersionUID = -2554018432709689579L;
	private User user;
	private List<String> list;
	private List<User> userList;
	private Set<User> userSet = new HashSet<User>();
	
	private Map<String, String> map = new HashMap<String, String>();
	
	private Tel tel;
	
	public String execute() throws Exception{
		System.out.println(user);
		
		System.out.println(list);
		
		
		for(User user : userList){
			System.out.println(user);
		}
		
		System.out.println("=========================");
		for(User user : userSet){
			System.out.println(user);
		}
		
		
		for (Entry entry:map.entrySet()){
			System.out.println(entry.getKey()+"=="+entry.getValue());
		}
		System.out.println("区号:" + this.tel.getAreaCode());
		System.out.println("电话号:" + this.tel.getPhoneCode());
		
		return SUCCESS;
	}

	public User getUser() {
		return user;
	}


	public void setUser(User user) {
		this.user = user;
	}


	public List<String> getList() {
		return list;
	}


	public void setList(List<String> list) {
		this.list = list;
	}


	public List<User> getUserList() {
		return userList;
	}


	public void setUserList(List<User> userList) {
		this.userList = userList;
	}

	public Set<User> getUserSet() {
		return userSet;
	}

	public void setUserSet(Set<User> userSet) {
		this.userSet = userSet;
	}

	public Map<String, String> getMap() {
		return map;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}

	public Tel getTel() {
		return tel;
	}

	public void setTel(Tel tel) {
		this.tel = tel;
	}
	
	
}
 局部类型转换器,与UserAction.java在同一目录
UserAction-conversion.properties
tel=com.javacrazyer.converter.TelConverter

#集合属性-Set类型   
Element_userSet=com.javacrazyer.domain.User
#指定索引
KeyProperty_userSet=id

#指定key类型
Key_map=java.lang.String
#指定value类型
Element_map=java.lang.String
 全局类型转换器src/xwork-conversion.properties
com.qiujy.domain.Tel=com.javacrazyer.converter.TelConverter
 src/struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">

<struts>
	<!-- 请求参数的编码方式 -->
	<constant name="struts.i18n.encoding" value="UTF-8"/>
	<!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
	<constant name="struts.action.extension" value="action,do,go,xkk"/>
	<!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  -->
	<constant name="struts.configuration.xml.reload" value="true"/>
	<!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  -->
	<constant name="struts.devMode" value="false"/>
	<!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  -->
	<constant name="struts.serve.static.browserCache" value="false" />
	<!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
	<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
	
	<!-- 指定由spring负责action对象的创建 
	<constant name="struts.objectFactory" value="spring" />
	-->
	<!-- 是否开启动态方法调用 -->
	<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
	
	<package name="my" extends="struts-default" namespace="/">
		<global-results>
			<result name="input">/error.jsp</result>
		</global-results>
	
		<action name="info" class="com.javacrazyer.web.action.UserAction">
			<result name="success">/info.jsp</result>
			<result name="input">/error.jsp</result>
		</action>
	</package>
	
</struts>
 converter.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Struts2中的转换器</title>
  </head>
  <body>
<h3>Struts2中的转换器</h3><hr/>
<form action="info.action" method="post">
	<table>
	
		<tr>
			<td>登录名</td>
			<td><input type="text" name="user.loginname"/></td>
		</tr>
		<tr>
			<td>生日</td>
			<td><input type="text" name="user.birthday"/></td>
		</tr>
		<tr>
			<td>性别</td>
			 <!--OGNL表达式:user属性的gender属性[由于是日期类型,程序中自定义有日期转换器]写法   -->
			<td><input type="radio" name="user.gender" value="M" checked="checked"/>男<input type="radio" name="user.gender" value="F"/>女</td>
		</tr>
		<tr>
			<td>考试成绩</td>
			<td><input type="text" name="user.score"/></td>
		</tr>
		<tr>
			<td colspan="2"><input type="submit" value=" 提交 "/></td>
		</tr>
	</table>
	
	<!--OGNL表达式:元素类型为String类型的List的写法   -->
	<input type="hidden" name="list[0]" value="张三"/>
	<input type="hidden" name="list[1]" value="李四"/>
	<input type="hidden" name="list[2]" value="王五"/>
	
	<!--OGNL表达式:元素类型为user类型的LIST属性的写法   -->
	<input type="hidden" name="userList[0].loginname" value="张三"/>
	<input type="hidden" name="userList[1].loginname" value="李"/>
	<input type="hidden" name="userList[2].loginname" value="王"/>
	
	<!--OGNL表达式:元素类型为user类型的set属性的写法 -->
	<input type="hidden" name="userSet.makeNew[0].loginname" value="xxx"/>
	<input type="hidden" name="userSet.makeNew[1].loginname" value="yyy"/>
	<input type="hidden" name="userSet.makeNew[2].loginname" value="ggg"/>
	 
	 <!--OGNL表达式:map属性的写法   -->
	 <input type="hidden" name="map['jolin']" value="caiyilin"/>
     <input type="hidden" name="map['jay']" value="zhoujielun"/>
	  
	   <!--OGNL表达式:Tel属性的写法   -->
	 <input type="hidden" name="tel" value="010-66298878"/>
</form>
  </body>
</html>
 info.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>显示提交的数据</title>
  </head>
  <body>
<h3>显示提交的数据</h3><hr/>
	<table>
		<tr>
			<td>登录名</td>
			<td><s:property value="user.loginname"/> </td>
		</tr>
		<tr>
			<td>生日</td>
			<td><s:date name="user.birthday" format="yyyy-MM-dd HH:mm:ss"/></td>
		</tr>
		<tr>
			<td>性别</td>
			<td><s:property value="user.gender"/> </td>
		</tr>
		<tr>
			<td>考试成绩</td>
			<td><s:property value="user.score"/></td>
		</tr>
		<tr>
			<td>电话号</td>
			<td><s:property value="tel"/></td>
		</tr>
		<tr>
			<td colspan="2"><input type="button" value=" 返回 " onclick="history.go(-1);" /></td>
		</tr>
	</table>

<hr/><s:debug/>
  </body>
</html>
 error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>出现内部错误</title>
  </head>
  <body>
<h3>出现内部错误</h3><hr/>

<s:actionerror/>
  </body>
</html>
 
总结
Struts2中的类型转换器
  1) Struts2中内置了一些常用的类型转换器:可以把客户端提交的String数据转换成对应类型的数据。
     a) 基本类型
     b) java.util.Date:
     c) 数组和列表
  2) 自定义类型转换器: 
     a) 继承自org.apache.struts2.util.StrutsTypeConverter类
  public abstract Object convertFromString(Map context, String[] values, Class toClass);
        context:OGNL上下文的Map对象
        values :需要转换的字符串数组
        toClass:要转换的目标类型
  public abstract String convertToString(Map context, Object o);
         context:OGNL上下文的Map对象
         o:需要转换的对象
     b) 注册:以全局方式
                    在应用程序的classpath下创建一属性文件,名为:xwork-conversion.properties
                    文件内容:待转换类型的全限定名=类型转换器类的全限定名
  3) 转换Set:
     0) Action中的Set属性需要进行初始化:如:
        private Set<User> userSet = new HashSet<User>();
     a) 添加针对某个Action的转换器配置文件:ActionName-conversion.properties 如:
        UserAction-conversion.properties
        
     b) 在这个文件中添加:Action的Set属性的相关配置
        Element_属性名=Set中的元素类型的全限定名                 #指定Set中的元素类型
        KeyProperty_属性名=Set中的元素类型中的某个属性  #指定Set的索引字段
                   如下示例:
        Element_userSet=com.qiujy.domain.User
        KeyProperty_userSet=id
        
     c) JSP页面: <input type="text" name="Set属性名.makeNew[0].属性名"/>
                    如:<input type="text" name="userSet.makeNew[0].loginname"/>



分享到:
评论
2 楼 CoolDragon_Y 2014-08-29  
你好,请问Map<String,List<Object>>如何转换?
1 楼 iceyang002 2014-07-11  
你好,请问list<map<String,Object>> 如何转换,如何从页面到action?

相关推荐

    Struts自定义类型转换器

    ### Struts自定义类型转换器 #### 一、概述 在Web开发中,表单提交的数据通常是字符串形式的,而在业务逻辑处理时往往需要将这些数据转换为其他类型的对象(如日期、数字等)。Struts框架为了更好地处理这种类型...

    传智播客struts2.1源代码_自定义类型转换器

    接着,当Struts2接收到相关参数时,会自动调用自定义转换器进行转换。 6. **调试与测试** 调试自定义类型转换器通常涉及到设置断点,观察转换过程中的变量状态,以及通过单元测试确保转换逻辑的正确性。在IDE如...

    struts2基础--使用自定义MVC

    4. **定制化配置**:Struts2的配置文件(struts.xml)可以被自定义,以指定Action的映射、结果类型、拦截器栈等。开发者可能根据租房系统的需求调整了这些配置。 5. **自定义模型驱动**:模型驱动是一种编程模式,...

    struts 2.0 自定义类型转换器 注册类型转换器 入门实例 简单实例

    当我们需要对默认类型转换器的功能进行扩展或者处理自定义类型时,就需要自定义类型转换器。 自定义类型转换器是Struts 2的核心特性之一,允许开发者根据业务需求定制数据转换规则。以下将详细介绍如何创建、注册...

    Struts2类型转换(一)----常规类型,自定义类型,错误处理

    理解并掌握如何利用内置转换器、自定义转换器以及处理转换错误,对于构建高效、稳定的Struts2应用至关重要。通过深入学习Struts2的源码和使用相关工具,我们可以更深入地了解这些机制,并优化我们的应用程序。

    Struts2自定义类型转换

    Struts2框架提供了强大的类型转换机制,允许开发者自定义类型转换器,以满足特定业务逻辑的需求。本文将深入探讨Struts2自定义类型转换的原理、分类以及具体实施步骤,帮助开发者更好地理解和应用这一功能。 #### ...

    struts2自定义类型转换器

    然而,对于如Date这样的复杂类型,需要自定义转换器来处理。 创建自定义类型转换器的步骤如下: 1. **定义转换器类**:继承`org.apache.struts2.util.FieldConverter`或`...

    struts-taglib-1.3.8.jar

    struts-taglib-1.3.8.jar struts-taglib-1.3.8.jar

    自定义类型转换器

    Struts2框架提供了一种灵活的方式来实现这种类型的转换——即通过自定义类型转换器(Type Converters)。本文档将详细介绍如何在Java中自定义类型转换器,并通过一个具体的例子来演示其使用方法。 #### 二、局部...

    struts2如何配置与自定义类型转换

    然而,当需要对自定义对象或者特殊的数据类型进行转换时,就需要自定义类型转换器。 **局部自定义类型转换**: 如果你只想为特定的Action中的某个字段创建类型转换器,你需要创建一个类继承自`StrutsTypeConverter`...

    struts1.38包,struts-core-1.3.8.jar

    struts1.38包,struts-core-1.3.8.jarstruts1.38包,struts-core-1.3.8.jar

    struts-1.2.9-lib.zip和struts-1.2.9-src.zip

    这里的"struts-1.2.9-lib.zip"和"struts-1.2.9-src.zip"是Struts 1.2.9版本的两个重要组件。 "struts-1.2.9-lib.zip"文件包含的是Struts 1.2.9的运行库,也就是库文件包。这个压缩包中汇集了运行Struts应用所需的...

    json-lib-2.1.jar和struts2-json-plugin-2.1.8.1.jar

    这个库支持多种Java类型,包括基本类型、集合、Map、自定义Java类等,使得JSON与Java之间的数据交互变得简单。 `struts2-json-plugin-2.1.8.1.jar` 则是Struts 2框架的一个插件,主要用于增强Struts 2对JSON的支持...

    struts-2.3.31-all.zip

    7. **类型转换**:Struts2提供了自动类型转换机制,能够将HTTP请求参数自动转换为Action类的属性。 8. **异常处理**:Struts2提供了一套全面的异常处理机制,能够优雅地处理运行时异常并生成相应的错误页面。 在...

    Struts2--自定义拦截器

    通常,你会在`struts.xml`或`struts-plugin.xml`文件中进行配置。 ```xml &lt;interceptor-stack name="myCustomStack"&gt; &lt;interceptor-ref name="defaultStack"/&gt; &lt;interceptor-ref name="myCustomInterceptor"/...

    struts-2.5.22-all.zip

    `struts-2.5.22-all`这个压缩包名称暗示了它包含了Struts2框架的所有组成部分,可能包括: 1. `struts2-core.jar`:核心框架,提供基础的MVC功能。 2. `struts2-convention-plugin.jar`:约定优于配置的插件,使得...

    struts-2.3.32-all

    10. **Plug-in机制**: Struts 2支持插件扩展,允许开发者添加自定义功能,如表单验证、数据类型转换等。 11. **OGNL (Object-Graph Navigation Language)**: Struts 2默认使用OGNL作为表达式语言,用于在Action和...

    struts-2.3.34-all.zip

    2. **配置文件**:主要包括struts.xml或struts-default.xml,用于定义Action、结果类型、拦截器栈等配置信息。 3. **拦截器(Interceptor)**:拦截器是Struts2的一大特色,它允许在Action调用前后插入自定义逻辑,...

Global site tag (gtag.js) - Google Analytics