一、类型转换的意义
对于一个智能的MVC框架而言,不可避免的需要实现类型转换.因为B/S(浏览器/服务器)结构应用的请求参数是通过浏览器发送到服务器的,这些参数不可能有丰富的数据类型,因此必须在服务器端完成数据类型的转换
MVC框架是一个表现层解决方案,理应提供类型转换的支持,Struts2提供了功能非常强大的类型转换支持.
二、表现层数据的处理
1、对于web应用而言,表现层主要用于与用户交互,包括收集用户输入数据,向用户呈现服务器的状态。因此表现层的数据的流向主要有两个方向:输入数据和输出数据。
2、对于输入数据:则需要完成由字符串数据向多种类型数据的转化。程序通常无法自动完成,需要在代码中手动转化
3、对于输出数据:不管是java或是jsp都支持多种数据类型的直接输出。
4、表现层另外一个数据处理是:数据校验,分为客户校验和服务器端校验.后边会重点讲解
三、类型转换
1、HTTP参数都是字符串类型。 保存的数据可能是字符串、数字、布尔、日期时间等或者JavaBean类型。 手工的类型转换,比如将字符串转换为日期,通过: 通过request.getParameter方法获取字符串; 检查是否为空; 通过DateFormat.parse方法将字符串转换为Date对象
2、Struts2类型转换
Struts2内置的类型转换
String和boolean 完成字符串与布尔值之间的转换
String和char 往常字符串与字符之间的转换
String和int、Integer 完成字符串与整型之间的转换
String和Long 完成字符串与长整型值之间的转换
String和double、Double 完成字符串与双精度浮点值的转换
String和Float 完成字符串和单精度浮点之间的转换
String和Date 完成字符串和日期类型之间的转换,日期格式使用格式用户请求所在Locale的SHORT格式
String和数组 在默认的情况,数组元素是字符串,如果用户定义类型转换器,也可以是其它复合数据类型
String和Map、List
四、自定义类型转换
这个程序想要实现的功能是对电话号的分离,如输入010-123456789,输出变成010@123456789
可以任意的取出区号和电话号。
配置什么的不过多的说了直接上代码如果想看Struts 2的环境配置请见我的另一篇博客: Struts2配置图解
1.JSP页面
(1)输入界面:in.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>Insert title here</title>
</head>
<body>
<div>
<s:form action="change" method="put">
<s:textfield name="user.phone" label="请输入电话号" />
<s:submit value="提交" />
</s:form>
</div>
</body>
</html>
(2)转换成功界面:
<%@ 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>Insert title here</title>
</head>
<body>
<p>转换成功</p>
电话号为:<s:property value="user.phone"/><br/>
电话号为:${phone }
<s:debug />
</body>
</html>
2.Java类
(1)Phone.java
package com.model;
public class Phone {
private String first;//区号
private String secnond; //电话号
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getSecnond() {
return secnond;
}
public void setSecnond(String secnond) {
this.secnond = secnond;
}
}
(2)User.java 封装起来
package com.model;
public class User {
private Phone phone;
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
}
(3)ChangeAction.java
package com.action;
import com.model.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
public class ChangeAction extends ActionSupport implements ModelDriven,Preparable{
private User user=new User();
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute(){
//user=new User();
return "success";
}
@Override
public void prepare() throws Exception {
// TODO Auto-generated method stub
//user=new User();
}
@Override
public Object getModel() {
// TODO Auto-generated method stub
return null;
// return user;
}
}
注意:
ModelDriven,Preparable 这两个接口是为了实例化,以至于可以在in.jsp 中控件的名字可以省去封装的类实例化。user.phone 可以直接写成phone,在success.jsp页面取出转换后的结果OGNL表达式取值的时候也用phone,而不用user.phone。
(4)PhoneTyoeConvert.java
package com.change;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.StrutsTypeConverter;
import com.model.Phone;
public class PhoneTyoeConvert extends StrutsTypeConverter{
@Override
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
// TODO Auto-generated method stub
String tel=arg1[0];
String string[]=tel.split("-");
Phone phone=new Phone();
phone.setFirst(string[0]);
phone.setSecnond(string[1]);
return phone;
}
@Override
public String convertToString(Map arg0, Object arg1) {
// TODO Auto-generated method stub
Phone phone=(Phone) arg1;
HttpServletRequest request = ServletActionContext.getRequest();
String ph = phone.getFirst()+"@"+phone.getSecnond();
request.setAttribute("phone", ph);
return ph;
}
}
注意:
如果用OGNL表达式取值的话可以用下面代码就能出结果:
public String convertToString(Map arg0, Object arg1){
Phone phone=(Phone) arg1;
return phone.getFirst()+"@"+phone.getSecnond();
}
但是当我用EL表达式取值的时候只能取到phone的地址,所以改成了上述的写法。
如图:
3.注册转换器
(1)全局类型转化器注册:
注册名的文件格式:xwork-conversion.properties文件该文件也是properties文件,其内容也是由”复合类型=对应的类型转换器类”项组成的。
在src下创建 xwork-conversion.properties
com.model.Phone=com.change.PhoneTyoeConvert
(2)局部类型转换器注册:
注册文件名格式:ActionName-conversion.properties:ActionName是需要转换器生效的Action的类名,后面的-conversion.properties字符串是固定部分
以上文件时典型的properties文件,文件有key-value对组成.文件内容为:propertyName=类型转换器类
ChangeAction-conersion.properties
phone=com.change.PhoneTyoeConvert
4.运行结果: