首先,何为struts2的类型转换器?

类型转换器的作用是将请求中的字符串或字符串数组参数与action中的对象进行相互转换。

一、大部分时候,使用struts2提供的类型转换器以及OGNL类型转换机制即可满足大部分类型转换需求。如:

类User.java

package models;

public class User {
private String username;
private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} }

类LoginAction

package actions;

import java.util.List;

import models.User;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport {

    private User user;

    public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} @Override
public String execute() throws Exception {
if (getUser().getUsername().equals("yangys")
&& getUser().getPassword().equals("123")) {
return SUCCESS;
}
return ERROR;
} }

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
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><s:text name="login page"></s:text></title>
</head>
<body>
<s:form action="login">
<s:textfield name="user.username" key="username" />
<s:password name="user.password" key="password" />
<s:submit value="login" />
</s:form>
</body>
</html>

不用做任何处理,表单中的user.username和user.password即可映射到LoginAction中的user对象上。

注:需提供相关的getter与setter

二、在特殊情况下,这种类型转换满足不了需求,比如需要把一个复杂字符串转换为一个对象。

如用户输入"huaihaizi,123"需要将huaihaizi映射到username,把123映射到password。则需要提供自定义类型转换器并将其注册到struts2中,供系统调用并完成类型转换。

为了模拟此需求,将login.jsp改为如下,通过一个user输入框输入用户名密码,以逗号分隔。

<%@ page language="java" contentType="text/html; charset=UTF-8"
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><s:text name="login page"></s:text></title>
</head>
<body>
<s:form action="login">
<s:textfield name="user" key="user" />
<s:submit value="login" />
</s:form>
</body>
</html>

User.java与LoginAction.java保持不变。此时为了达到user输入框中的内容映射到user对象的username和password上,需要编写一个自定义转换器类。在OGNL项目中有一个TypeConvert接口,这个借口就是自定义类型转换器必须实现的接口,该接口定义如下。

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

实现自定义类型转换器必须实现上面的接口,但是该接口过于复杂,所以OGNL提供了实现类DefaultTypeConverter,通常都采用继承并重写DefaultTypeConverter的convertValue()方法来实现自定义类型转换器,如上需求,需要编写UserConverter.java,代码如下:

package converters;

import java.util.Map;

import models.User;
import ognl.DefaultTypeConverter; public class UserConverter extends DefaultTypeConverter { @Override
public Object convertValue(Map context, Object value, Class toType) {
if (toType == User.class) {
String[] params = (String[]) value;
User user = new User();
user.setUsername(params[0].split(",")[0]);
user.setPassword(params[0].split(",")[1]);
return user;
} else if (toType == String.class) {
User user = (User) value;
String userString = "<" + user.getUsername() + ","
+ user.getPassword() + ">";
return userString;
}
return null;
}
}

这里,convertValue方法就是执行类型转换逻辑的,参数value是转换前的值,toType是转换目标类型,通过判断toType来执行转换方向的逻辑代码。如此例中,toType==User.class时,即为将页面字符串转换成User类的对象,由于适应页面控件参数的通用性,页面参数统一包装成了字符串数组,如果是一个字符串,则为长度1的字符串数组。比如此例中,输入为"huaihaizi,123",则把huaihaizi赋值给user对象的username,把123赋值给user对象的password,并将此user返回即可。反之则把user对象的username和password拼接成字符串返回。

三、struts2提供了一个StrutsTypeConverter抽象类,这个类是DefaultTypeConverter的子类,将convertValue的两个转换方向拆分成了两个方法,

convertFromString(Map context,String[] values,Class toClass)

convertToString(Map context ,Object o)

逻辑更为清楚,用法与DefaultTypeConverter一致。

三、然后通过在struts2项目中注册此自定义类型转换器即可,注册此自定义类型转换器有三种方式。

1.注册局部类型转换器,局部类型转换器仅仅对某个Action的属性起作用

局部类型转换器则是在该Action同一目录下添加ActionName-convertion.properties,并在内部添加一行映射关系<propName>=<ConverterClass>。本例子中在LgoinAction.java所在包下添加LoginAction-convertion.properties文件,并在文件中添加user=converters.UserConverter即可。

2.注册全局类型转换器,全局类型转换器对所有Action的特定类型的属性都会生效

在源代码根路径下提供xwork-convertion.properties文件。并在文件中添加<propType>=<ConverterClass>。本例子中在src目录下添加xwork-convertion.properties文件,并在文件中添加models.User=converters.UserConverter即可。

3.使用JDK1.5的注解来注册类型转换器。

局部类型转换器与全局类型转换器的区别:局部类型转换器只针对局部变量进行一次性转换,比如该局部变量是个List<User>,也是在局部类型转换器中对该变量进行一次转换。如果用全局类型转换器,则该List中的每一个User都将进行一次转换。

四、处理Set集合属性的类型转换,一般情况下不建议在Action中使用Set集合属性,因为Set集合里元素是无序的,所以Struts2不能准确的将参数转换成Set集合里的元素,也不能准确的读取Set集合里的元素。除非Set集合的每个元素都有一个唯一标示,比如对于上面的User类来讲,将username做为标识,则在Action的Set<User>中不能存在两个User对象的username相同,需要重写User的equals和hashCode方法。

