将root 当成arraylist放入数据sturts2 入门笔记

刚启动idea 就报出错误 

[2019-04-14 03:08:22,780] Artifact 05-sturts2:war exploded: Error during artifact deployment. See server log for details.

解决办法:

file-project structure -probleam 里面有一个fix

第二个错误:

就是需要的jar包没有加全

这几个是创建idea 时自带的jar包,我使用的jar包是5版本的
commons-fileupload.jar commons-io.jar commons-lang.jar freemarker.jar log4j.jar ognl.jar struts2-core.jar

这个时候运行报错

需要再添加上几个jar包

asm-5.2.jar
asm-commons-5.2.jar
asm-tree-5.2.jar
commons-lang3-3.8.1.jar
javassist-3.20.0-GA.jar

这个时候idea 自动生生的sturts.xml文件是标错的

idea的配置文件扫描的类是

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

但是新的jar包中去掉了ng这个包,所以只需要改成下面的就可以了。学完springmvc后再看sturts2 真是挺简单的。

org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

 

下面对jar包进行一下分析

 


asm-5.2.jar
asm-commons-5.2.jar  
asm-tree-5.2.jar        红色的是用于实现代理的主要jar包
javassist-3.20.0-GA.jar
 commons-lang3-3.8.1.jar javassist-3.20.0-GA.jar
commons-fileupload.jar
commons-
io.jar 文件上传
commons-lang.jar 这个是定义的基本数据类型以及对它的扩展
freemarker.jar stutrs2 的ui
log4j.jar 日志
ognl.jar 对象图导航语言,是一种表达式是一个独立的项目是被sturts2引进来的
struts2-core.jar 核心jar包

X先放上一个简单的例子
jsp

<%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2019/4/14
  Time: 15:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form name="f1" action="loginaction/login.action" method="post">
   姓名: <input type="text" name="name"/>
   年龄: <input type="password" name="password"/>
     <input type="submit" value="提交"/>

  </form>
  </body>
</html>
index.jsp

sturts.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <package name="loginaction" namespace="/loginaction" extends="struts-default">
        <action name="login" class="com.sturts2.action.loginAction">
            <result name="success">/welcome.jsp</result>

        </action>
    </package>
    
</struts>
sturts.xml
<%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2019/4/14
  Time: 15:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

name =${name}
password = ${password}
</body>
</html>
welcome.jsp

需要注意的地方就是你的表单的属性名 name 必须要和你的实体类中的名字相同

讲解一下配置文件的加载顺序

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>      表单中的action中的地址就是loginaction/login.action 也就是名称空间加上 标签<action>中的name 从而找到要加载的试题类loginAction ,如果没有在
<action>标签中指定method 那么 所执行的action 方法 也就是 execute 这个名字不能变否则找不到
必须要写成 public String execute(){ return "success"} 否则不会执行 正好对应标签中的 <result>标签中的success
<package name="loginaction" namespace="/loginaction" extends="struts-default"> <action name="login" class="com.sturts2.action.loginAction"> <result name="success">/welcome.jsp</result> </action> </package> </struts>

 

struts.properties 文件修改默认配置

 

 struts.xml 修改访问路径的后缀名   

action="loginaction/login.do"   
action="loginaction/login.php"
action="loginaction/login.html"
struts.action.extension=do,php,html

 

web.xml 和struts.properties 和struts.xml 相比谁的优先级比较高

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
        <param-name>struts.action.extension</param-name>
        <param-value>do</param-value>
    </init-param>
    
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <constant name="struts.action.extension" value="go"></constant>
    <package name="loginaction" namespace="/loginaction" extends="struts-default">
        <action name="login" class="com.sturts2.action.loginAction">
            <result name="success">/welcome.jsp</result>

        </action>
    </package>
    
</struts>

 

 

运行后可知,web.xml>struts.properties>struts.xml

但是我们一般不在web.xml 或者struts.properties中进行设置。

 

struts.xml包命名问题

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <constant name="struts.action.extension" value="go"></constant>
    <package name="aaa-bbb-loginaction" namespace="/aaa/bbb/loginaction" extends="struts-default">
        <action name="login" class="com.sturts2.action.loginAction">
            <result name="success">/welcome.jsp</result>

        </action>
  <package name="aaa-loginaction" namespace="/aaa/loginaction" extends="struts-default">
        <action name="login" class="com.sturts2.action.loginAction">
            <result name="success">/welcome.jsp</result>

        </action>
</package> </struts>

一般如果我们有多个package 那么package 中的name 与namespace都是相对应的

