Struts2入门(三)——类型转换

一、前言

笔者一直觉得,学习一个知识点,你首先要明白,这东西是什么?有什么用?这样你才能了解。好了,不说废话。

1.1、类型转换为何存在?什么是类型转换?

在MVC框架中,都是属于表示层解决方案,都需要负责收集用户请求的参数,并且将请求参数传给应用的控制器组件,但是,这里有一个问题,客户端提交的请求参数都是字符串数据类型,而java这门语言本身就是强类型语言,所以我们需要类型转换,就是把字符串类型转化为你所需要的类型。

在MVC框架中,表示层数据处理分为两个方法:客户端输入数据,服务端输出数据;客户端输入数据需要进行类型转换才能确保我们的数据类型是正确的,服务端输出数据无需经过类型转换。

简单说就是:

在javaweb中,当你在jsp页面提交一个username到servlet中,你是否在通过request.getParameter("username")去获取数据;但是

如果是一个Date时间类型呢?你是否要先指定时间的转换格式,然后再根据request.getParameter("date");获取数据之后再去转换呢?但是,你想过没有?如果是多个页面请求数据的话,那你每次打getParameter();这个方法,累吗?你不累,程序都累了。所以,Struts2 为我们提供了一种类型转换器,只需要编写固定的操作就能得到你想要的数据,简单说来,就是把表单的数据赋值给实体类。

1.2、类型转换器简单介绍

1.2.1、类型转换器需要继承DefaultTypeConverter类,需要重写该类的convertType方法。

convertType方法的作用:

1、负责对类型的转换,不过这种转换是双向的,我们可以通过判断数据的类型判断转换的方向

2、该方法有三个参数:

  context:是类型转换环境的上下文

  value:    是需要转换的参数(随转换方向不同,如果字符串向实例转换时,它是字符串数组;如果实例字符串转换时,它是实例)

  toType: 是转换后的目标参数

二、类型转换器

2.1、类型转换器有两种:局部类型转换器和全局类型转换器,就字面上的意思一样,全局和局部的。

关于类型转换器的注册方式有三种:

1、局部类型转换器仅仅对某个Action起作用

2、全局类型转换器对所有Action特定类型的属性都会起作用

3、我们可以通过注解的方式来生成类型转换器(JDK1.5以上的注解)

2.2、局部类型转换器:

新建实体类userbean:

package com.TypeConverter;

import java.util.Date;

public class userbean {
    private String uname;
    private String upwd;
    private int uage;
    private Date udate;
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public String getUpwd() {
        return upwd;
    }
    public void setUpwd(String upwd) {
        this.upwd = upwd;
    }
    public int getUage() {
        return uage;
    }
    public void setUage(int uage) {
        this.uage = uage;
    }
    public Date getUdate() {
        return udate;
    }
    public void setUdate(Date date) {
        this.udate = date;
    }
    public userbean(){
}
    public userbean(String uname, String upwd, int uage, Date udate) {
        this.uname = uname;
        this.upwd = upwd;
        this.uage = uage;
        this.udate = udate;
    }
}    

userbean

建立jsp视图:这里的是Test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>局部类型转换器</title>
</head>
<body>
    <h2>请输入您的注册信息</h2>
    <form action="user">
    <!-- 注意:name的名字必须是userbean1,跟useraction里面属性名字一样 -->
    <label>用户名:</label><input type="text" name="userbean1"><br/>
    <label>密&nbsp;码:</label><input type="text" name="userbean1"><br/>
    <label>年&nbsp;龄:</label><input type="text" name="userbean1"><br/>
    <label>生&nbsp;日:</label><input type="text" name="userbean1"><br/>
    <input type="submit">
    </form>
</body>
</html>

在struts.xml配置信息。我们只需要配置这个

这里的<result name="input">是错误机制处理程序,就是说当页面跳转错误或者异常问题的时候,会跳转到你指定的页面,这里笔者是让其自动跳转到原来的页面。

我们可以定义一个局部的错误处理消息提示,这里笔者没有做,但是可以了解下:

新建useraction.properties,放在同级目录下,
这里的useraction是值你继承ActionSupport的类,然后往该文件中写入:
invalid.fieldvalue.属性名=提示消息(其中属性名可以是:uname或者upwd等)
当类型转换错误就会跳转,你可以在页面上使用JSTL打印,如:
<%@ taglib uri="/struts-tags" prefix="s"%>
然后使用<s:fielderror/>该标签显示出你的提示消息

错误消息处理机制

新建useraction类,继承ActionSupport。

package com.TypeConverter;

import com.opensymphony.xwork2.ActionSupport;

//使用的是局部的类型转化器
public class useraction extends ActionSupport {
    private userbean userbean1;
    public userbean getUserbean1() {
        return userbean1;
    }
    public void setUserbean1(userbean userbean1) {
        this.userbean1 = userbean1;
    }
    public String execute(){
        System.out.println(userbean1.getUname());
        System.out.println("useraction");
        return SUCCESS;
    }
}

