四、数据类型的转换(明白原理,实际开发中几乎不用)

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 数据转换器的更多相关文章

  1. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  2. 菜鸟学Struts2——Interceptors

    昨天学习Struts2的Convention plugin,今天利用Convention plugin进行Interceptor学习,虽然是使用Convention plugin进行零配置开发,这只是 ...

  3. 菜鸟学Struts2——零配置(Convention )

    又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Conv ...

  4. 菜鸟学Struts2——Results

    在对Struts2的Action学习之后,对Struts2的Result进行学习.主要对Struts2文档Guides中的Results分支进行学习,如下图: 1.Result Types(Resul ...

  5. 菜鸟学Struts2——Actions

    在对Struts2的工作原理学习之后,对Struts2的Action进行学习.主要对Struts2文档Guides中的Action分支进行学习,如下图: 1.Model Driven(模型驱动) St ...

  6. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  7. 13、零配置Struts2开发

    Convention 插件 从 Struts 2.1 开始, Struts 可以使用 Convention 插件来支持零配置: Convention 插件完全抛弃配置信息, 不仅不需要使用 strut ...

  8. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  9. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

随机推荐

  1. kibana简单使用——elaticsearch的文档,索引的CRUD操作

    1.初始化索引: #number_of_shards:分片的数量,mo'ren默认为5 #number_of_replicas:副本副本的副本的数量 #shards一旦设置不能修改 PUT lagou ...

  2. WPF中自定义MarkupExtension

    在介绍这一篇文章之前,我们首先来回顾一下WPF中的一些基础的概念,首先当然是XAML了,XAML全称是Extensible Application Markup Language (可扩展应用程序标记 ...

  3. 手把手制作一个简单的IDEA插件(环境搭建Demo篇)

    新建IDEA插件File --> new --> Project--> Intellij PlatForm Plugin-->Next-->填好项目名OK 编写插件新建工 ...

  4. No module named 'ConfigParser'

    系统: CentOS-6.4-x86_64 Python : Python 3.4.5 和 Python 3.5.2 安装 MySQL-python ,结果出错: ImportError: No mo ...

  5. echo显示颜色

    如有转载,不胜荣幸.http://www.cnblogs.com/aaron-agu/ [;;34m hello aaron \[0m”

  6. js笔记2

    原型:prototype 和 __proto__ prototype 给他即将生成的对象继承下去的属性 prototype: 显式原型,每个function下都有prototype属性,该属性是一个对 ...

  7. jQuery AJAX获取JSON数据解析多种方式示例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. Spring Boot 构建电商基础秒杀项目 (四) getotp 页面

    SpringBoot构建电商基础秒杀项目 学习笔记 BaseController 添加 public static final String CONTENT_TYPE_FORMED = "a ...

  9. Jquery实现检测用户输入用户名和密码不能为空

    要求 1.用户名和密码为空点击登录时提示相应的提示 2.获取用户名输入框时,错误提示清除 思路 1.创建1个input-text标签和1个input-password标签,1个input-botton ...

  10. 重写Distinct

    添加类并继承`IEqualityComparer`,重写方法 public class DistinctComparer : IEqualityComparer<ActionInfo> { ...