name="aaa-bbb-loginaction" namespace="/aaa/bbb/loginaction"
 name="aaa-loginaction" namespace="/aaa/loginaction"
而且,namspace中也可以不写但是namespace中至少要写上/
 

接下来添加配置文件的属性

<package name="register" namespace="/registeraction" extends="struts-default">
        <action name="register" class="com.sturts2.action.RegisterAction" method="register">  加上这个就意味着我们可以自定义方法名而不是execute
            <result name="success">/register.jsp</result>

        </action>
    </package>
我们默认的页面是进行转发
<result type="dispatcher" name="success">/register.jsp</result>

下面是进行重定向
<result type="redirect" name="success">/welcome.jsp?uname=${name}&amp;upassword=${password}</result>

 还有另外一种写法

 <package name="loginaction" namespace="/loginaction" extends="struts-default">
        <action name="login" class="com.sturts2.action.loginAction">
            <!--<result name="success">/welcome.jsp</result>-->
           <!-- <result type="redirect" name="success">/welcome.jsp?uname=${name}&amp;upassword=${password}</result>-->
            <result type="redirectAction" name="success">
                <param name="actionMapper">actionName</param>
               <param name="uname">${uname}</param>
               <param name="upassword">${upassword}</param>

            </result>

        </action>
        <action name="actionName">
            <result name="success">/welcome.jsp</result>
        </action>
    </package>

 

解决配置文件冗余

先看一个例子

<package name="some" namespace="/someAction" extends="struts-default">
    <action name="first" class="com.sturts2.action.someAction" method="doFirst">
        <result name="ar">/apage.jsp</result>
        <result name="br">/bpage.jsp</result>
        <result name="success"> /welcome.jsp</result>

    </action>
<action name="second" class="com.sturts2.action.someAction" method="doSecond">
    <result name="ar">/apage.jsp</result>
    <result name="br">/bpage.jsp</result>
    <result name="success">/welcome.jsp</result>

</action>
    
</package>

这些都是重复的代码下面就是简化

包范围全局视图

<package name="some" namespace="/someAction" extends="struts-default">
    <global-results>
        <result name="ar">/apage.jsp</result>
        <result name="br">/bpage.jsp</result>
    </global-results>
    
    <action name="first" class="com.sturts2.action.someAction" method="doFirst">
        <result name="success"> /welcome.jsp</result>
    </action>

    <action name="second" class="com.sturts2.action.someAction" method="doSecond">
        <result name="success">/welcome.jsp</result>
    </action>
    
</package>

继续抽取

<!--这个包不定义action也就不会被访问,所以名称空间也可以省略了那么也可以定义成抽象的,一旦定义成抽象的就不能再定义action-->
<package name="basepackage"  extends="struts-default" abstract="true">
    <global-results>
        <result name="ar">/apage.jsp</result>
        <result name="br">/bpage.jsp</result>
    </global-results>

</package>
    <package name="some" namespace="/someAction" extends="struts-default">
        <action name="first" class="com.sturts2.action.someAction" method="doFirst">
            <result name="success"> /welcome.jsp</result>
        </action>

        <action name="second" class="com.sturts2.action.someAction" method="doSecond">
            <result name="success">/welcome.jsp</result>
        </action>
    </package>

 值栈操作(想root中显示放入数据)

package com.sturts2.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * Description: 05-sturts2
 * Created by lenovo on 2019/4/14 22:18
 */
public class resolveValueStack {

    public String execute(){
           //从request域中获取valueStack
        String key = ServletActionContext.STRUTS_VALUESTACK_KEY;
        HttpServletRequest request = ServletActionContext.getRequest();

        ValueStack value_stack = (ValueStack) request.getAttribute(key);
/*
        Map<String, Object> context = value_stack.getContext();
*/
       //解析这个root属性的本质是ArrayList 特点存入的数据是无名对象,只有对象没有名称 然后将user对象进行了压栈
        loginAction user = new loginAction("zhangsan", "23");
        value_stack.getRoot().push(user);

       //有名对象就是放入到map中
        HashMap<String, loginAction> map = new HashMap<>();
        loginAction user1 = new loginAction("lisi", "23");
        map.put("user1",user1);
         value_stack.push(map);
         //向值栈中直接放入有名对象,即map
        loginAction user2 = new loginAction("wangwu", "23");
        value_stack.set("user2",user2);
        loginAction user3 = new loginAction("zhaoliu", "23");

        /*取出一个进行查看将root当成arraylist*/
        value_stack.getRoot().get(2);
        value_stack.getRoot().add(user3);
        return "success";
    }
}
<%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2019/4/14
  Time: 15:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

  PI = <s:property value="@java.lang.Math@PI"></s:property>
  random = <s:property value="@java.lang.Math@random()*100 "></s:property>
 <%-- <form name="f1" action="loginaction/login.action" method="post">
   姓名: <input type="text" name="name"/>
   年龄: <input type="password" name="password"/>
     <input type="submit" value="提交"/>

  </form>

  <a href="registeraction/register.action">注册</a>--%>
  <%--读取非根数据--%>
  <s:property value="#city"></s:property>

  <s:debug></s:debug>

 name: <s:property value="name"></s:property>
  age: <s:property value="age"></s:property>
 name: <s:property value="user1.name"></s:property>
  age: <s:property value="user1.age"></s:property>

 name: <s:property value="user2.name"></s:property>
  age: <s:property value="user2.age"></s:property>

  </body>