重点来了:我们需要新建类去继承DefaultTypeConverter,然后重写里面的方法。

这里的类名是TestType

package com.TypeConverter;

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

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

//
public class TestType extends DefaultTypeConverter {
    @Override
    public Object convertValue(Map<String, Object> context, Object value, Class toType) {
        //需要将字符串向userbean类型转换时
        if(toType==userbean.class){
            //系统的请求参数是一个字符串数组
            System.out.println("TestType");
            String params[] = (String[]) value;
            userbean user = new userbean();
            user.setUname(params[0]);
            user.setUpwd(params[1]);
            user.setUage(Integer.parseInt(params[2]));
            SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
            try {
                user.setUdate(s.parse(params[3]));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return user;
        }else if(toType==String.class){
            userbean user = (userbean) value;
            System.out.println("--------------------");
            return "<"+user.getUname()+">";
        }
        System.out.println("--------------------");
        return null;
    }
}

在这里笔者遇到一点小问题:就是使用

SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");

s.format(param[3]);

一直报错误:Unexpected Exception caught setting ‘userbean1‘ on ‘class com.TypeConverter.useraction: Error setting expression ‘userbean1‘ with value [‘admin‘, ‘123‘, ‘20‘, ‘1992-1-2‘, ],直到我把userbean中的udate类型改为Date类型才能够正常走,并且把s.format换成s.parse(param[3])。疑惑。

笔者测试代码走的顺序:

先走继承DefaultTypeConverter类的TestType,然后跳转到useraction类中的execute方法。

注意:我们还需要在建一个文件,告诉程序说,我们要把数据填充到类是哪一个?新建Actionname-conversion.properties

其中-conversion.properties是固定的,需要改变只是Actionname(表示继承ActionSupport的类,这里是useraction。对应struts.xml的class)

新建useraction-conversion.properties。放在同级目录下:

该文件的内容有:

这里的userbean1是你在useraction中实例化的名字。

后面的TestType是你继承DefaultTypeConverter类的名字。这里是TestType

代码运行结果如下:

Test.jsp界面

target.jsp界面效果:

target.jsp的代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>类型转化器输出结果</title>
</head>
<body>
    用户名:${userbean1.uname }<br/>
    密码:${userbean1.upwd }<br/>
    年龄:${userbean1.uage }<br/>
    生日:${userbean1.udate }<br/>
</body>
</html>

target.jsp的代码

2.3、全局类型转换

2.3.1、对指定的类型的全部属性有效。基本操作一样,只是有一点不同,properties文件放的位置和名字不同。

新建jsp页面,页面名:Test1.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>使用全局的类型转换器</title>
</head>
<body>
    <h2>使用全局的类型转换器</h2>
    <form action="Stubean">
    <label>用户名:</label><input type="text" name="stu"><br/>
    <label>年&nbsp;龄:</label><input type="text" name="stu"><br/>
    <input type="submit">
    </form>
</body>
</html>

Test1.jsp

新建实体类StuBean:

package com.TypeConverter.global;

public class StuBean {
    private String uname;
    private int uage;
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public int getUage() {
        return uage;
    }
    public void setUage(int uage) {
        this.uage = uage;
    }
}

StuBean

配置struts.xml

新建StuAction类继承ActionSupport

package com.TypeConverter.global;

import com.opensymphony.xwork2.ActionSupport;

//使用全局的类型转换器
//执行顺序:类型转换器——>execute

public class StuAction extends ActionSupport {
    private StuBean stu;

    public StuBean getStu() {
        return stu;
    }

    public void setStu(StuBean stu) {
        this.stu = stu;
    }

    public String execute(){
        System.out.println("StuAction");
        System.out.println(stu.getUname());
        return SUCCESS;
    }
}

StuAction

新建GlobalTypeConverter类继承StrutsTypeConverter,这里的StrutsTypeConverter是简化类型转换器,它是DefaultTypeConverter的子类。以下是代码:

package com.TypeConverter.global;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

public class GlobalTypeConverter extends StrutsTypeConverter {

    //转化为javabean对象
    @Override
    public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
        System.out.println("Global...");
        StuBean stu = new StuBean();
        stu.setUname(arg1[0]);
        stu.setUage(Integer.parseInt(arg1[1]));
        return stu;
    }

    //转化为String对象
    @Override
    public String convertToString(Map arg0, Object arg1) {
        StuBean s = (StuBean)arg1;
        return s.getUname()+"!!";
    }

}

GlobalTypeConverter

注意:全局与局部不同的地方在于properties文件名和放的位置不同,全局的文件名为:xwork-conversion.properties

位置在:

放在classes之下,有些没有classes文件,需要自己创建。

内容为:

前面的是该StuBean实体类的路径,后面的是继承StrutsTypeConverter类的类型转换器