@Override
public int hashCode() {
// TODO Auto-generated method stub
return getUsername().hashCode();
} @Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj != null && obj.getClass() == User.class) {
User objUser = (User) obj;
if (objUser.getUsername().equals(this.getUsername())) {
return true;
}
}
return false;
}

然后在局部类型转换器注册文件中指定该Set集合元素的标识。如该Set集合为users,则上面讲过在LoginAction-conversion.properties中添加users=converters.UserConverter 即可注册该局部类型转换器,现在此行下面添加KeyProperty_users=username则可以制定users变量的唯一标识属性是username。

struts2自定义类型转换器的更多相关文章

  1. [JavaWeb基础] 013.Struts2 自定义类型转换器

    很多时候,我们在做web开发的时候经常要用到时间的转换器,Struts2给我们提供了一种类型转换器的接口.下面我们讲讲怎么实现吧. 1.首先我们要定义一个类型转换的类,继承自com.babybus.s ...

  2. Struts2初学 struts2自定义类型转换器

    一.问题的引出      Struts2的类型转换是基于OGNL表达式的,由于请求的参数都是字符串,而JAVA 本身属于强类型的的语言,这样就需要把请求参数字符串转换成其他类型.     Struts ...

  3. Struts2之自定义类型转换器

    Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用d ...

  4. Struts2框架的自定义类型转换器

    前言:对于java的基本数据类型及一些系统类(如Date类.集合类),Struts2提供了内置类型转换功能,但是也有一定的限制.所以就演示出自定义类型转换器 一.应用于局部类型转换器 eg.用户登录出 ...

  5. [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. struts2基础---->自定义类型转换器

    这一章,我们开始struts2中自定义类型转换器的学习. 自定义类型转换器

  7. sruts2 自定义类型转换器

    1.1.1    Struts2中自定义类型转换器:(了解) 类型转换的过程是双向的过程: JSP---->Action参数提交:String---Date. Action---->JSP ...

  8. 自定义类型转换器converter

    作用:目前将日期转换成string,将string转换成我想要的类型   0509课件里讲 一.数据类型转换在web应用程序中,数据存在两个方向上的转换:1.当提交表单时  表单数据以字符串的形式提交 ...

  9. Struts(二十):自定义类型转换器

    如何自定义类型转换器: 1)为什么需要自定义类型转化器?strtuts2不能自动完成字符串到所有的类型: 2) 如何定义类型转化器? 步骤一:创建自定义类型转化器的类,并继承org.apache.st ...

随机推荐

  1. 【原】Docker

    Docker 最近Docker火的不行不行的,正好有时间,找点资料学习一下. 1.Docker是一个轻量级虚拟化技术,比虚拟机有更多优势,简易安装.更快的速度.服务集成与开发流程自动化.跨平台.可移植 ...

  2. 解决Mac下Sequel Pro 1.1 连接 Homebrew安装Mysql5.7.8的问题 Sequel Pro 1.1 encountered an unexpected error

    解决Mac下Sequel Pro 1.1 连接 Homebrew安装Mysql5.7.8的问题 Sequel Pro encountered an unexpected error Sequel Pr ...

  3. vijosP1115 火星人

    vijosP1115 火星人 链接:https://vijos.org/p/1115 [思路] 排列组合. 题目要求为求第下m个排列. 这里有两种方法,首选的是调用algorithm中的next_pe ...

  4. Pascal <-> C/C++ 转换简明教程

    在OI的学习中,阅读多种语言的能力是很重要的. 本文就着眼于让大家最快地掌握这两种语言间的转换方法. 程序主结构 C/C++ Pascal 主程序(即开始执行的程序段)和其他函数.过程本质上都属于函数 ...

  5. 引入less报错解决方法以及浏览器设计不同的地方

    XMLHttpRequest cannot load file:///C:/Users/PAXST/Desktop/805/first.less. Cross origin requests are ...

  6. 分布式搜索Elasticsearch增、删、改、查操作深入详解

    引言: 对于刚接触ES的童鞋,经常搞不明白ES的各个概念的含义.尤其对“索引”二字更是与关系型数据库混淆的不行.本文通过对比关系型数据库,将ES中常见的增.删.改.查操作进行图文呈现.能加深你对ES的 ...

  7. jbpm4.4 demo2

    package cn.itcast.b_processdefinition; import java.io.FileInputStream; import java.io.FileOutputStre ...

  8. Android实时监听网络状态(1)

    其实手机在网络方面的的监听也比较重要,有时候我们必须实时监控这个程序的实时网络状态,android在网络断开与连接的时候都会发出广播,我们通过接收系统的广播就可以实现网络的监听. 1.添加访问网络和获 ...

  9. PHP获取当前url路径的函数及服务器变量

    $_SERVER["QUERY_STRING"],$_SERVER["REQUEST_URI"],$_SERVER["SCRIPT_NAME" ...

  10. 结构体数组(C++)

    1.定义结构体数组 和定义结构体变量类似,定义结构体数组时只需声明其为数组即可.如: struct Student{ int num; char name[20]; char sex[5]; int ...