</html>

 

向root中隐士放入数据
当请求到来的时候将数据放在了root 和context 中 带有#号的数据从contxt中获取数据,不带#的从root中获取数据

<%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2019/4/14
  Time: 15:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

  PI = <s:property value="@java.lang.Math@PI"></s:property>
  random = <s:property value="@java.lang.Math@random()*100 "></s:property>
 <%-- <form name="f1" action="loginaction/login.action" method="post">
   姓名: <input type="text" name="name"/>
   年龄: <input type="password" name="password"/>
     <input type="submit" value="提交"/>

  </form>

  <a href="registeraction/register.action">注册</a>--%>
  <%--读取非根数据--%>
  <s:property value="#city"></s:property>

  <s:debug></s:debug>

 name: <s:property value="name"></s:property>
  age: <s:property value="age"></s:property>
 name: <s:property value="user1.name"></s:property>
  age: <s:property value="user1.age"></s:property>
  <%--request.name 底层执行的是request.getAttribute("name")--%>
  request.name: <s:property value="#request.name"></s:property>
  request.age: <s:property value="#request.age"></s:property>

 name: <s:property value="user2.name"></s:property>
  age: <s:property value="user2.age"></s:property>
<%--底层执行的是request.getParameter("name")--%>
  parameters.name: <s:property value="#parameters.name"></s:property>
  parameters.age: <s:property value="#parameters.age"></s:property>

  action.name: <s:property value="action.name"></s:property>
  action.age: <s:property value="action.age"></s:property>
  </body>
</html>

 数据的加载顺序,先找root 再找 context

request中的加载循序,当通过action将值保存在context 和root中的值不同时,分别获取到自己存放的相应的值,但是如果通过request进行获取,那么就会取到和root

中的值相同的结果。

 

OGNL标签

List

<s:set var="mylist" value="{'zs','li','wu'}">
      <s:iterator value="#mylist">
        <s:property/>   尽管没有指定但是也取到了相应的值<%--iterator默认会将当前的迭代对象放入到值栈栈顶--%> <%--properties 标签默认会输出值栈栈顶元素--%>
 </s:iterator> </s:set>

 

Map

<s:set var="mymap" value="#{'mobile':'123456','qq':'12455'}">
      <s:iterator value="#mymap" var="entity">
          <s:property value="entity"/>
      </s:iterator>

      <s:iterator value="#mymap">
          <s:property value="key"/> =<s:property value="value"/>
      </s:iterator>
  </s:set>
  

集合元素的判断

  <s:property value="'zs' in  #mylist"/>
  <s:property value="'zs' not in  #mylist"/>

创建bena

<%--创建bena--%>

     <s:bean name="com.sturts2.java.Student" var="student2">
         <s:param name="name" value="'zhangsna'"/>
         <s:param name="age" value="2"/>

     </s:bean>
     <s:bean name="com.sturts2.java.Student" var="student3">
         <s:param name="name" value="'lisi'"/>
         <s:param name="age" value="2"/>

     </s:bean>
     <s:bean name="com.sturts2.java.Student" var="student4">
         <s:param name="name" value="'wu'"/>
         <s:param name="age" value="2"/>

     </s:bean>

  <%--集合投影将前面的三个Student对象的name 属性值再组成一个list--%>
  <s:set var="students" value="{student2,student3,student4}"/>
  <s:set var="studentsnames" value="#students.{name}"/>
  <s:iterator value="#studentsnames">

      <s:property/> 
  </s:iterator>



  <s:property value="#student2"/>

 

