struts2类型转换
实验报告3 (2)
![实验报告3 (2)](https://img.taocdn.com/s3/m/55e9fb1c79563c1ec5da716d.png)
实验2 Struts2类型转换(2学时)题目/任务1.掌握基于OGNL的类型转换。
2.掌握基于OGNL表达式对于Map集合的转换。
难度系数知识点说明/训练要点1.基于OGNL的类型转换。
2.基于OGNL表达式对于Map集合的转换。
实现效果1、运行结果:a)基于OGNL的类型转换:b)基于OGNL表达式对于Map集合的转换实现步骤1、搭建环境。
◆将当前目录下,环境工程包内StrutsDemo20文件导入到eclipse中。
2、进行实验。
在edu.zb.entity包下有一个User实体类,User里有userName、password、age属性。
并且已添加set、get方法以及有参和无参的构造方法,并且重写了toString()方法。
◆基于OGNL的类型转换:●打开edu.zb.action包下的loginAction类,添加一个User类型的user属性。
并添加set、get方法。
●打开WebContent目录下的login.jsp页面,将第一个“<s:textfield>”标签里的name和id属性改为“erName”。
●将第二个“<s:textfield>”标签里的的name和id属性改为“user.age”。
●将“<s:password>”标签里的name和id属性改为“user.password”。
●打开WebContent目录下的index.jsp页面,在body使用ValueStack对象实现获取引用的过程:调用request的getAttritube(“struts.valueStack”)方法,返回ValueStack类型的对象,命名为vs,然后跳跃vs的findString(“user”)方法获得user的相关属性值。
实际代码如下所示:●在第一行里page属性后面添加对相关类的导入。
如下所示:●运行login.jsp,在login、年龄、pass文本框内分别输入”admin”、“20“、”123456 “。
类型转换中的异常处理及资源国际化教学内容
![类型转换中的异常处理及资源国际化教学内容](https://img.taocdn.com/s3/m/c4d52a1084868762cbaed540.png)
类型转换中的异常处理及资源国际化Struts2的类型转换异常处理在视图页面中,用户的输入是很复杂的,偶然的输入错误或者恶意输入都会导致程序异常。
因此,必须对用户输入的数据进行校验。
例如,年龄信息必须是整数,一但用户输入了一个ABC,这时就需要进行数据类型校验。
Struts 2.0提供了类型转换异常处理机制,使用的是一个名字为conversionError的拦截器,这个拦截器被注册在默认的拦截器栈中。
如果Struts 2.0在类型转换过程中出现问题,这个拦截器就会进行拦截,并将异常信息封装成一个fieldError对象在视图页面上显示出来。
整个过程无须我们参与,Struts 2.0的类型转换器和conversionError拦截器会自动实现。
(一)简单类型转换异常主要是处理一些String、int、Date等数据类型之间的转换异常。
见例子“convError”,一个用户注册的功能:(1)Action的代码:package conv;import com.opensymphony.xwork2.ActionSupport;public class userAction extends ActionSupport{private String name;private int age;public String getName() {return name;}public void setName(String name) { = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String addUser(){return SUCCESS;}}从上述代码中我们可以看到该Action仅,包含了name和age两个属性,其中age属性是int类型的。
(2)strust.xml配置文件代码:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration2.0//EN""/dtds/struts-2.0.dtd"><struts><constant name="struts.enable.DynamicMethodInvocation"value="false" /><constant name="struts.devMode" value="false" /><package name="Struts2.0_AddBook" extends="struts-default"> <action name="addUser" class="erAction"method="addUser"><result name="input">index.jsp</result></action></package></struts>在这个配置文件中的package包,继承了struts-default.xml文件,而struts-default.xml文件定义了Struts 2.0内建的拦截器,其中就包括我们上面提到的conversionError拦截器。
Struts 2 的世界-第三章 struts2的类型转换
![Struts 2 的世界-第三章 struts2的类型转换](https://img.taocdn.com/s3/m/44a96a05cc17552707220853.png)
《开始Struts 2》第三章struts2的类型转换序所有的MVC框架,都是属于表现层的解决方案,都需要负责收集用户请求参数,并将请求参数传给应用的控制器组件。
此时问题出现了,所有的请求参数都是,也只能是字符串数据类型,但Java是强类型的语言,因此MVC框架必须将这些字符串请求参数转换成相应的数据类型——这个工作是所有的MVC框架都应该提供的功能。
Struts 2提供了非常强大的类型转换机制,Struts 2的类型转换是基于OGNL表达式的,只要我们把HTML输入项(表单元素和其他GET/POST的参数)命名为合法的OGNL表达式,就可以充分利用Struts 2的类型转换机制。
除此之外,Stints 2提供了很好的扩展性,开发者可以非常简单地开发出自己的类型转换器,完成字符串和自定义复合类型之间的转化(例如,完成字符串到Person实例的转换),如果类型转换中出现未知异常,类型转换器开发者无需关心异常处理逻辑,Struts 2的conversionError拦截器会自动处理该异常,并且提示在页面上生成提示信息。
总之,Struts2的类型转换器提供了非常强大的表现层数据处理机制,开发者可以利用Struts 2的类型转换机制来完成任意的类型转换。
自动型转换器在struts1.x中只能简单的进行String和基本数据类型的转换,但Struts2支持多种类型的自动转换:XWork will automatically handle the most common type conversion for you. This includes support forconverting to and from Strings for each of the following:∙String∙boolean / Boolean∙char / Character∙int / Integer, float / Float, long / Long, double / Double∙dates - uses the SHORT format for the Locale associated with the current request∙arrays - assuming the individual strings can be coverted to the individual items∙collections - if not object type can be determined, it is assumed to be a String and a new ArrayList is createdNote that with arrays the type conversion will defer to the type of the array elements and try to convert each item individually. As with any other type conversion, if the conversion can't be performed the standard type conversion error reporting is used to indicate a problem occured while processing the type conversion.∙Enumerations∙BigDecimal and BigInteger例子:注册实例:运行结果:可以看出,struts对多种类型的转换可以应付自如,但这种准换要依据的原则:◆表单name值要和action中的属性值名称一样◆Action中的属性要有Set方法使用类型转换器当需要把一个字符串转换成一个复杂对象时,类型转换器就可以发挥强大的作用了。
Struts2教程02
![Struts2教程02](https://img.taocdn.com/s3/m/47f9877101f69e31433294fa.png)
注:上面的两个方法都必须重写.
自定义类型转换器
5
自定义类型转换器--示例:转换成int[] 自定义类型转换器--示例:转换成int[]
6
注册自定义类型转换器有两种方法
局部类型转换器:只有特定的Action才可以使用
注册方法:在Action所在的包中建立properties文件,文件 名格式:Action类名-conversion.properties,内容如下: inver=com.aptech.conversition.IntArrayConverter 其中:inver是action属性名,
注:验证文件要和Action类放在同一包中
使用struts2验证框架我们应该做什么? 使用struts2验证框架我们应该做什么?
12
两个方面
DOCTYPE
从xwork-core-2.1.6.jar中可以找到
验证内容
查看doc文档,有详尽的说明和示范
验证文件怎么写? 验证文件怎么写?
13
输入员工信息应该遵循下面的规范
boolean,char,int,long,float,double基础类型,包括 封装类型和对应数组. Date,String数组,元素类型为String的List
Struts2类型转换 Struts2类型转换
4
类型转换器是一个继承自StrutsTypeConverter (抽象类)的类,必须重写两个方法:
public Object convertFromString(Map context, String[] values, Class toClass)
从字符串转换成目标类型
public String convertToString(Map context, Object o)
struts2学习笔记2
![struts2学习笔记2](https://img.taocdn.com/s3/m/9e497fc9524de518964b7dbb.png)
Struts学习1.2一、类型转换a)可以继承DefaultTypeConverter或StrutsTypeConverter类,也可以直接实现TypeConverter接口b)直接实现TypeConverter接口(这里不对该方法进行着重理解)i.需要重写下面的方法convertValue(Map<String,Object> context, Object target, Member member, StringpropertyName, Object value, Class toType)c)继承DefaultTypeConverter类i.需要重写下面的方法convertValue(Map<String,Object> context, Object value, Class toType) ii.该方法的返回值就是Action类中的属性的值iii.参数value---String[]要转化的值,该值是字符串类型的数组,strus2底层用request.getParameterValues("属性名")iv.参数toType要转化的数据类型,这里是java.util.Date.class类型d)实现思路i.在上面的方法中判断value是否为空,并且length是否大于0,如果两个条件都满足,如果两者有一个不满足就返回nullii.再判断toType是否为空,如果为空则返回null,如果不为空,则要判断一下是否是我们要转换的类型(toType!=java.util.Date.class)如果不是,则返回nulliii.如果上面两个值都不为空,并且length也大于0,则开始判断value是否是String[](value instanceof String[])如果这个条件为true,我们再执行iv.遍历value字符串数组,开始我们的转换v.最后需要编写一个properties资源文件,该文件放置到和当前Action同一个包下,内容是:Key Value要转换的目标类型当前转换器所在的完整类路径二、文件上传a)首先我们知道Struts2中是利用apache上传组件来完成的文件上传功能,Struts2对该组件又进行了一次封装,所以用起来更加灵活,方便,简单b)主要的三个字段(提供getter和setter方法):i.[File Name]:File类型,通常是HTML页面中input的name属性的值,保存上传的临时目录下的文件---------File - the actual Fileii.[File Name]ContentType:String类型,必须是HTML页面中input的name属性的值+ContentType,保存了上传文件的类型---------String - the content type ofthe fileiii.[File Name]FileName:String类型,通常是HTML页面中的input的name属性的值+FileName,保存了上传文件的真实名称---------String - the actual name ofthe file uploaded (not the HTML name)c)有了以上的三个段,我们可以用ServletContext对象获取上传文件保存的目录i.ServletContext realPath =ServletActionContext.getServletContext().getRealPath("/upload");ii.通常apache上传组件中的IO包里的FileUtils工具类,利用该类下的copyFile()方法,我们可以将临时文件复制到实际目录下iii.copyFile(File srcFile, File destFile)该方法有两个参数,参数一:源文件,我们这里是三个主要字段的第一个FileName;参数二:该参数要一个File对象,我们可以这样写(new File(realPath ,[File Name]FileName))里面的第一个参数是要保存文件的目录,我们通过ServletContext获取到的,第二个参数是三个主要字段的第三个(真实的文件名称)d)最后上传成功后,再将保存的临时文件夹下的临时文件删除掉i.代码:[File Name].delete();e)配置Struts.xmli.在Action中要配置两个结果:<result name="success">/upload/success.jsp</result><result name="input">/upload/error.jsp</result> ii.其中第一行,表示程序运行成功时,转到success.jsp;第二行表示程序运行失败时,转到error.jspiii.更改临时文件的存放目录<constant name="struts.multipart.saveDir"value="D:/temp"></constant>iv.配置上传文件的总开关,这里的配置对当前web应用的所有的上传都有效,默认上传大小是2M<constant name="struts.multipart.maxSize"value="222097152"></constant>v.以上的配置是对全局生效的方式,以下来看一下对局部生效的方式:f)更改文件上传失败的提示:Key Valuestruts.messages.error.uploading 上传失败: {0}rge 文件太大: {0} "{1}" "{2}" {3}struts.messages.error.content.type.not.allowed 内容类型不允许: {0} "{1}" "{2}"{3}struts.messages.error.file.extension.not.allowed 扩展名不允许: {0} "{1}" "{2}" {3} 三、自定义拦截器a)要定义自定义拦截器,需要实现Interceptor接口,重写里面的三个方法,三个方法分别为:init()、intercept(ActionInvocation invocation)、destroy()这三个方法代表了拦截器的生命周期b)参数ActionInvocation: 代表一个给定动作的执行状态, 拦截器可以从该类的对象里获得与该动作相关联的Action对象和Result对象,在完成拦截器自己的任务之后,拦截器将调用ActionInvocation对象的invoke方法前进到Action处理流程的下一个环节 ActionInvocation:封装了程序运行上下文信息,[action result...]c)如:获取一些上下文的信息i.获取当前Action名称:invocation.getProxy().getActionName()ii.获取命名空间:invocation.getProxy().getNamespace()iii.获取当前方法:invocation.getProxy().getMethod()iv.获取代理对象:invocation.getProxy()d)在Struts.xml中配置拦截器i.在对应的包下申明一个<interceptors></interceptors>ii.在上面的<interceptors>标签内添加:<!--name属性:自定义拦截器的唯一名称--><interceptor name="limit" class="自定义拦截器完整类路径" /><!--name属性:自定义拦截器栈的唯一名称--><interceptor-stack name="limitStack"><!--name属性:把默认栈添加到自定义栈中--><interceptor-ref name="defaultStack"/><!--name属性:把自定义拦截器添加到自定义栈中--><interceptor-ref name="limit"/></interceptor-stack>iii.在<interceptors>标签后添加引用:<default-interceptor-ref name="limitStack"/>四、表单验证a)代码方式进行表单验证i.要利用Struts2中的内部机制来完成表单验证,需要在当前访问的Action类中重写validate()方法ii.在该方法中对需要验证的字段进行判断,如果不符合条件,则使用this关键字,调用addFieldError()方法,该方法有两个参数,第一个添加进去的字段名,用于在JSP或其它地方取值,第二个参数要一个字符串类型的提示语。
03Struts2类型转换.ppt
![03Struts2类型转换.ppt](https://img.taocdn.com/s3/m/77b835d6eff9aef8951e065a.png)
ProductsStrutsConverter2.java
converterFromString
• 使用arg2来 判断是处理 List还是处 理数组
convertToString方法
xwork-conversion.properties
struts.xml
观察结果
• 寻找错误,并进行修改 • 第一个发现错误期末考试加分5
局部类型转换 vs 全局类型转换
• 注册全局变量的文件
– xwork-conversion.properties
• 放置如右图位置
– 该文件内容:
• 属性类名 = 转换器类
• 注册完成后,与前所示局部类型转换效果相同
Struts提供StrutsTypeConverter
• 该类,有两个主要抽象方法:
• 对应结果:
两个以上信息输入的处理
• 修改product.jsp如右:
• 修改product.jsp代码如下:
修改productdetail.jsp
• 代码如下
修改ProductActin.java
• 代码如下:
修改ProductAction-conversion.properties
• 修改如下:
配置struts.xml
• 在包中增加如下代码:
类型转换器
• 基于OGNL实现
– 提供了ognl.TypeConverter接口
• 所有类型转换器必须实现该接口
– TypeConverter接口的默认实现类 DefaultTypeConverter
• 通过继承该类,也可以实现类型转换 • 在DefaultTypeConverter中一般只需覆盖convertValue
第3章 类型转换
![第3章 类型转换](https://img.taocdn.com/s3/m/e231281efc4ffe473368ab59.png)
3.1.2 简单的类型转换示例
• 这个示例通过用户输入页来接受用户输入姓名、年龄、注 册日期,然后将用户输入页提交到相应的Action进行处理, 最后再通过输出页输出用户的输入信息。 • 步骤如下。
3.2 Struts 2内建的类型转换器
• Sturts 2为常用的数据类型提供了内建的类型转 换器,所以根本不用自定义转换器。对于内建的 转换器,Struts在遇到这些类型时,会自动去调 用相应的转换器进行类型转换。下面来看Struts 2提供了哪些内建的类型转换器,以及这些内建类 型转换器的使用。
3.2.5 集合类型转换器
• 上面介绍的是通过字符串数组来接受参数值,同 样也可以通过集合类型来接受参数值。Struts 2 提供的集合类型转换器,会将参数值自动赋值到 集合类型属性中。
3.3 OGNL表达式语言
• Struts 2已经实现了一些常用的类型转换器,但 是这些类型转换器毕竟还是有限的。如果是开发 者自己定义的数据类型,就必须自定义类型转换 器来进行转换。在Struts 2中自定义类型转化器 是非常方便和简单。因为Struts 2的类型转换是 基于OGNL来实现的,所以在介绍自定义类型转换 器之前先简单介绍OGNL。
•
3.3.2 在Eclipse中查看OGNL类文件
• 因为导入的库文件都是已经编译好的class文件, 而不是源文件。必须把这些class文件和下载好的 源代码进行关联,这样就能在Eclipse中查看这些 库文件中的类了。 • 具体步骤如下。
3.4 自定义类型转换器
• Struts 2已经实现了一些常用的类型转换器,但 是这毕竟这些类型转换器毕竟还是有限的。如果 是开发者自己定义的数据类型,就必须自定义类 型转换器来进行转换。
Struts2各分类流程、与Struts1区别
![Struts2各分类流程、与Struts1区别](https://img.taocdn.com/s3/m/ebbca2828762caaedd33d43c.png)
Struts2各分类流程、与Struts1区别1、类型转换下面就类型转换的一些基本内容和相关的流程进行分析1。
构建项目这个也不用多说,大家都知道,我学习STRUTS2相关的项目文件都放在一个工作区下(workspace),这样便于管理,同时我觉得很好的一点就是能够创建一个公用的用户库,这样创建一个项目时可以导入这个用户库即可(目前需要用到的几个JAR包分别是struts-core.jar,ognl.jar,xwork.jar,freemarker.jar,common-logging.jar,创建一个用户库,将他们加入即可,以后每次项目中导入该用户库即可,这样比较方便2。
编写web.xml文件<?xml version="1.0" encoding="UTF-8"?><web-app version="2.4" xmlns="/xml/ns/j2ee"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/xml/ns/j2ee/xml/ns/j2ee/web-app_2_4.xsd"><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>3,编写JSP页面input.jsp<s:form action="PointConverter" method="post"><s:textfield name="point" label="point"/><s:textfield name="age" label="age" /><s:textfield name="username" label="username" /><s:textfield name="date" label="birthday" /><s:submit label="submit" /></s:form>这里使用了STRUTS2的标签库,故需要在JSP页面中指定<%@ taglib prefix="s" uri="/struts-tags" %>页面中主要是提示用户输入各个值,其中Point点需要用户用逗号隔开两个坐标值3。
Struts2的自动类型转换及自定义类型转换
![Struts2的自动类型转换及自定义类型转换](https://img.taocdn.com/s3/m/fa2d9e3731126edb6f1a102e.png)
Struts2的自动类型转换及自定义类型转换2010十一月8tags: Struts, Struts2, 类型转换by Ethan为什么会有类型转换?HTTP协议中传递的任何内容都是String类型的,所以一旦我们在服务器上需要一个非String类型的对象,例如:int或者Date,那么我们就需要在收到HTTP请求的数据的时候,首先将String类型的数据变换为我们需要的对应类型的数据,之后再使用。
这个过程就是类型转换类型转换在Struts2中是透明的,即Struts2内置了类型转换机制。
一、概述在B/S应用中,将字符串请求参数转换为相应的数据类型,是MVC框架提供的功能,而Struts2是很好的MVC框架实现者,理所当然,提供了类型转换机制。
Struts2的类型转换是基于OGNL表达式的,只要我们把HTML输入项(表单元素和其他GET/POET的参数)命名为合法的OGNL表达式,就可以充分利用Struts2的转换机制。
除此之外,Struts2提供了很好的扩展性,开发者可以非常简单的开发自己的类型转换器,完成字符串和自定义复合类型之间的转换。
总之,Struts2的类型转换器提供了非常强大的表现层数据处理机制,开发者可以利用Struts2的类型转换机制来完成任意的类型转换。
二.常规类型的转换:比如表单提交的信息有用户名,生日, 年龄, Action中对应的数据类型分别是String, Date, int.没什么好说的, Struts2会自动完成.Struts2内建了常用的类型转换器,如String ,boolean,char,int,long,float,double,Date, 数组(假定元素是String类型), 集合(假定元素是String类型,用ArrayList封装)实现自定义类型转换器实现TypeCoverter接口,或者继承DefaultTypeConverter实现类(该类实现了TypeCoverter接口),通过继承该实现类来实现自己的类型转换器。
struts2自定义类型转换器
![struts2自定义类型转换器](https://img.taocdn.com/s3/m/a218c48b6aec0975f46527d3240c844769eaa028.png)
struts2自定义类型转换器//原理详述Struts2自定义类型转换器分为局部类型转换器和全局类型转换器(1)局部类型转换器如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用date类型是可以接收到的,但是如果传的是20101112这样类型的字符串,用date类型是获取不到,并且会出现错误的,struts2提供了一种类型转换器供我们使用。
以下为局部类型转换器的开发步骤a.首先要写一个类来继承DefaultTypeConverterb.然后覆盖convertValue这个方法,在里面进行数据转型c.在action类所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是类名,后面的-conversion.properties是固定的写法,如:HelloWorldAction-conversion.propertiesd.Properties文件里面的内容为:属性名称=类型转换器的全类名(既包名.类名)如:birthday=com.ljq.type.converter.DateTypeConverter(2)全局类型转换器如果业务需求所有的日期都要转换,则可以使用全局类型转换器,只要在src根目录下面放置xwork-conversion.properties文件,并且properties文件中的内容为:待转换的类型=类型转换器的全类名如:java.util.Date = com.type.Converter.DateTypeConverter 即可代码Action类package com.ljq.action;import java.util.Date;public class HelloWorldAction {// 日期private Date birthday;// 枚举private Gender gender;public String execute() {return "success";}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) { System.out.println("birthday="+birthday); this.birthday = birthday;}// 自定义枚举public enum Gender {MAN,WOMEN}public Gender getGender() {return gender;}public void setGender(Gender gender) { System.out.println("gender="+gender); this.gender = gender;}}日期类型转换器package com.ljq.type.converter;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Map;importcom.opensymphony.xwork2.conversion.impl.DefaultTypeConver ter;/*** 日期自定义类型转换器** @author jiqinlin**/public class DateTypeConverter extends DefaultTypeConverter {@SuppressWarnings("unchecked")@Overridepublic Object convertValue(Map<String, Object> context, Object value,Class toType) {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");try {if (toType == Date.class) { // 当字符串向Date类型转换时String[] params = (String[]) value;return sdf.parseObject(params[0]);} else if (toType == String.class) { // 当Date转换成字符串时Date date=(Date)value;return sdf.format(date);}} catch (java.text.ParseException e) {e.printStackTrace();}return null;}}枚举类型转换器package com.ljq.type.converter;import java.util.Map;import com.ljq.action.HelloWorldAction.Gender;importcom.opensymphony.xwork2.conversion.impl.DefaultTypeConver ter;/*** 枚举自定义类型转换器** @author jiqinlin**/public class GenderTypeConverter extends DefaultTypeConverter{@Overridepublic Object convertValue(Map<String, Object> context, Object value,Class toType) {if(toType==Gender.class){ //当字符串向Gender类型转换时String[] params=(String[])value;return Gender.valueOf(params[0]);}else if (toType==String.class) { //当Gender转换成字符串时Gender gender=(Gender)value;return gender.toString();}return null;}}配置类型转换器测试路径日期http://localhost:8083/struts2/control/employee/list_execute .do?birthday=20110315 23:34:55枚举http://localhost:8083/struts2/control/employee/list_execute .do?gender=WOMEN局部类型转换器: HelloWorldAction-conversion.propertiesbirthday=com.ljq.type.converter.DateTypeConvertergender=com.ljq.type.converter.GenderTypeConverter全局类型转换器: xwork-conversion.propertiesjava.util.Date=com.ljq.type.converter.DateTypeConverter在页面打印日期和枚举的值birthday=${birthday }gender=${gender }简单使用代码:public class DateConverter extends DefaultTypeConverter { @Override public Object convertValue(Map context, Object value, Class toType) {SimpleDateFormat dateFormat = newSimpleDateFormat("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 (Parse Exception e) {}return null;}}将上面的类型转换器注册为局部类型转换器:在Action类所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是Action的类名,后面的-conversion.properties是固定写法,对于本例而言,文件的名称应为HelloWorldAction-conversion.properties 。
struts2学习笔记(四)全局数据类型转换
![struts2学习笔记(四)全局数据类型转换](https://img.taocdn.com/s3/m/1dd1dd8ccc22bcd126ff0c3b.png)
struts2学习笔记(四)全局数据类型转换前文讲到了局部数据类型转换,通过action类目录下的XAction-conversion.properties配置文件进行指定,在这种转换方法中,如果要对同一个Action类中多个数据类型进行转换,可在properties文件中多写几行,格式为:要转化的属性名= 负责转化的Converter类(指定包名).注释符号为#但是如果有多个Action类都包含同一个数据类型且都要对该数据类型进行转换,那么按照局部类型转换的思想则需要配置多个XAction-conversion.properties文件,这样显然过于复杂且难于管理.在这种情况下就需要用到全局数据类型转换了.具体操作如下:将先前Action类目录下的XAction-conversion.properties文件中的内容注释掉在WEB-INF/classes目录下新建一个xwork-conversion.properties文件(在MyEclipse中可直接新建在src文件夹下),写上: 自定义类型的包名+类名= 执行转换的类的包名+Converter类名,如: com.test.bean.Point=com.test.converter.PointConverter2.这样所在Action类在执行set和get方法时都要首先要读取classes 目录下的xwork-conversion.properties文件(如果存在),以确定当前的属性要不要执行类型转换,如果需要则调用properties文件指定的Converter类进行转换,这样就实现了全局的数据类型的转换.在上一文中,我们写局部数据类型转换用到的PointConverter.java类是继承了DefaultTypeConverter类,在里面重写了public Object convertValue(Map context, Object value, Class toType)方法,用if(Point.class==toType)和if(String.class==toType)来决定转换的方向.而在实际的项目开发中一般不会这样来写,而是用PointConverter.java去继承StrutsTypeConverter类,在子类中重写StrutsTypeConverter类的public Object convertFromString(Map context, String[] values, Class toClass)方法和public String convertToString(Map context, Object o)方法.方法中参数context为上下文信息,convertFromString是将客户端发进来字符串形式的数据转化为自定义的对象,其参数values为一个字符串数组,(如果是一个字符串则是长度为一的字符串数组,以字符串数组的形式写出是为了增加程序的通用性).convertToString方法是将对象转化为字符串并用于显示页面的输出.如此转换的类的代码:-------------------------------------------------------------------------------------------------// PointConverter2.javapackage com.test.converter;import java.util.Map;import org.apache.struts2.util.StrutsTypeConverter;import com.test.bean.Point;public class PointConverter2 extends StrutsTypeConverter {@Overridepublic Object convertFromString(Map context, String[] values, Class toClass) {Point point=new Point();String[] paramValues = values[0].split(",");int x=Integer.parseInt(paramValues[0]);int y=Integer.parseInt(paramValues[1]);point.setX(x);point.setY(y);return point;}@Overridepublic String convertToString(Map context, Object o) {Point point = (Point)o;int x=point.getX();int y=point.getY();String result="[x="+ x+", y="+y+"] this is processed byPointConverter2.java!";return result;}}-----------------------------------------------------------------------------------------------到此我可以进一步修改我们一直使用的那个实例,如果要在一个页面中输入多个点的信息,则我们需要多个textField组件来进行输入,<s:textfield name="point" label="point"></s:textfield><s:textfield name="point1" label="point2"></s:textfield><s:textfield name="point2" label="point3"></s:textfield>这样在Action类中就需要这样写了:private Point point;private Point point2;private Point point3;如此就需要过多的set和get方法了,但是利用全局数据类型可以方便进行转换.联想到JAVA1.5的新特性,我们可以使用泛型.如此我们就可以改写input.jsp: <s:textfield name="point" label="point"></s:textfield><s:textfield name="point" label="point2"></s:textfield><s:textfield name="point" label="point3"></s:textfield>在Action类中为为private List<Point> point;生成了SET和GET方法如下:public List<Point> getPoint() {return point;}public void setPoint(List<Point> point) {this.point = point;}这样我必须重写Converter类了,重写后的代码如下:----------------------------------------------------------------------------------------------//PointConverter3.javapackage com.test.converter;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.apache.struts2.util.StrutsTypeConverter;import com.test.bean.Point;public class PointConverter3 extends StrutsTypeConverter {@Overridepublic Object convertFromString(Map context, String[] values, Class toClass) {List<Point> list=new ArrayList<Point>();//初始泛型数组for(String value : values){//遍历values数组String[] paramValues=value.split(",");//将values中的一项按逗号分成数组Point point=new Point();//转化成一个Point对象int x=Integer.parseInt(paramValues[0]);int y=Integer.parseInt(paramValues[1]);point.setX(x);point.setY(y);list.add(point);}return list;}@Overridepublic String convertToString(Map context, Object o) {StringBuilder result=new StringBuilder();List<Point> list=(List<Point>)o;int number=0;result.append("[ ");for(Point point : list){++number;int x=point.getX();int y=point.getY();result.append(number).append(" x=").append(x).append(" y= ").append(y);}result.append(" ]");return result.toString();}}----------------------------------------------------------------------------------------关于配置:如果这种类型只是在一个Action类中需要转换,则可以使用局部数据类型转换.方法point=com.test.converter.PointConverter3,这里的point为Action类中的泛型数组名,就是类的一个属性名.附(一种框架自动进行转换的方法):在input.jsp页面中有两个textField组件,name分别为point.x ; point.y 分别用来输入点的X坐标和Y坐标,这样提交以后框架可以自动在Point类中对X,Y属性进行赋值和转换,但是需要在Point类中重写toString方法,这里并不提倡这样操作。
OGNL和类型转换
![OGNL和类型转换](https://img.taocdn.com/s3/m/1ff74648b84ae45c3a358c0d.png)
9.2.2 自定义类型转换器
创建自定义类型转换器 Struts 2提供了一个开发人员编写自定义类型转换器时可以 使 用 的 基 类 : org.apache.struts2.util.StrutsTypeConverter 。 StrutsTypeConverter 是抽象类,继承DefaultTypeConverter 。 StrutsTypeConverter 类定义了两个抽象方法,用于不同的转 换方向,分别为: public Object convertFromString(Map context, String[] values, Class toType) public String convertToString(Map context, Object object) 配置自定义类型转换器 应用于全局范围的类型转换器
12
总结
本章主要介绍了 OGNL 基础知识和类型转换,我 们清楚的知道基于 B/S模式的应用程序要完成数据之 间的交互,必须要进行数据类型的转换,否则将出现 B/S两端类型不兼容问题从而无法完成数据之间的交 互,其转换的基础则是OGNL。 通过在一个具体的实例中实现多种自定义类型的 类型转换,总而言之,Struts 2是很好的MVC框架的 实现者,它对视图层和非视图层提供了强有力的类型 转换机制,从而让开发者运用自如。
自定义类型转换器目录结构
11
9.2.3 注册自定义类型转换器
新建坐标格式的类型转换器 创建坐标类Point、创建类型转换类PointConverter
新建日期类型的类型转换器DateConverter
新建复选框选择的集合类型格式的类型转换器 创建兴趣类Hobby,创建转换类HobbyConverter类 创建表单提交页面reg.jsp和提交成功success.jsp页面 创建RegAction类 配置struts.xml文件 部署运行程序
struts2数据类型转换
![struts2数据类型转换](https://img.taocdn.com/s3/m/aac30f11f18583d0496459f0.png)
实现集合类型转换器 :
· 数组属性的类型转换器(例子:ArrayConvert ) 请求的Action代码:
public class RegisterAction implements Action { //封装 user请求参数的User数组属性 private User[] user ; //封装 birth请求参数的属性 private Date birth ; //封装 Action处理结果的tip属性 private String tip ; 省略 Setter和getter方法 //处理用户请求的excute()方法 public String execute() throws Exception { // 直接调用user属性的name属性和password属性进行判断 if(getUser()[0].getName().equals("wangjuzhu") && getUser()[0].getPassword().equals("wjz")){ setTip("转换成功") ; return SUCCESS ; }else{
通过 toType 类型判断了类型转换的方向后, 我们就可以分别实现两个方向的转换逻辑了。 实现类型转换器的关键就是实现 conertValue 方法,该方法有三个参数:
第二种方式:基于 Struts2 的类型转换器(例子:TypeConvent3) Struts 2提供了一个StrutsTypeConverter 的抽象类,这个抽象类是 DefaultTypeConverter 类的子类。 开发时可以直接继承这个类来进行转换器的构建。 通过继承 该类来构建类型转换器,可以不用对转换的类型进行判断(和第一种方式的区别) 。 ·StrutTypeConverter 类的代码:
struts2自定义类型转化器
![struts2自定义类型转化器](https://img.taocdn.com/s3/m/5cfbb91b0066f5335a812152.png)
public class DateConverter extends DefaultTypeConverter {/** 将value的值转换为执行类型toType对应的值* @param context* @param value 需要转换的值* @param toType 将要转成的类型*/public Object convertValue(Map<String, Object> context, Object value,Class toType) { try {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");if(toType.equals(Date.class)){String[] dateString = (String[]) value; //request.getParameterValues()return dateFormat.parse(dateString[0]);}if(toType.equals(String.class)){Date date = (Date) value;return dateFormat.format(date);}return super.convertValue(context, value, toType);} catch (ParseException e) {throw new RuntimeException(e.getMessage(),e);}}}配置局部类型转换器:将上面的类型转换器注册为局部类型转换器:在Action类所在的包下放置ActionClassName-conversion.properties文件,ActionClassName 是Action的类名,后面的-conversion.properties是固定写法,对于本例而言,文件的名称应为HelloWorldAction-conversion.properties 。
struts22(动态方法调用result类型转换)
![struts22(动态方法调用result类型转换)](https://img.taocdn.com/s3/m/b5a8ea3f02020740be1e9bcc.png)
1 2 3
在result中关于路径的说明
在result映射的配置中,在指定实际资源的位置时,可以使用绝对路径也可以 使用相对路径。绝对路径是以斜杠(/)开头,相对于当前web项目的上下文路 径,相对路径不以斜杠(/)开头,相当于当前执行的action路径。
<package name=“default” extends=“struts-default” namespace=“/admin”> <action name=“login” class=“.LoginAction”> <result>success.jsp</result> <result name=“error”>/error.jsp</result> </action>
所有结果类型都定义在 struts-defalt.xml中。
结果类型 chain
dispatcher freemarker httpheader
redirect redirectAction
stream velocity
xslt plainText
说明 用于Action链式处理 用于Web资源的集成,包括JSP的集成,默认值。 用于FreeMarker的集成 用于控制特殊的HTTP行为 用于重定向到另外的URL(web资源) 用于重定向到别外的action映射 用于向浏览器返回一个InputStream(用于文件下载) 用于Velocity集成 用于XML/XSLTWYS DN 用于显示某个特定页面(如jsp,html的原始内容)
-Action的名称。 namespace - used to determine which namespace the action is in that
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
类型转换的必要性:在前台Form表单中接受到服务器端的是String类型的,而服务器端往往需要的不完全是String型的,还需要int、date型以及其他的实体类型,这就涉及到Struts2的类型转换Struts2类型转换是基于xwork中的ONGL的,自定义转换器可以继承自DefaultT ypeConverter,也可以继承自StrutsT ypeConverter类(继承自DefaultT ypeConverter)。
自定义转换器使用方法1、所有对象类型都需要自定义转换器,自定义转换器需继承DefaultT ypeConverter类,覆盖public Object convertV alue(Map context , Object value, Class toT ype) {}方法;2、为已经写好的转换器注册:在action包里新建XXXAction-conversion.properties文件(局部配置文件),并在里边声明需要转换的Action类的成员变量(Point):变量名=转换器类,也可以用全局配置文件配置:在src目录下新建xword-conversion.properties,里面声明:要转化的实体类=转换器类。
在传参数的过程中,出现参数类型为对象类型的时候,也可以不使用自定义转换器,但是必须满足:1、该对象类型的各个成员变量在表单中单独输入2、实体类提供一个无参的构造方法struts2 框架据我目前所知道有以下几下几大好处:类型转换、表单验证、国际化支持、处理表示分开等,当然还有其它很多的好处,这就有待继续学习了。
struts2类型转换是它的一个主要功能之一。
它的流程如下图1、struts2的一些基本例:login.jsp(新建一个JSP页面)导入struts2的标签<%@ taglib prefix="s" uri="/struts-tags" %> 下面添加一个表单<s:form action="login"><s:textfield name="username" label="username"></s:textfield> <s:password name="password" label="password"></s:password> <s:submit label="submit"></s:submit></s:form>结果页面result.jspusername:<%= request.getParameter("username") %><br> password:<%= request.getParameter("password") %>新建一个LoginAction类,继承ActionSupport有成员变量以及他们的set、get方法:private String username;private String password;public String execute() throws Exception{return SUCCESS;}struts.xml<struts><package name="test" extends="struts-default"><action name="login" class="com.test.action.LoginAction"><result name="success">/result.jsp</result></action></package></struts>下面来分析下上面的代码,先看struts.xml中的内容。
pachkage中的name属性,表示了该project。
在该package中定义了一个action,name属性为login,调用class路径为com.test.action.LoginAction,即上面定义的LoginAction类。
result中属性name="success"表示了,当页面回一个success结果时跳至result.jsp页面。
这样通过struts.xml将LoginAction 类与login.jsp页面关联起来。
其中login.jsp中<s:form action="login">将该表单与struts.xml 中名为login的action关联。
程序是如何运作的呢?当我们访问login.jsp,输入username与password,按submit提交后,程序调用LoginAction中各个set方法,讲表单中对应的值赋值给对应的成员变量,注(与页面中的同名)。
(这里因为没有写自己的类型转化,所以通过struts2提供的默认的类型转化完成,下面我会做具体说明)。
完成了表单的提交后,页面通过validate方法进行相关验证,该方法需要我们overwrite(比如,我们判断username不为空等等。
),完成了validate 之后,通过execute方法,返回一个result,如返回SUCCESS,同去struts.xml中的该action 中查找对应的result进行页面的跳转,如上代码,则我们跳转至result.jsp,并且,result.jsp 通过LoginAction中的get方法,获得各成员变量显示出之前我们提交的内容。
2、类型转化之前提到,在set方法之前隐含了类型转化。
页面提交,我们获得的所有内容都是String类型的,而在set方法中,我们要set的成员,并不一定是String类型,所以我们需要一定的类型转化。
例:我们要输入一个Point(x,y),则我们需要对其进行类型转换。
首先,我们在工程下新建一个Point类,成员变量int x,y;已经相对应的set,get方法。
新建一个input.jsp页面<s:form action="pointConverter"><s:textfield name="point" label="point"></s:textfield><s:textfield name="age" label="age"></s:textfield><s:textfield name="username" label="username"></s:textfield><s:textfield name="date" label="birthday"></s:textfield><s:submit label="submit"></s:submit></s:form>新建一个output.jsp,对输入进行输出point:<s:property value="point"/><br>age:<s:property value="age"/><br>username:<s:property value="username"/><br>date:<s:property value="date"/><br>下面是主要的类型转化类,新建一个类PointConverter继承DefaultTypeConverter 重写下面的public Object convertV alue(Map context, Object value, Class toType)方法具体内容:if(Point.class == toType){Point point = new Point();String[] str = (String[])value;String[] paramV alues = str[0].split(",");int x = Integer.parseInt(paramV alues[0]);int y = Integer.parseInt(paramV alues[1]);point.setX(x);point.setY(y);return point;}if(String.class == toType){Point point = (Point)value;int x = point.getX();int y = point.getY();String result = "[x=" + x + " , y=" + y + "]";return result;}return null;新建PointAction继承ActionSupport包扩成员变量以及相关set,get方法:private Point point;private int age;private String username;private Date date;public String execute() throws Exception{return SUCCESS;}struts.xml中的配置,添加一个action<action name="pointConverter" class="com.test.action.PointAction"><result name="success">/output.jsp</result></action>可以看到,在input.jsp的表单中,已经使用了pointConverter该action下面需要写类型转换的文件PointAction-conversion.properties内容:point=com.test.converter.PointConverter表示:用PointConverter对PointAction中的point进行类型转换3、对多个不同Action类中的同类型对象的转换,使用全局类型转换(上面的资源文件属于局部类型转换)全局类型转换的资源文件命名固定为:xwork-conversion.properties若,我们要对所有的Point定义的对象用PointConverter进行类型转化,则com.test.bean.Point=com.test.converter.PointConverter4、使用StrutsTypeConverter来完成上述转换(免去了两个转换方向的判断)新建PointConverter2继承StrutsTypeConverter@Overridepublic Object convertFromString(Map context, String[] values, Class toClass){Point point = new Point();String[] paramV alues = values[0].split(",");int x = Integer.parseInt(paramV alues[0]);int y = Integer.parseInt(paramV alues[1]);point.setX(x);point.setY(y);return point;}@Overridepublic String convertToString(Map context, Object o){Point point = (Point)o;int x = point.getX();int y = point.getY();String result = "[ x = " + x + " , y = " + y + " ]";return result;}5、对于集合类型的转换,如private List<Point> point;新建PointConverter3继承StrutsTypeConverter@Overridepublic Object convertFromString(Map context, String[] values, Class toClass){List<Point> list = new ArrayList<Point>();for(String value : values){Point point = new Point();String[] paramV alues = value.split(",");int x = Integer.parseInt(paramV alues[0]);int y = Integer.parseInt(paramV alues[1]);point.setX(x);point.setY(y);list.add(point);}return list;}@Overridepublic String convertToString(Map context, Object o){List<Point> list = (List<Point>)o;StringBuilder sb = new StringBuilder();sb.append("[ ");int number = 0 ;for(Point point : list){++number;int x = point.getX();int y = point.getY();sb.append(number).append(" x = ").append(x).append(" , y = ").append(y).append(" "); }sb.append("]");return sb.toString();}。