`
callmegod
  • 浏览: 110265 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类
最新评论

struts2 类型转换

 
阅读更多

类型转换
在网页上传输的数据均是以String类型来传输的,而当我们对这些数据进行处理的时候。不可能都是使用String,这就需要用到类型转换,struts2提供了非常强大的类型机制,首先,对于将String转换为int等简单类型,struts2已经提供,不需要我们再作任何的考虑了。struts2甚至提供了从String转换到Date这样的对象类型的类型转换。而如果我们有一些自己定义的对象,期望我们的数据能由String转换到这些数据类型,那么,我们也可以自己定义如何从String转换到我们的自定义数据类型,下面我们就通过一个例子,来说明如何利用struts2来完成从String到我们自己定义的数据类型的转换。
在这里,我们的自定义类叫Point,它就是一个包括一个点的x和y坐标的类(其实没什么实际意义,只是用于演示如何完成将网页的String类型转换为一个自定义的类型)。另外,我们还会同时演示一下,struts2能自动将String转换为int类型,自动将String类型转换为Date类型。
我们继续使用在前两讲使用的工程,只是新建一些网页,添加配置信息而已。
第一步,我们新建一个网页,这个网页叫做input.jsp,里面的代码如下:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
  
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <s:form action="pointConverter">
            <s:textfield name="point" label="点坐标" />
            <s:textfield name="age" label="年龄" />
            <s:textfield name="username" label="姓名" />
            <s:textfield name="birthday" label="日期" />
            <s:submit value="提交" />
       </s:form>
    </body>
</html>
从上面的代码我们可以看出,我们仍然使用了struts2的标签。这里一共有四个文本框:
<s:textfield name="point" label="点坐标" />
<s:textfield name="age" label="年龄" />
<s:textfield name="username" label="姓名" />
<s:textfield name="date" label="日期" />
第一个文本框叫point,它将对应我们的Point类(如何对应?别着急,耐心往下看),第二个叫age,它将对应一个int类型,第三个文本框叫username,它对应String类型,当然,这个文本框是不需要类型转换的。第四个叫date,它对应java.util.Date类型。
而表单的action属性赋值为pointConverter,也在说明,我们将在struts2.xml文件中添加一个新的<action>标记,而这个<action>标记的name属性将为pointConverter(注意大小写)。
我们先放一放struts2.xml,先说说神秘的类型转换如何进行?别着急,我们还没有写我们的Point类呢。所以,第二步,我们在src目录中新建一个包(右击src目录,选择new-package),包名叫com.speakmore.struts2test.bean,然后在这个包里new一个class (右击刚刚新建的包,选择new-class),它的名字就叫Point,下面是它的代码:
package com.speakmore.struts2test.bean;
public class Point {
    private int x;
    private int y;
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    @Override
    public String toString() {
        return "[x="+x+",y="+y+"]";
    }
   
}
大家可以看到,这个Point有两个私有属性x和y,有二个set方法,还有二个get方法。另外还写了一个toString方法,里面只是返回一个字符串,没什么特别的意义。这个方法将会在我们后面的代码中用到,到时我再做详细的说明。
第三步,完成struts2.xml的配置。代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="struts2" extends="struts-default">
        <action name="login" class="com.speakmore.struts2test.action.LoginAction">
            <result name="input">/login2.jsp</result>
            <result name="success">/result.jsp</result>
            <result name="failer">/login2.jsp</result>
        </action>
        <action name="pointConverter" class="com.speakmore.struts2test.action.PointAction">
            <result name="success">/output.jsp</result>
        </action>
    </package>
</struts>
这里我还是写出了全部代码,重要的是下面一段:
        <action name="pointConverter" class="com.speakmore.struts2test.action.PointAction">
            <result name="success">/output.jsp</result>
        </action>
这是新添加的<action>标签,如上面已经提到过的,它的name属性赋值为pointConverter,与input.jsp里的表单action属性对应,class属性说明我们的input.jsp里的数据将提交给com.speakmore.struts2test.action.PointAction类的一个对象,当这个对象处理完数据之后,如果返回success,则由<result>标记说明把页面转到output.jsp。
好的,下面我们接着来新建类PointAction。
由于com.speakmore.struts2test.action包我们在前二讲中已经建好,所以,直接右击这个包,然后选择new-class,填上类名:PointAction即可。它的代码如下:
package com.speakmore.struts2test.action;
import com.opensymphony.xwork2.ActionSupport;
import com.speakmore.struts2test.bean.Point;
import java.util.Date;
/**
*
* @author mouyong
*/
public class PointAction extends ActionSupport {
    private Point point;
    private int age;
    private String username;
    private Date birthday;
    public Point getPoint() {
        return point;
    }
    public void setPoint(Point point) {
        this.point = point;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = date;
    }
    @Override
    public String execute() throws Exception {
        return this.SUCCESS;
    }
   
}
在代码中,我们可以看到,这个类导入了两个类,一个是前面已经提到过的com.opensymphony.xwork2.ActionSupport,另一个就是我们刚刚建立的com.speakmore.struts2test.bean.Point。ActionSupport类是struts2提供的一个用于定义action处理的类,我们继承了它,这样可以获得Struts2所提供的功能(比如一会儿就要讲到的类型转换)。而Point类就是我们刚刚写的那个Point类,它用来存放我们将在文本框中输入的x和y坐标。
第四步,我们要写一个类:PointConverter。这个类的作用就是用来完成String到Point的转换,还有Point到String的转换。代码如下:
package com.speakmore.struts2test.converter;
import java.util.Map;
import com.speakmore.struts2.bean.Point;
import ognl.DefaultTypeConverter;
public class PointConverter extends DefaultTypeConverter {
         @Override
         public Object convertValue(Map context, Object value, Class toType) {
                   if(Point.class==toType){
                            //如果toType不是String,那就说明数据是从客户端送到服务器端。
                            Point p=new Point();
                            //由于value是通过request.getParameterValues()方法获得的,所以它是一个数组
String[] str=(String[])value;
                            String[] valueParam=str[0].split(",");
                           
                            p.setX(Integer.parseInt(valueParam[0]));
                            p.setY(Integer.parseInt(valueParam[0]));
                           
                            return p;
                   }
                  
                   if(String.class==toType){
                            //如果toType是String,则说明数据是从服务器端到客户端
                            Point p=(Point)value;//此时的value一定是我们需要的对象
                            return p.toString();
                   }
                   return null;
         }
}
这里作点解释。首先,PointConverter类继承了DefaultTypeConverter:
public class PointConverter extends DefaultTypeConverter
DefaultTypeConverter也就是struts2规定的一个默认类型转换器,如果我们要做一些特别的类型转换,那么我们就要写一个继承自DefaultTypeConverter的类。
它有一个方法:convertValue是需要我们重写的,里面的代码就是完成从String到自定义类型的转换以及从自定义类型到String的转换(这是因为在我们的网络上,由客户端传过来的数据都是String类型的,而服务器如果要做一些运算,就需要其它的类型(如int,float等基本类型或者别的引用类型),所以,归纳之后,当客户端的数据送来时,我们需要的转换就是String到其他类型,而如果是服务器向客户端发送数据时,我们需要的转换就是其他类型到String)。
@Override
         public Object convertValue(Map context, Object value, Class toType) {
                   if(Point.class==toType){
                            //如果toType不是String,那就说明数据是从客户端送到服务器端。
                            Point p=new Point();
                            //由于value是通过request.getParameterValues()方法获得的,所以它是一个数组
String[] str=(String[])value;
                            String[] valueParam=str[0].split(",");
                           
                            p.setX(Integer.parseInt(valueParam[0]));
                            p.setY(Integer.parseInt(valueParam[0]));
                           
                            return p;
                   }
                  
                   if(String.class==toType){
                            //如果toType是String,则说明数据是从服务器端到客户端
                            Point p=(Point)value;//此时的value一定是我们需要的对象
                            return p.toString();
                   }
                   return null;
         }
关于convertValue方法的参数,第一个不作说明了(目前我也不知道它有什么用),第三个参数是说明我们需要转换的类型是什么,第二个参数是Object,它是将被转换的数据。之所以定为Object,是由于被转换的数据与第三个参数密切相关。如果第三个参数不是String,那说明数据是从客户端送到服务器端,此时第二个参数就是一个通过request.getParameterValues()方法获得的String数组。所以有了我们的第一个if语句:
if(Point.class==toType){
                            //如果toType不是String,那就说明数据是从客户端送到服务器端。
                            Point p=new Point();
                            //由于value是通过request.getParameterValues()方法获得的,所以它是一个数组
String[] str=(String[])value;
//str的第一个值就是我们需要转换的点坐标值
                            String[] valueParam=str[0].split(",");
                           
                            p.setX(Integer.parseInt(valueParam[0]));
                            p.setY(Integer.parseInt(valueParam[1]));
                           
                            return p;
                   }
如果第三个参数是String,那说明我们的第二个参数是一个需要转换为String的对象。它是要发送到客户端去进行显示的。于是就有了我们的第二个if语句:
if(String.class==toType){
                            //如果toType是String,则说明数据是从服务器端到客户端
                            Point p=(Point)value;//此时的value一定是我们需要的对象
                            return p.toString();
                  }
在这里大家看到了p.toString(),这是我们常常采用的解决方案:如果一个对象需要转换成String,那就重写这个对象的toString()方法,在toString()方法中定义一个适当的,能表达此对象的String(怎么定?想怎么定就怎么定,决定权在于你自己!)。
接着我们来完成第五步:在PointAcion类所在的包下面写一个属性文件(右击com.speakmor.struts2test.converter包,新建一个file,取名叫PointAction-conversion.properties),由它来说明我们的PointAction类中的哪个属性需要进行转换,由谁进行转换。下面是它的代码:
#属性文件名说明:
#PointAction部分就是需要类型转换的Action类的类名。
#对哪个类里的属性要进行类型转换就用哪个类的类名作为属性文件的开头
#-conversion.properties是固定不变的
#属性写法说明
#等号左边说明要对哪个属性进行类型转换
#等号右边说明用哪个类进行类型转换
point=com.speakmore. struts2test.converter.PointConverter
OK!我们还差最后一个文件:output.jsp。全部代码如下:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
   
</head>
<body>
    点坐标:<s:property value="point"/><!-- value就是action里定义的属性,与get方法或set方法匹配 -->
    年 龄:<s:property value="age"/>
    姓 名:<s:property value="username"/>
    生 日:<s:property value="birthday"/>
</body>
</html>
这段代码并不是很复杂,我暂时不做很多解释了。
现在大家可以尝试运行一下这个程序,在input.jsp页面的“点坐标”文本框中填入20,30(注意中间是一个逗号,这样才能和我们的PointConverter类中的str[0].split(,)匹配!),其它文本框按正常的输入方式进行输入(注意只能输正确的值哦!)看一看类型转换是否可以成功?
好的,如果你调试总是不成功,你可以和我联系(QQ或者是留),记得收集你的错误信息,以便我能判断你错在哪里(记得看医生是要带病历的哦,你都不告诉医生你的症状,只说你病了,医生是不可能知道你得了什么病的)。
在本讲的最后一部分,我给大家说一说整个程序运行的流程(如果有说错的地方,希望大家批评指正!):
首先我们看到的页面应该是input.jsp,它有四个文本框,分别是point,age,username,date代码如下:
<s:form action="pointConverter">
            <s:textfield name="point" label="点坐标" />
            <s:textfield name="age" label="年龄" />
            <s:textfield name="username" label="姓名" />
            <s:textfield name="birthday" label="日期" />
            <s:submit value="提交" />
        </s:form>
现在我们在第一个文本框(point)中填入“20,30”,第二个文本框(age)中填入“30”,第三个文本框(username)中填入“张三”,第四个文本框(birthday)中填入“1973-9-1”之后,点击“提交”按钮时,struts2会根据struts.xml中的定义:
<action name="pointConverter" class="com.speakmore.struts2test.action.PointAction">
            <result name="success">/output.jsp</result>
        </action>
将input.jsp中的表单数据提交给PointAction类。其中point(字符串“20,30”)调用setPoint()方法,将数据交给Point类型的对象point,这时问题来了,在PointAction中的point是一个Point类型的,如何将字符串“20,30”交给Point呢?这时我们的属性文件(PointAction-conversion.properties)起作用了,它说明了有一个叫做PointConverter的类可以完成String到Point的转换。于是struts2启动了PointConverter类,调用了它的一个方法convertValue()。这个方法如下:
public Object convertValue(Map context, Object value, Class toType) {
此时,第三个参数toType是Point,而第二个参数是由request.getParameterValues(“point”)获得的一个数组。于是,我们知道,这个方法中的第一个if语句将起作用:
if(Point.class==toType){
于是,我们做的第一件事情就是new一个Point类:
Point p=new Point();
再之后,我们将第二个参数还原为String数组:
String[] str=(String[])value;
我们定义的Point类其实就是一个存坐标的类,它有两个属性,一个是x,另一个是y,而我们填在“point”文本框中的值是“20,30”,注意我们使用了逗号进行分隔。于是就有了以下几句代码:
String[] valueParam=str[0].split(",");
                           
                            p.setX(Integer.parseInt(valueParam[0]));
                            p.setY(Integer.parseInt(valueParam[1]));
其中str[0]的意思就是“取出第一个point文本框的值:字符串’20,30’(其实这里就只有一个,但struts2使用了数组,所以我们必须使用下标0来取出第一个)”,split(“,”)的意思就是“以逗号作为分隔符,将point文本框的值分成多个字符串”(这里是两个字符串,一个是20,另一个是30)。之后的两句就是对这两个字符串进行转换,调用setX()和setY()方法,将20存入x中,30存入y中。
最后,返回p:
return p;
这个p就会传给PointAction的setPoint方法,作为它的参数。于是,字符串“20,30”就成功转换成了Point类型(其实就是分隔字符串,把20给x坐标,30给y坐标,把它们都封装在Point里面)。
第二个文本框(age)的值是字符串“30”,它会调用PointAction类的setAge()方法,这时问题又来了,setAge()方法的参数是一个int,如何完成类型转换呢?别着急,struts2会自动完成这个类型转换不用我们插手的。
第三个文本框(username)的值是字符串“张三”,它会调用setUsername()方法,这个方法的参数就是字符串,所以struts2直接将值就给它了,并不进行转换。
第四个文本框(birthday)的值是字符串“1973-9-1”,它会调用setBirthday()方法,这个方法的参数是java.util.Date,同样,struts2也能自动完成字符串到Date类型的转换,不需要我们操心的。
当四个文本框填充完成之后,struts2调用了PointAction类的execute()方法,如下:
public String execute() throws Exception {
        return this.SUCCESS;
    }
这个方法没做什么事情,只是返回了一个常量:SUCCESS,这个常量其实就是字符串“success”,于是struts2又根据struts.xml文件中的以下代码:
<result name="success">/output.jsp</result>
将页面转到了output.jsp。关键代码如下:
点坐标:<s:property value="point"/>
    年 龄:<s:property value="age"/>
    姓 名:<s:property value="username"/>
    生 日:<s:property value="birthday"/>
这里我们首先看到的是:
<s:property value="point"/>
这一句代码的意思其实就是“从PointAction中将point送到客户端显示”,于是struts2就调用了PointAction的getPoint()方法,获得了Point类型的值。可是客户端要的是一个字符串,并不是Point。不要紧,struts2再次根据属性文件(PointAction-conversion.properties)的说明,调用了PointConverter类的convertValue()方法。这一次struts2赋给convertValue()的第三个参数将会是String(客户端需要String),而赋给convertValue()方法第二个参数将是getPoint()方法返回的Point对象。于是convertValue()方法的第二个if语句起作用了:
if(String.class==toType)
我们做的第一件事,就是把第二个参数(value)转换为Point
Point p=(Point)value;
然后返回p的字符串形式。
return p.toString();
这里就会返回字符串“[x=20,y=30]”。这个字符串将在客户端的页面上看到。
output.jsp的第二句是:
<s:property value="age"/>
struts2自动调用了PointAction的getAge()方法,获得int类型的数据,并自动转换为字符串“30”,在客户端显示出来。
第三句是:
<s:property value="username"/>
struts2自动调用了PointAction的getUsername(),获得String类型的数据“张三”,直接送往客户端显示。
最后一句是:
<s:property value="birthday"/>
struts2自动调用了PointAction的getDate(),获得了Date类型的数据,经过自动类型转换为字符串“73-9-1”在客户端显示出来。
综上所述,struts2可以帮助我们完成绝大多数的类型转换,并不需要我们操太多的心(当然,我们输入的数据格式必须符合相关规定)。如果我们需要进行一些特定的类型转换,我们只需要写一个继承自DefaultTypeConverter的类,重写convertValue()方法,定义如何完成从特定类型转换到字符串的过程以及如何从数字串转换到特定类型的过程(两个if语句),之后再写了一个叫做XXXAction-conversion.properties的文件,在里面说明谁要进行类型转换,谁来完成这个完换。然后把它与XXXAction类文件放在一起就可以了
分享到:
评论

相关推荐

    STRUTS2类型转换

    Struts2是一个流行的Java web开发框架,其核心是Action,而类型转换是Struts2处理用户输入数据的一个重要环节。Struts2内置了多种类型转换,可以将HTTP请求中的字符串数据转换为各种基本类型和复杂类型,如日期、...

    struts2 类型转换器

    在Struts2中,类型转换器(Type Converter)是框架的一个关键特性,用于处理Action类中属性的自动类型转换。这个特性使得开发者无需手动进行数据类型之间的转换,从而提高了开发效率和代码的可读性。 标题中的...

    struts2类型转换

    本篇文章将深入探讨Struts2中的类型转换机制。 1. **类型转换的概念** 类型转换是指将一个数据类型的值转换为另一个数据类型的过程。在网络请求中,用户输入的数据通常是字符串类型,而服务器端的Action类属性可能...

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

    Struts2是一个强大的MVC框架,它在处理Web应用程序时提供了许多便利,其中包括类型转换功能。类型转换是将用户输入的数据自动转化为服务器端处理所需的类型,这样可以避免手动转换带来的繁琐工作。本篇文章将深入...

    struts2类型转换和国际化

    在Struts2中,类型转换和国际化是两个重要的特性,用于处理数据类型之间的转换以及多语言环境下的内容显示。 **类型转换**是Struts2处理请求参数与Action类属性之间数据类型不匹配的过程。当用户通过表单提交请求时...

    struts2类型转换深入总结

    Struts2提供了一些工具类和方法来辅助类型转换,比如`FieldError`用于记录转换失败的字段和错误信息,`ValueStack`提供了`convertValue`方法进行转换,以及`ActionContext`中的`getValueStack`方法获取当前栈顶的`...

    struts2类型转换和验证流程图

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

    struts2简单实例(类型转换)

    在这个"struts2简单实例(类型转换)"中,我们将探讨Struts2如何处理不同类型的数据转换,以及如何创建一个简单的演示应用。 首先,让我们理解什么是类型转换。在Web应用程序中,用户通过表单提交的数据通常是字符...

    struts2类型转换 拦截器 校验的例子

    Struts2是一个强大的Java web框架,它为开发者提供了丰富的功能,包括类型转换、拦截器和校验机制。本文将深入探讨这些关键知识点,并通过实际例子来帮助你理解它们的工作原理和应用。 首先,我们来看看**类型转换...

    struts2类型转换机制

    struts2类型转换机制

    struts2学习笔记3数据类型转换

    struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换

    Struts2类型转换与输入校验 .zip

     熟悉和掌握Struts2自定义类型转换。  熟悉和掌握Struts2内建校验的操作方法  实验环境与设备:  已经接入局域网的网络实验室,机器上装有IE浏览器等;  strtus2.5.8  实验内容: (1) 编写一个...

    Struts2 ConverterType类型转换 案例源码

    Struts2是一个强大的MVC框架,它在处理用户请求时提供了丰富的功能,其中包括类型转换(Converter)。类型转换是Struts2框架中一个重要的特性,它允许我们把前端表单提交的数据自动转换为后端Java对象的属性。在这个...

    struts2 类型转换 数据校验

    2. **自定义转换器**:如果需要处理特殊类型或有特定转换规则,可以通过实现`org.apache.struts2.util.TypeConverter`接口创建自定义转换器,并通过`@Result`注解或者`struts.xml`配置文件进行注册。 3. **转换异常*...

    STRUTS2类型转换错误导致OGNL表达式注入漏洞分析1

    《STRUTS2类型转换错误导致OGNL表达式注入漏洞分析》 STRUTS2框架在处理用户输入时出现的类型转换错误,可能导致OGNL(Object-Graph Navigation Language)表达式注入漏洞。此漏洞允许攻击者通过精心构造的输入,...

    [原]Struts2类型转换

    在Struts2中,类型转换是一项关键功能,它允许框架将用户输入的数据自动转换为应用程序需要的特定数据类型。这篇博客文章可能是关于Struts2内部的类型转换机制及其使用的探讨。 在Struts2中,类型转换是通过`...

Global site tag (gtag.js) - Google Analytics