如果要设置错误处理消息的话,我们可以添加一行代码,当页面出错的时候提示,这里笔者没有做,但是可以了解,添加代码为:

xwork.default.invalid.fieldvalue=提示消息

显示效果上面有介绍。如果你需要的话可以使用。

代码运行结果为:

Test1.jsp界面

target1.jsp界面

有谁能介绍一个录制操作的软件,谢谢。

以上就是Struts2 类型转换器的基本知识,有不足的请下方留言。谢谢。

时间: 2024-12-26 04:39:40

Struts2入门(三)——类型转换的相关文章

java struts2入门学习---异常处理和类型转换

https://www.cnblogs.com/amosli/p/3530577.html 一.struts2对异常的处理 1.自定义局部异常: <action> <exception-mapping result="sonException" exception="java.lang.ArithmeticException"></exception-mapping> </action> 2.自定义全局异常: <

IOS开发语言Swift入门连载---类型转换

IOS开发语言Swift入门连载-类型转换 类型转换可以判断实例的类型,也可以将实例看做是其父类或者子类的实例. 类型转换在 Swift 中使用is 和 as 操作符实现.这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型. 你也可以用来检查一个类是否实现了某个协议,就像在 Checking for Protocol Conformance部分讲述的一样. 定义一个类层次作为例子 你可以将它用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的

struts2中的类型转换

类型转换 所有的页面与控制器传递的数据都是String类型,在对其进行处理时可能会用到各种的数据类型,程序无法自动完成数据类型的转换,这就需要我们在代码中进行手手动操作,这个过程就称为类型转换. 内置类型转换器 在Web应用程序中,用户在视图层输入的数据都是字符串,业务控制层在处理这些数据时,就必须把从视图层传递过来的字符串进行类型转换.Struts2提供了简单易用的数据类型转换机制,struts2提供的类型转换如下: 1)String:将int.long.double.boolean.Stri

Flex入门(三)——微架构之Cairngorm

大家都知道我们在开发后台的时候,都会使用MVC,三层等分层架构,使后台代码达到职责更为分明单一,高内聚低耦合,例如,Dao层只是进行和数据库打交道,负责处理数据:Service(B层)只是进行逻辑判断处理,而Action则进行后台和前台页面的交互等.从而使程序更加容易管理,更加灵活,更加容易扩展,更加容易维护.也就是大家比较熟悉的Struts(SpringMVC)+Spring+Hibernate(Mybatis)等. 而作为前台Flex处理,也提供了类似的处理功能,想要达到的效果,也是代码分层

Swift语法基础入门三(函数, 闭包)

Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: func 函数名称(参数名:参数类型, 参数名:参数类型...) -> 函数返回值 { 函数实现部分 } 没有参数没有返回值 可以写为 ->Void 可以写为 ->() 可以省略 Void.它其实是一个空的元组(tuple),没有任何元素,可以写成() func say() -> V

Thinkphp入门三—框架模板、变量(47)

原文:Thinkphp入门三-框架模板.变量(47) [在控制器调用模板] display()   调用当前操作名称的模板 display(‘名字’)  调用指定名字的模板文件 控制器调用模板四种方式: [在控制器给模板传递变量] 在smarty里边给模板传递变量信息 $smarty -> assign(变量名称,值); 在tp框架里边同样适用assign()给模板传递变量信息 ThinkPHP的模板引擎的左右标记: ThinkPHP/Lib/ Behavior/ ParseTemplateBe

Redbean:入门(三) - Exec 以及 Query 以及 ConvertToBeans

<?php //引入rb入口文件 include_once 'rb.php'; //定义dsn以及相关的数据 $dsn = 'mysql:host=localhost;dbname=hwibs_model'; $user = 'root'; $pass = ''; $table = 'link'; //链接数据库 R::setup($dsn,$user,$pass); //链接数据表 R::dispense($table); //exec::直接执行一条sql语句[不需要链接表即可使用][参数2

AppleWatch开发入门三——代码交互与控制器生命周期

AppleWatch开发入门三--代码交互与控制器生命周期 一.引言 在前两篇博客中,讨论了关于watch开发中框架与界面布局相关,然而主要的逻辑,终究还是要通过代码来实现的,在我们创建了项目之后,就会生成InterfaceController这个文件,它就是我们storyBoard中的入口视图控制器. 二.代码交互与控制器声明周期 storyBoard中的控件我们可以通过拖拽的方式关联到文件中,Action和Outlet两种关联方式基本可以达到我们修改控件和处理业务逻辑的需求. WKInter

kafka入门三:写第一个Kafka应用

一.整体看一下Kafka 我们知道,Kafka系统有三大组件:Producer.Consumer.broker . producers 生产(produce)消息(message)并推(push)送给brokers,consumers从brokers把消息提取(pull)出来消费(consume). 二.开发一个Producer应用 Producers用来生产消息并把产生的消息推送到Kafka的Broker.Producers可以是各种应用,比如web应用,服务器端应用,代理应用以及log系统等