`
wangyalei
  • 浏览: 53989 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Struts2类型转换详解

阅读更多

Struts2 一个经典的MVC 框架  他能很好的负责收集用户请求的参数 ,并将参数传给应用的控制器组件。但是所有的请求参数都是string 类型的么? 当然不是。可能是 int ,float,double,boolean,date 等java 所支持的所有数据类型,当然也可能是用户自己定义的对象类型,Struts2 提供了非常强大的类型转换机制,struts2的类型转换是基于OGNL 表达式的,开发者可以利用Struts2的类型转换机制来完成任意类型的转换.

 

 

1 平时的 web 开发 假如我们现在有一个简单的注册实例

 

用户名:改注册信息是一个String类型
密  码:同上
年  龄: int 类型
生  日: java.util.Date

 

通常的写法 写一个pojo 把 请求的参数封装中对象

public class UserBean{

private String name;
private String password;
private int age;
private Date birth;

// sttter and getter
.......

}

 页面收集到的书信息 提交到Servlet,该Servlet  将这些请求封装成UserBean 的值对象

 

 

public class Regist extends HttpServlet{
      
 public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException { 
			
	  request.setCharacterEncoding("GBK");
	   String name = request.getParameter("username");
	   String pass = request.getParameter("pass");
	   String strAge = reqeust.getParameter("birth");
	   
	   // 下面 进行类型 转换
	   // 字符串 类型 
		int age = Integer.parseInt(strAge);
		// 使用 SimpleDateFormat 将字符串 转向日期转换
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");
		Date birth = null;
		try{
			   birth = sdf.parse(strBirth);
		   }catch(Exception e){
		   
		   }
	   
		// ..................
}

  以上 是普通的类型转换,但是如果 我们需要把一个字符串 转换成一个复杂对象时,怎么转换?我们用以上的方式来做   当然也可以作,不过很麻烦 ,struts2为我们提供了这一机制,当然以上普通的类型转换 Struts2能为我们自动的转换。

Struts2的类型转换是基于OGNL的,在OGNL中有一个接口TypeConverter,这个接口就是定义类型转换的。

 

 

public interface TypeConverter{

	public Object convertValue(Map context, Object target,Member member,
				String propertyName, Object value, Class toType);

}

 实现 以上接口过与 复杂,OGNl 还提供了一个实现该接口的实现类DefaultTypeConverter 

public class DefaultTypeConverter implements TypeConverter {
    private static final String NULL_STRING = "null";

    private final Map<Class, Object> primitiveDefaults;

    public DefaultTypeConverter() {
        Map<Class, Object> map = new HashMap<Class, Object>();
        map.put(Boolean.TYPE, Boolean.FALSE);
        map.put(Byte.TYPE, Byte.valueOf((byte) 0));
        map.put(Short.TYPE, Short.valueOf((short) 0));
        map.put(Character.TYPE, new Character((char) 0));
        map.put(Integer.TYPE, Integer.valueOf(0));
        map.put(Long.TYPE, Long.valueOf(0L));
        map.put(Float.TYPE, new Float(0.0f));
        map.put(Double.TYPE, new Double(0.0));
        map.put(BigInteger.class, new BigInteger("0"));
        map.put(BigDecimal.class, new BigDecimal(0.0));
        primitiveDefaults = Collections.unmodifiableMap(map);
    }

    public Object convertValue(Map<String, Object> context, Object value, Class toType) {
        return convertValue(value, toType);
    }

    public Object convertValue(Map<String, Object> context, Object target, Member member,
            String propertyName, Object value, Class toType) {
        return convertValue(context, value, toType);
    }
			............
}

 
我们通过继承DefultTypeConverter来实现自己的类型转换器

最经典的问题———— 在 一个文本框中输入x,y坐标

自定义类型Point

 

public class Point {
    private int x;
    private int y;
    
    //省略getter and setter
}

//Struts Action:
public class PointAction extends ActionSupport {
    private Point point;
    ......
}

 

浏览器中输入:
<s:textfield name="point" label="坐标" ></s:textfield> 

  这样,从浏览器传过来point的String值,不能直接set到PointAction中的point对象中。 同时,输出point对象时,直接调用getter也是不行的。这时,就需要一个类型转换器,实现Point类与String之间的转换。

 下面 自定义类转换器 需重写DefaultTypeConverter类的convertValue方法(注意的是:name="point" point 是 Point类型在Action中的声明对象)

package com.conversion.util;


import java.util.Map;

import com.conversion.pojo.Point;

import ognl.DefaultTypeConverter;


public class PointActionConver extends DefaultTypeConverter{

	/*********
	 * @param context 是指的转换类型的上下文
	 * @param value 是一个目标类型 一般是一个数组 里面盛放的是要转换的Value
	 * @param toType 要转换成是什么类型的
	 * @return  转换后的类型值
	 */
	@Override
	public Object convertValue(Map context, Object value, Class toType) {
		// 从 string 转换为 Point类型
System.out.println("point\t"+toType);
		if (Point.class == toType) {
			Point point = new Point();
			String[] pStrings = (String[])value;
			
			String[] xString = pStrings[0].split(",");
			int x = Integer.parseInt(xString[0]);
			int y = Integer.parseInt(xString[1]);
			point.setX(x);
			point.setY(y);
			return point;
		} else if(String.class == toType){
			//从Point类型 转换为 String
 System.out.println("stirng\t"+toType);
			Point point =(Point)value;
			int x = point.getX();
			int y = point.getY();
			String result = "x"+x+"y"+y;
			return result;
		}
		
		return null;
	}

}

 页面输出

<s:property value="point"/>

 控制台输出

       point class com.conversion.pojo.Point
       stirng class java.lang.String       因为conventValue方法的负责完成数据类型转换,不过这种转换是双 向   的,当需要把字符串转换成Point 类型,是通过该方法实现, 当需要把String 类型转换成Point类型是也通过这个方法,所以我们用toType做判断

 

  在最后一步是要 指定类型转换的配置文件信息 我们可以把这个配置文件分为全局的或是局部的

  规范:

  1.       注册成局部类型转换器

在与*Action.class相同位置下提供一个ActionName-conversion.propertiesProperites,文件 key-value组成,内容如下: propertyName=类型转换器类(需要加包前缀)

  2.      注册成全局类型转换器

 为了让系统中的多个Action重复使用类型转换器类,需要把类型转换器类设置成全局类型转换器:它需要在classes  目录提供一个xwork-conversion.properties文件,内容由“复合类型=对应类型转换器”项组成,它们都需要提供完整的包前缀。

 

例如 : 上一个RegisterAction中我们要把Point 进行类型转换

配置成 局部的  PointAction-conversion.properties, 全局的是 xwork-conversion.properties

在局部中 我要 写成 point=com.conversion.util.PointActionConver

全局中   com.conversion.pojo.Point=com.conversion.util.PointActionConver

以上类型转换是基于OGNL 的DefaultTypeConverter来实现的,不论是从 String ---》对象 还是 对象------》String 都从convertValue(,,,)来实现,其逻辑不是很清晰,Struts2基于DefaultTypeConverter类提供了

StrutsTYpeConverter这个抽象类 ,我们可以继承这个抽象类 来实现类型的转换

public abstract class StrutsTypeConverter extends DefaultTypeConverter {
    public Object convertValue(Map context, Object o, Class toClass) {
        if (toClass.equals(String.class)) {
            return convertToString(context, o);
        } else if (o instanceof String[]) {
            return convertFromString(context, (String[]) o, toClass);
        } else if (o instanceof String) {
            return convertFromString(context, new String[]{(String) o}, toClass);
        } else {
            return performFallbackConversion(context, o, toClass);
        }
    }

    /**
     * Hook to perform a fallback conversion if every default options failed. By default
     * this will ask Ognl's DefaultTypeConverter (of which this class extends) to
     * perform the conversion.
     *
     * @param context
     * @param o
     * @param toClass
     * @return The fallback conversion
     */
    protected Object performFallbackConversion(Map context, Object o, Class toClass) {
        return super.convertValue(context, o, toClass);
    }


    /**
     * Converts one or more String values to the specified class.
     *
     * @param context the action context
     * @param values  the String values to be converted, such as those submitted from an HTML form
     * @param toClass the class to convert to
     * @return the converted object
     */
    public abstract Object convertFromString(Map context, String[] values, Class toClass);

    /**
     * Converts the specified object to a String.
     *
     * @param context the action context
     * @param o       the object to be converted
     * @return the converted String
     */
    public abstract String convertToString(Map context, Object o);
}

 实现这个类 我们必须实现这个类的抽象方法

当我们 把 String 类型 转换 复杂对象时 调用的是

 public abstract Object convertFromString(Map context, String[] values, Class toClass);

 当 从复杂类型 到 String 时 调用

 public abstract String convertToString(Map context, Object o);

 上面的我们可以改成 基于 StrutsTypeConverter(配置信息 都无用改)

public class PointActionConver extends StrutsTypeConverter {

	//convertFromString 从字符转换为对象
	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
		
		
		Point point = new Point();
		String[] paramString = values[0].split(",");
		int x = Integer.parseInt(paramString[0]);
		int y = Integer.parseInt(paramString[1]);
		point.setX(x);
		point.setY(y);
		return point;
	}

	//转换到字符串
	@Override
	public String convertToString(Map context, Object o) {
		
		
		Point point = (Point)o;
		int x = point.getX();
		int y = point.getY();
		String resultstring = "x="+x+"y="+y;
		return resultstring;
	}

}

 这两个方法 分别处理不同的类型转换 看起来更清晰 了 ,Struts2还提供了 关于集合类型的转换

 页面端:

<s:textfield name="point" label="坐标"></s:textfield>
<s:textfield name="point" label="坐标"></s:textfield>
 <s:textfield name="point" label="坐标"></s:textfield>

 Action :

    

public class PointAction extends ActionSupport {

	private List<Point> point;
	

	@Override
	public String execute() throws Exception {

		return SUCCESS;
	}

	


	public List<Point> getPoint() {
		return point;
	}




	public void setPoint(List<Point> point) {
		this.point = point;
	}


	
}

 

 类型转换器

public class PointActionConver extends StrutsTypeConverter {

	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
		System.out.println("11111111111111111111");
		List<Point> list = new ArrayList<Point>();
		for(String value:values){
			Point point = new Point();
			String[] paramvalueStrings = value.split(",");
			int x = Integer.parseInt(paramvalueStrings[0]);
			int y= Integer.parseInt(paramvalueStrings[1]);
			point.setX(x);
			point.setY(y);
			list.add(point);
		}
		return list;
	}

	@Override
	public String convertToString(Map context, Object o) {
		// TODO Auto-generated method stub
		System.out.println("222222222222222222222");
		List<Point> list = (List<Point>)o;
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("[");
		for(Point point:list){
			int x = point.getX();
			int y = point.getY();
			stringBuilder.append("x=").append(x).append(",y=").append(y).append("/n");
		}
		stringBuilder.append("]");
		return stringBuilder.toString();
		 
	}

}

 注意 当要转换集合类型是 配置文件信息 要添加上

 List:   Element_xxx=需要转换的类(包名+类型);

 Map:Element_xxx=复合类型 KeyProperty_xxx=name (其中nameset索引属性名)

 例如:Element_materialList=com.conversion.pojo.Point

 Struts2的类型转换时非常强大的 除了以上方法来完成 类型转换 他还提供了 注释的方法 (好了 已经很罗嗦了

 

分享到:
评论

相关推荐

    struts2的类型转换详解

    Struts2 的类型转换是其框架中的一个重要特性,它允许开发者轻松地将用户提交的字符串数据转换为应用程序所需的各类数据类型。在 MVC 框架中,用户输入的数据通常是字符串形式,而Java作为强类型语言,需要将这些...

    struts2类型转换和验证流程图

    ### Struts2类型转换与验证流程详解 #### Struts2框架概述 Struts2是一个用于构建企业级Java Web应用的强大框架。它集成了MVC设计模式,并提供了丰富的插件支持和灵活的配置选项。在Struts2中,类型转换和验证机制...

    struts2数据类型转换

    ### Struts2 数据类型转换详解 #### 一、引言 在Web开发中,特别是使用Struts2框架进行开发时,数据类型转换是一项至关重要的功能。由于Web应用程序的基础通信协议HTTP仅支持字符串形式的数据传输,因此,服务器端...

    关于Struts2的类型转换详解

    在Struts2中,类型转换是一个关键特性,它允许框架自动将用户输入的数据(通常是字符串)转换为应用程序所需的其他数据类型。本文将深入探讨Struts2的类型转换机制,以及如何利用这一特性来优化表现层的数据处理。 ...

    Struts2应用开发详解04

    在本教程中,我们将深入探讨Struts2的类型转换机制,了解其工作原理以及如何自定义类型转换。 首先,Struts2的类型转换主要由`ValueStack`和`TypeConverter`接口实现。当用户提交表单时,Struts2会将请求参数与...

    struts2 result配置详解

    Struts2 Result 配置详解 Struts2 框架中 Result 配置是一种非常重要的配置,它直接影响着应用程序的执行结果。Result 配置通常用于定义 Action 的执行结果,例如将结果.redirect 到一个新的 URL,或者将结果....

    Struts2应用开发详解03

    本教程“Struts2应用开发详解03”主要关注两个关键方面:通过Struts2.2源代码生成CHM格式的帮助文档以及类型转换的初步探讨。 首先,让我们深入理解如何通过Struts2.2的源代码生成CHM格式的帮助文档。CHM(Compiled...

    Struts2应用开发详解05

    Struts2作为一款流行的Java Web框架,其在处理表单数据和类型转换方面有着独特的机制。本篇将深入探讨Struts2的批量类型转换,帮助开发者更好地理解和利用这一功能。 在传统的Web开发中,我们经常需要对用户提交的...

    Struts2开发详解

    Struts2通过Struts2-jquery插件或JSON结果类型,支持异步更新,提供更丰富的用户体验。 总的来说,Struts2作为一个成熟的Java web框架,具有丰富的特性和良好的社区支持,为开发者提供了高效且灵活的开发工具,是...

    struts2校验器类型详解

    ### Struts2校验器类型详解 #### 一、Struts2内建校验器 在探讨Struts2校验器之前,我们首先需要了解这些校验器是如何被定义和集成到框架中的。如文中所述,Struts2的内建校验器主要位于`xwork-2.0.4.jar`压缩包中...

    struts2技术知识详解

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web应用框架,它不仅继承了Struts1的优点,还引入了许多新的特性,如拦截器机制、类型转换、文件上传下载等功能。 #### 二、Struts2的核心概念 ####...

    struts2+ajax详解pdf清晰

    在《struts2+ajax详解》这本书中,你将深入学习这两种技术的结合使用,包括配置、Action编写、Ajax请求的处理以及如何在Struts2中返回JSON数据等内容。通过阅读13 struts2.0 & ajax(1).pdf和14 struts2.0 & ajax(2)....

    Struts2框架开发详解

    OGNL在Struts2中扮演了关键角色,它不仅用于视图层的数据绑定,还在类型转换中起到了重要作用,使得开发者可以方便地处理不同类型的数据。 对于Web项目中的验证,Struts2提供了一套完整的验证框架,允许开发者定义...

    Struts2配置文件详解

    6. **类型转换(type-conversion)**:Struts2提供了一种机制,可以自动将HTTP请求参数转换为Action类的属性。通过`&lt;conversion&gt;`标签,你可以自定义类型转换规则。 除了上述核心元素,Struts2配置文件还支持许多...

    Struts2详解,Struts2与Struts1的区别

    新手必备,看完绝对思路清晰。醍醐灌顶啊! 一. Struts2介绍 1.... 数据类型转换器 11. 实现文件上传 12. Struts2的拦截器 13. 拒绝表单重复提交 四. OGNL表达式 五. Struts2中常用标签

    Struts2视频教程

    - **类型转换和验证**:Struts2支持自定义类型转换器,可以将用户输入的数据转换为所需的类型;同时还提供了一套强大的验证机制,确保用户输入的数据符合预期格式。 #### 五、Struts2实战经验 - **国际化**:通过...

    Struts2标签库详解

    ### Struts2 标签库详解 #### 一、引言 Struts2是一个流行的Java Web框架,它基于MVC架构设计,简化了Web应用程序的开发。Struts2提供了丰富的标签库来帮助开发者构建功能强大的用户界面。这些标签库不仅提高了开发...

    struts2 详解文档

    本详解文档将涵盖从Struts2的基本概念到高级特性的详细说明。 1. **Struts2介绍**:Struts2是Apache软件基金会的开源项目,它继承了Struts1的优点,并引入了许多新特性,如OGNL(Object-Graph Navigation Language...

    struts2标签详解与实例

    Struts2标签详解与实例 在Java Web开发中,Struts2框架因其强大的MVC(模型-视图-控制器)架构而备受青睐。Struts2提供了丰富的标签库,简化了视图层的开发,使开发者可以更加专注于业务逻辑。本文将深入探讨Struts...

Global site tag (gtag.js) - Google Analytics