集合查询

 

 

 动态方法调用

 

 

 

 

  public String doFirst(){
        if("aaa".equals(name)){
            return "ar";
        }


        if ("bbb".equals(name)){
            return "br";
        }
        return "success";

    }

     public String doSecond(){
       if (age<15){
             return "ar";

         }
       if (age>60){
             return "br";
        }
        return "welcome";
     }

 

 

 <package name="some" namespace="/someAction" extends="basepackage">
        <action name="first" class="com.sturts2.action.someAction" method="doFirst">
            <result name="success"> /welcome.jsp</result>
        </action>

        <action name="second" class="com.sturts2.action.someAction" method="doSecond">
            <result name="success">/welcome.jsp</result>
        </action>
    </package>

 

 这种方式显得代码不够灵活,使用动态方法调用

  <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
    <package name="some" namespace="/someAction" extends="basepackage">
        <action name="some" class="com.sturts2.action.someAction">
            <result name="success"> /welcome.jsp</result>
        </action>


    </package>

在浏览器中进行访问的时候需要在命名空间后加上!后面带上你的方法名

http://localhost:8087/soneAction!doFirst.action

 请求接收参数

属性驱动方式

服务端接收客户端离散数据的方式(也即是单个值进行接收)

在 Action 类中定义与请求参数同名的属性,即,要定义该属性的 set 方法。这样就能够使 Action 自动将请求参数的值赋予同名属性

我也觉得没有什么特殊的啊,不就是正常的接收值吗,

 <input type="text" name="name"/>
      <input type="text" name="age"/>

 

域驱动方式(也就是将值封装到一个对象中进行接收)

服务器端以封装好的对象方式接收来自客户端的数据方式。将用
户提交的多个数据以封装对象的方式进行整体接收。该方式要求,表单提交时,参数以对象
属性的方式提交。而 Action 中要将同名的对象定义为属性(为其赋予 getter and setter)。这
样请求将会以封装好的对象数据形式提交给 Action。

 <input type="text" name="student.name"/>
      <input type="text" name="student.age"/>
执行过程还是比较复杂的

对象类型数据接收的内部执行过程比较复杂:
(1)当将表单请求提交给服务器后,服务器首先会解析出表单元素,并读取其中的一个元
素 name 值,如读取出如下:
(2)执行 Action 的 getStudent()方法以获取 Student 对象。判断 Student 对象是否为 null,
若为 null,则服务器会通过反射创建一个 Student 对象。
(3)由于此时的 Student 对象为 null,所以系统会创建一个并调用 setStudent()方法将 student
初始化。
(4)此时的 student 已非空,会将刚才解析出的表单元素,通过调用其 set 方法,这里是
setName()方法,将用户输入的值初始化该属性。
(5)再解析下一个表单元素,并读取其 name 值。
(6)再次执行 Action 的 getStudent()方法以获取 Student 对象。此时的 Student 对象已非空。
(7)将刚才解析出的表单元素,通过调用其 set 方法,这里是 setAge()方法,将用户输入的
值初始化该属性。

集合数据接收

所谓集合数据接收是指,以集合对象方式接收数据。此情况与域驱动接收数据原理是相
同的。注意,集合与数组是不同的

 <form name="" action="">
      <input type="text" name="name"/>
      <input type="text" name="age"/>

      <input type="text" name="student[0].name"/>
      <input type="text" name="student[0].age"/>

      <input type="text" name="student[1].name"/>
      <input type="text" name="student[1].age"/>



  </form>

 

public class Student {

    private List<Student> students;

    public String execute(){
    
    return  "success";
}
}

此时用于接收集合数据的属性,不能定义为数组。因为数组长度是固定的,而集合长度
是可扩展的。

姓名1:${students.get(0).name}
  年龄1:${students.get(0).age}

  姓名2:${students[1].name)}
  年龄2:${students[2].age}

 

类型转换

 int 和 Integer

long 和 Long

float 和 Float

double 和 Double

char 和 Character

boolean 和 Boolean

Date:

可以接收 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss 格式字符串

数组:可以将多个同名参数,存放到到数组

集合:可以将数据保存到 List、Map 

3 自定义类型转换器

在上面程序中,若输入非 yyyy-MM-dd 格式,如输入 yyyy/MM/dd 格式,在结果页面中
还可以正常看到 yyyy/MM/dd 的日期输出。但查看控制台,却给出了 null 值。其实底层已经
发生了类型转换失败,抛出了类型转换异常 TypeConversionException。若要使系统可以接收
其它格式的日期类型,则需要自定义类型转换器。
查看 DateConverter、NumberConverter 等系统定义好的类型转换器源码,可以看到它们
都是继承自 DefaultTypeConverter 类。所以,我们要定义自己的类型转换器,也要继承自该
类。在使用时,一般需要覆盖其父类的方法 convertValue(),用于完成类型转换。

