Struts2-10 类型转换

  MVC框架具有将字符串请求参数转换为响应数据类型的功能,而Struts2.0作为MVC框架的实现者,理所当然提供了类型转换机制,概述如下:

  • HTTP没有“类型”的概念,表单输入的只可能是字符串或字符串数组;
  • Struts2从表单到Action对象的类型转换即是从字符串到非字符串的;
  • Struts2的params拦截器在将请求参数映射到Action对象属性时,可自动完成字符串和基本数据类型间的转换。

一、类型转换错误消息的显示与定制

1.1 类型转换错误

  ConversionError拦截器作为默认拦截器栈的一员,负责添加与类型转换有关的出错消息(前提是Action类实现了ValidationAware接口)和保存各请求参数的原始值。
 
  若字段标签使用非simple主题,则类型转换错误消息为:”Invalid field value for field fieldName”。

  如果类型转换发生错误,则

  • 若Action类未实现ValidationAware接口:Struts2发生类型转换错误时,仍会继续调用其Action方法,就好像什么都没发生一样;
  • 若Action类实现了ValidationAware接口:Struts2发生类型转换错误时,不会继续调用其Action方法;而将检查相关action元素的声明是否包含name=input的result元素,若有则将控制权转交给该元素,否则抛出异常。
  • 注意:可以直接继承于实现了ValidationAware接口的ActionSupport类来代替实现ValidationAware接口。
1.2 覆盖默认错误信息
  • 新建属性文件ActionClassName.properties,放在Action类所在包中;
  • 添加键值对:invalid.fieldvalue.fieldName=Custome error message。
1.3 强制显示错误信息

  如果表单是simple主题,则不会自动显示错误消息。解决方案如下:

  • 使用EL或OGNL表达式显示:${fieldErrors.age[0]},即通过debug标签可知,类型转换出错时在值栈的Action对象中有一个类型为Map<String, List<String>>的fieldErrors属性;
  • 使用s:fielderror标签来显示:<s:fielderror fieldName="fieldname"></s:fielderror>,即使用其fieldName属性显示指定字段的错误信息。

  问题:若是simple主题,且用s:fielderror标签来显示错误消息,则该消息包含在一个ul、li、span中,影响页面排版,如何去除?

  • 在src下新建template.simple包,并新建fielderror.ftl文件;
  • 将Struts2核心包/template/simple/fielderror.ftl文件内容复制到新建fielderror.ftl文件中;
  • 剔除掉影响页面排版的ul、li、span部分即可。

二、自定义类型转换器

  因为Struts2不能自动完成字符串到非基本数据类型的转换,故需要定制类型转换器,主要包括开发类型转换器类和配置类型转换器两部分;具体如下:

2.1 开发类型转换器类

  自定义类型转换器必须实现ongl.TypeConverter接口或该接口某种具体实现类进行扩展,常扩展StrutsTypeConverter类即可。

2.2 配置类型转换器

(1)基于字段的配置
  该方式可以为某Model类(可能是Action也可能是JavaBean) 的各个属性分别配置一个自定义类型转换器;配置方法如下:

  • 新建属性文件ModelClassName-conversion.properties,放在Model类所在包下;
  • 添加键值对:字段名=类型转换器的全类名;
  • 注意:第一次使用该转换器时即创建实例(单实例的)……

(2)基于类型的配置
  该方式为整个应用中所有Model类的各个属性均配置同一个自定义类型转换器,配置方法如下:

  • 在src目录下新建xwork-conversion.properties文件;
  • 添加键值对:待转换的类型=类型转换器的全类名;
  • 注意:在当前Struts2应用被加载时创建实例(创建两次)……
2.3 实现自定义的时间类型转换器

  要求:时间pattern需要以web应用初始化参数的形式配置在web.xml中,且当类型转换失败给出自定义信息。
  
  web.xml中配置初始化参数如下:

<context-param>
    <param-name>pattern</param-name>
    <param-value>yyyy-mm-dd hh:mm:ss</param-value>
</context-param>

  类型转换器DateConverter.java代码如下:

package com.qiaobc.struts.converter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.StrutsTypeConverter;

public class DateConverter extends StrutsTypeConverter {

    private DateFormat dateFormat;

    public DateConverter() {
        System.out.println("DateConverter...");

        // 获取应用程序的初始化参数
        /**
         * 基于字段的配置采用如下方法获取初始化参数,因其在第一次使用类型转换器时创建实例
         */
        // ServletContext servletContext = ServletActionContext.getServletContext();
        // String dateStr = servletContext.getInitParameter("pattern");

        // dateFormat = new SimpleDateFormat(dateStr);
    }

    /**
     * 基于类型的配置采用如下方法获取初始化参数,因其在应用加载时即创建实例
     */
    public DateFormat getdDateFormat() {

        if(dateFormat == null) {

            ServletContext servletContext = ServletActionContext.getServletContext();
            String dateStr = servletContext.getInitParameter("pattern");

            dateFormat = new SimpleDateFormat(dateStr);
        }

        return dateFormat;
    }

    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {

        System.out.println("convertFromString...");

        if(toClass == Date.class) {
            if(values != null && values.length > 0) {
                // 将values[0]转换为Date型
                try {
                    // 基于字段的配置采用如下方法
                    // return dateFormat.parse(values[0]);
                    // 基于类型的配置采用如下方法
                    return getdDateFormat().parse(values[0]);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }

        // 未转换成功则返回values
        return values;
    }

    @Override
    public String convertToString(Map context, Object o) {

        System.out.println("convertToString...");

        if(o instanceof Date) {
            Date date = (Date) o;
            return dateFormat.format(date);
        }

        // 未转换成功则返回null
        return null;
    }
}

三、类型转换器与复杂属性&集合的协同使用

  类型转换器与复杂属性协同使用的基本原理图如下所示:
这里写图片描述
  类型转换器与集合协同使用的基本原理图如下所示:
这里写图片描述

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值