struts2 数据转换器
四、数据类型的转换(明白原理,实际开发中几乎不用)
1、开发中的情况:
实际开发中用户通过浏览器输入的数据都是String或者String[]。
String/String[]————填充模型(set方法)————>POJO(plain old java object) pojo中有java的数据类型。
POJO————————获取(get方法)————>页面展示:String
2、类型转换情况
写数据:(增,删,改)都是String或String[]数组转换为其他类型。
读数据:(查)其他类型转换为String。
3、Struts2提供的常用类型转换
a.基本数据类型自动转换。
b.日期类型:默认按照本地日期格式转换(yyyy-MM-dd)。
c.字符串数组:默认用逗号+空格,连接成一个字符串。
4、自定义类型转换器(知道)
示例:把日期格式按照 MM/dd/yyyy的格式转换
4.1、Struts2中的类型转换器结构:
/**
* Interface for accessing the type conversion facilities within a context.
*
* This interface was copied from OGNL's TypeConverter
*
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
public interface TypeConverter
{
/**
* Converts the given value to a given type. The OGNL context, target, member and
* name of property being set are given. This method should be able to handle
* conversion in general without any context, target, member or property name specified.
* @param context context under which the conversion is being done
* @param target target object in which the property is being set
* @param member member (Constructor, Method or Field) being set
* @param propertyName property name being set
* @param value value to be converted
* @param toType type to which value is converted
* @return Converted value of type toType or TypeConverter.NoConversionPossible to indicate that the
conversion was not possible.
*/
public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType); public static final Object NO_CONVERSION_POSSIBLE = "ognl.NoConversionPossible"; public static final String TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter";
}
TypeConverter(类型转换父接口)
/**
* Default type conversion. Converts among numeric types and also strings. Contains the basic
* type mapping code from OGNL.
*
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
public class DefaultTypeConverter implements TypeConverter { protected static String MILLISECOND_FORMAT = ".SSS"; 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);
}
DefaultTypeConverter部分(Abstract)
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);
}
Struts2TypeConverter(abstract)
DefaultTypeConverter 实现接口 TypeConverTer ;
Struts2TypeConverter 继承了DefaultTypeConverter
其它转换器都几乎继承自 Struts2TypeConverter
4.2、编写类型转换器(编写一个类继承StrutsTypeConverter,实现抽象方法)
/**
* 需求:
* 把表单中的MM/dd/yyyy格式的数据转成日期类型
* 把数据库中的本地日期格式,转成MM/dd/yyyy形式输出
*
* 自定义子类转换器:
* 第一步:编写一个类,继承自StrutsTypeConverter,实现convertFromString,convertToString抽象方法
* @author zhy
*
*/
public class MyTypeConvertor extends StrutsTypeConverter { //定义一个类型转换器
private DateFormat format = new SimpleDateFormat("MM/dd/yyyy"); /**
* 把字符串数组中的数据转成日期类型
*
* 方法参数详解:
* Map context:是OGNL的上下文对象,我们暂时不知道,所以暂时也不用
* String[] values:要转换的数据
* Class toClass:目标类型
*/
public Object convertFromString(Map context, String[] values, Class toClass) {
//1.先看看有没有数据
if(values == null || values.length == 0){
return null;
}
//2.取出数组中的第一个元素
String date = values[0];
//3.判断目标类型的字节码是不是日期类型
if(toClass == java.util.Date.class){
try {
//4.使用DateFormat进行转换,并且返回转换后的结果
return format.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
return null;
} /**
* 把日期类型的数据转换成字符串
*
* 方法参数详解:
* Map context:是OGNL的上下文对象,我们暂时不知道,所以暂时也不用
* Object o:要转换的数据
*/
public String convertToString(Map context, Object o) {
//1.判断object是不是日期类型
if(o instanceof Date){
Date date = (Date)o;
//2.是日期类型,使用转换器转成指定格式的字符串,并返回
return format.format(date);
}
return null;
} }
MyTypeConverter(自己的转换器)
4.3、注册类型转换器
局部类型转换器:只能指定javabean中的属性用
按照属性来注册。在属性所属的javabean的包下建立一个.properties文件。文件名称:javabean名称-conversion.properties
#局部类型转换器文件名的命名规范:javabean的名称-conversion.properties
#局部类型转换器声明,声明方式是以使用的属性名称作为key,以类型转换器的全类名作为value
birthday=com.itheima.web.converter.MyTypeConvertor
javabean的名称-conversion.properties
全局类型转换器:(推荐)
按照要转换的数据类型来注册。
at the top op classpath,建立一个固定名称xwork-conversion.properties的属性文件。
#全局类型转换器文件名的命名规范:xwork-conversion.properties。文件放到类路径的根路径
#全局类型转换器声明,声明方式是以使用的数据类型(全类名)作为key,以类型转换器的全类名作为value
java.util.Date=com.itheima.web.converter.MyTypeConvertor
xwork-conversion.properties
5、转换失败后的处理(需要掌握)
当转换失败后,页面提示:
一串英文的错误提示
解决办法:配置回显结果视图
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<package name="p1" extends="struts-default">
<action name="register" class="com.itheima.web.action.UserAction" method="register" >
<result type="redirect">/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="exists">/message.jsp</result><!-- 当用户名已经存在之后,转向的结果视图 -->
<!-- 当出现问题之后,需要从哪来回哪去 -->
<result name="input">/register1.jsp</result>
</action>
</package>
</struts>
struts2.xml
问题:
配置了回显视图后,当转换失败时,可以回到请求页面,但是表单数据都没了?
显示错误提示:借助Struts2的标签库。
回显数据:使用struts2的标签库生成表单。(建议使用)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%--导入struts2的标签库 --%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用户注册,使用的是struts2的标签</title>
<s:head></s:head>
</head>
<body>
<s:actionerror/><%-- 动作错误 --%>
<s:fielderror /><%-- 字段错误 --%>
<%--struts2的form标签,它提供了和原始html表单标签几乎一致的属性
action:请求的地址。直接写动作名称。不用写contextPaht
method:请求的方式。在这里不用写。struts2的form表单默认就是post
enctype:表单编码的MIME类型
--%>
<s:form action="register.action">
<s:textfield name="username" label="用户名" requiredLabel="true" requiredPosition="left"/>
<s:password name="password" label="密码" showPassword="true"/>
<s:textfield name="birthday" label="生日"/>
<s:submit value="注册"/>
</s:form>
</body>
</html>
jsp代码
错误信息中文提示:使用的是struts2的国际化。
(在国际化中进行详解)
问题:
类型转换器当转换失败后,如何进入input视图的?
原因:
是由一个叫做conversionError的拦截器完成的。
注意:
要想使用类型转换中的错误处理,在定义Action时必须继承ActionSupport
struts2 数据转换器的更多相关文章
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...
- 菜鸟学Struts2——Interceptors
昨天学习Struts2的Convention plugin,今天利用Convention plugin进行Interceptor学习,虽然是使用Convention plugin进行零配置开发,这只是 ...
- 菜鸟学Struts2——零配置(Convention )
又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Conv ...
- 菜鸟学Struts2——Results
在对Struts2的Action学习之后,对Struts2的Result进行学习.主要对Struts2文档Guides中的Results分支进行学习,如下图: 1.Result Types(Resul ...
- 菜鸟学Struts2——Actions
在对Struts2的工作原理学习之后,对Struts2的Action进行学习.主要对Struts2文档Guides中的Action分支进行学习,如下图: 1.Model Driven(模型驱动) St ...
- 菜鸟学Struts2——Struts工作原理
在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...
- 13、零配置Struts2开发
Convention 插件 从 Struts 2.1 开始, Struts 可以使用 Convention 插件来支持零配置: Convention 插件完全抛弃配置信息, 不仅不需要使用 strut ...
- 12、Struts2表单重复提交
什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...
- 11、Struts2 的文件上传和下载
文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...
随机推荐
- kibana简单使用——elaticsearch的文档,索引的CRUD操作
1.初始化索引: #number_of_shards:分片的数量,mo'ren默认为5 #number_of_replicas:副本副本的副本的数量 #shards一旦设置不能修改 PUT lagou ...
- WPF中自定义MarkupExtension
在介绍这一篇文章之前,我们首先来回顾一下WPF中的一些基础的概念,首先当然是XAML了,XAML全称是Extensible Application Markup Language (可扩展应用程序标记 ...
- 手把手制作一个简单的IDEA插件(环境搭建Demo篇)
新建IDEA插件File --> new --> Project--> Intellij PlatForm Plugin-->Next-->填好项目名OK 编写插件新建工 ...
- No module named 'ConfigParser'
系统: CentOS-6.4-x86_64 Python : Python 3.4.5 和 Python 3.5.2 安装 MySQL-python ,结果出错: ImportError: No mo ...
- echo显示颜色
如有转载,不胜荣幸.http://www.cnblogs.com/aaron-agu/ [;;34m hello aaron \[0m”
- js笔记2
原型:prototype 和 __proto__ prototype 给他即将生成的对象继承下去的属性 prototype: 显式原型,每个function下都有prototype属性,该属性是一个对 ...
- jQuery AJAX获取JSON数据解析多种方式示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Spring Boot 构建电商基础秒杀项目 (四) getotp 页面
SpringBoot构建电商基础秒杀项目 学习笔记 BaseController 添加 public static final String CONTENT_TYPE_FORMED = "a ...
- Jquery实现检测用户输入用户名和密码不能为空
要求 1.用户名和密码为空点击登录时提示相应的提示 2.获取用户名输入框时,错误提示清除 思路 1.创建1个input-text标签和1个input-password标签,1个input-botton ...
- 重写Distinct
添加类并继承`IEqualityComparer`,重写方法 public class DistinctComparer : IEqualityComparer<ActionInfo> { ...