定义 convertValue 方法时需要注意,其转换一般是定义为双向的。
就本例而言,从浏览器表单请求到服务器端 action 时,是由 String 到 Date 的转换,那
么,第一个参数 value 为 String 类型的请求参数值,第二个参数 toType 为要转换为的 Date
类型。
当类型转换成功,但服务器端其它部分出问题后,需要返回原页面。此时用户填写过的
数据应重新回显。回显则是由服务器端向浏览器端的运行,需要将转换过的 Date 类型重新
转换为 String。那么,此时的 value 则为 Date 类型,而 toType 则为 String。
注意第一个参数 value,若转换方向为从请求到 action,则 value 为字符串数组。因为请
求中是允许携带多个同名参数的,例如下面表单中的兴趣爱好项的 name 属性为 hobby,其
值就有可能为多个值。

 

 

 <form name="" action="">

      <input type="checkbox" name="hobby" value="fitness"/> 健身
      <input type="checkbox" name="hobby" value="running"/>跑步
      <input type="checkbox" name="hobby" value="swing"/>游泳

  </form>

 

这时的这个同名参数,其实就是数组。Struts2 为了兼顾到这种多个同名参数的情况,
就将从请求到 action 方向转换的 value 指定为了 String[],而非 String。其底层使用的 API 为:
String[] value = request.getParameterValues(…);
注意,对于服务器端向浏览器端的转换,需要使用 Struts2 标签定义的表单才可演示出。
演示时,age 元素填入非数字字符,birthday 填写正确。另外,向<action/>中添加 input 视图,
Action 类需要继承 ActionSupport 类。
只所以要继承自 ActionSupport 类,是因为 ActionSupport 类实现了 Action 接口,而该接
口中定义了 INPUT 字符串常量。一旦发生类型转换异常 TypeConversionException,系统将自
动转向 input 视图

 <s:form action="" method="">
     <s:textfield name="age" label="年龄"></s:textfield>
      <s:textfield name="birthday" label="生日"></s:textfield>
      <s:submit value="提交"></s:submit>
  </s:form>
public class Student extends ActionSupport {

    private int age;
    private Date birthday;



    public String execute(){
    System.out.println(birthday);
    return  "success";
}
}

Date 在这里自动导入的是 java.sql 包中的,而我们需要的是 java.util 包中
的 Date。

 

package com.sturts2.action;

import ognl.DefaultTypeConverter;

import javax.management.ValueExp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * Description: 05-sturts2
 * Created by lenovo on 2019/4/17 9:17
 */
public class MyDateConverter extends DefaultTypeConverter {

    @Override
    public Object convertValue(Map context, Object value, Class toType) {

        SimpleDateFormat format = new SimpleDateFormat("yyyy/MMM/ss");

        //由页面到服务端方向,是由String到Date的转换
        try {

            if (toType== Date.class){
                System.out.println("从页面到服务端");
                String[] params = (String[]) value;
                return format.parse(params[0]);
            }else if (toType==String.class){
                System.out.println("从服务端到页面");
                Date date = (Date) value;
                return format.format(date);
            }



        } catch (ParseException e) {
            e.printStackTrace();
        }


        return super.convertValue(context, value, toType);
    }
}

定义好类型转换器后,需要注册该转换器,用于通知 Struts2 框架在遇到指定类型变量
时,需调用类型转换器。
根据注册方式的不同及其应用范围的不同,可以将类型转换器分为两类:局部类型转换
器、全局类型转换器。

局部类型转换器

局部类型转换器,仅仅对指定 Action 的指定属性起作用。若注册方式为,在 Action 类
所在的包下放置名称为如下格式的属性文件:ActionClassName-conversion.properties 文件。
其中 ActionClassName 是 Action 类名,-conversion.properties 是固定写法。就本例而言,该
注册文件的名称应为 SomeAction-conversion.properties。
该属性文件的内容遵循如下格式:属性名称=类型转换器的全类名。就本例而言,文件
中的内容为:birthday= com.abc.converters.MyDateConverter。

全局类型转换器

全局类型转换器,会对所有 Action 的指定类型的属性生效。其注册方式为, 在 src 目
录下放置名称为 xwork-conversion.properties 属性文件。该文件的内容格式为:待转换的类
型=类型转换器的全类名。就本例而言,文件中的内容为:
java.util.Date=com.abc.converters.MyDateConverter

注意,对于服务器端向浏览器端的转换,即数据的回显功能,需要使用 Struts2 标签定
义的表单才可演示出。演示时,age 元素填入非数字字符,birthday 填写正确

 

posted @ 2019-04-14 15:21  纳兰容若♫  阅读(205)  评论(0编辑  收藏  举报