struts2的类型转换

1.struts2可以自动转换8大基本数据类型和String以及Date类型

login.jsp:

login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
     
     <form action="login" method="post">
     
     username:<input type="text" value="" name="username"/><br/>
     password:<input type="password" name="password" value="" /><br/>
     age:<input type="text" name="age"/><br/>
     time:<input type="text" name="time"/><br/>
     <input type="submit" value="提交" />
     
     </form>
    
  </body>
</html>
View Code

LoginAction.java:

package com.shensiyuan.struts.action;

import java.util.Date;

public class LoginAction {
    private String username;
    private String password;
    private int age;
    private Date time;
    public void setUsername(String username) {
        this.username = username;
    }
    public String getUsername() {
        return username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getPassword() {
        return password;
    }
    
    public String execute(){
        return "success";
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public void setTime(Date time) {
        this.time = time;
    }
    public Date getTime() {
        return time;
    }

}
View Code

result.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'result.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    username:${requestScope.username }<br/>
    password:${requestScope.password }<br/>
    age:${requestScope.age }<br/>
    time:${requestScope.time }
  </body>
</html>
View Code

struts.xml:

    
        <action name="login" class="com.shensiyuan.struts.action.LoginAction">
            <result name="success">/result.jsp</result>
        </action>
        
View Code

当前台页面为这种格式的时候,result得到这种结果

后台控制器报了一点转换错误

原理:

login.jsp中form的action属性为:login
没有特别设置,默认视为以.action结尾
首先被struts2过滤器过滤--->进入struts.xml 查找对应name为login的action,进入此文件
struts.xml中package默认继承struts-default package
在action中调用各种getset方法进行一系列默认操作,执行execute方法
execute方法返回的字符串与result中name字段对比,进入对应结果页面

struts自动赋值:
注意:
jsp页面表单标签name属性值对应action中的setXXX(),而并不是action中的属性名。比如name等于name,对应的是setName方法,这是老师说的。不过我认为当成Action中的属性明比较好理解些

struts自动转换,它会根据你的setXXX方法,将参数转化为需要的参数类型,如果可以不能转化成功,抛出异常
例如,age属性为int setAge的参数为int类型,struts就会自动将得到的参数尝试转化为int类型使用。time类型为Date,struts、也会尝试将Settime参数转化为Data类型

 

-----------------------------------------------------------------------------

 

使用转换器转换对象属性。

struts2的类型转换,对于8个原生数据类型以及Date,String等常见类型,Struts2可以使用内奸的类型转换器实现自动的转换;但是对于自定义的对象类型来说,需要我们指定类型转换的方式

知识点:

转换器:

DefaultTypeConverter类,在ognljar包中

参数: Object为要被转换的对象,Class为想要转换成为的类型

如何调用转换器?

在Action的setXXX()方法给属性赋值的时候,需要先将参数值进行转换成属性对应的类型。如果是8大数据类型String或者Date,则调用默认转换器,要使用我们的转换器,需要在Action的同一目录下定义一个XX-conversion.properties XX为Action名

xml中内容:键值对 key:Action中需要使用转换器转换的属性  Value:转换器的地址

例如:user=com.shensiyuan.struts.converter.UserConverter2

StrutsTypeConverter继承DefaultTypeConverter的抽象类。使用这个对象显得更加标准符合规范,后面都使用这个。

/*
 * $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.struts2.util;

import java.util.Map;

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

/**
 * <!-- START SNIPPET: javadoc -->
 *
 * Base class for type converters used in Struts. This class provides two abstract methods that are used to convert
 * both to and from strings -- the critical functionality that is core to Struts's type coversion system.
 *
 * <p/> Type converters do not have to use this class. It is merely a helper base class, although it is recommended that
 * you use this class as it provides the common type conversion contract required for all web-based type conversion.
 *
 * <p/> There's a hook (fall back method) called <code>performFallbackConversion</code> of which
 * could be used to perform some fallback conversion if <code>convertValue</code> method of this
 * failed. By default it just ask its super class (Ognl's DefaultTypeConverter) to do the conversion.
 *
 * <p/> To allow the framework to recognize that a conversion error has occurred, throw an XWorkException or
 * preferable a TypeConversionException.
 *
 * <!-- END SNIPPET: javadoc -->
 *
 */
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);
}
View Code

 

input.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>Insert title here</title>
</head>
<body>

  <form action="user" method="post">

     <h1>用户名和密码之间用“;”隔开</h1>

     userInfo:<input type="text" name="user" /><br/>
     <input type="submit" value="submit"/>"


 </form>

</body>
</html>
View Code

User.java:

package com.shensiyuan.struts.bean;

public class User {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

}
View Code

struts.jsp:

<action name="user" class="com.shensiyuan.struts.action.UserAction">
            <result name="success">/output.jsp</result>
        </action>
View Code

UserAction.java:

package com.shensiyuan.struts.action;

import com.opensymphony.xwork2.ActionSupport;
import com.shensiyuan.struts.bean.User;


public class UserAction extends ActionSupport {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String execute(){
        //System.out.println("username:"+user.getUsername());
        //System.out.println("password:"+user.getPassword());
        return SUCCESS;
    }

}
View Code

UserConverter.java:

package com.shensiyuan.struts.converter;

import java.util.Map;
import java.util.StringTokenizer;

import com.shensiyuan.struts.bean.User;

import ognl.DefaultTypeConverter;

public class UserConverter extends DefaultTypeConverter {
    @Override
    public Object convertValue(Map m,Object value,Class cla){
        //System.out.println(cla);
        /**
         * 这里主要使用到的参数就是value和cla两个参数,前者代表在jsp页面获取到的值,后者代表要转换成为的数据类型
         * 当要转换成为的数据类型为User这一对象类型的话执行代码
         * 首先接受再jsp中控件name属性对应的值,因为多个控件有可能name属性值相同,所以得到的value是一个数组形式
         * 根据jsp源码我们可以知道我们只需要得到jsp中name属性值的数组的第0位置的元素
         * 使用StringTokenizer类的构造方法将字符串分隔成数组StringTokenizer(str,spiltchar)两个参数分别代表要分割的字符串和分隔依据字符
         * 使用nextToken()将分割得到的字符串一一赋值到指定对象中,并返回该对象
         */
        if(User.class.equals(cla)){
            String[] content=(String[])value;
            StringTokenizer str=new StringTokenizer(content[0],";");
            User user=new User();
            user.setUsername(str.nextToken());
            user.setPassword(str.nextToken());
            return user;
        }else if(String.class.equals(cla)){
            User content=(User)value;
            String userInfo="username: "+content.getUsername()+",password: "+content.getPassword();
            return userInfo;
        }
        return null;
    }

}
View Code

output.jsp:  注意output.jsp使用的是struts标签获取的user,这样才能走set方法转换类型,使用EL得到的是一个地址

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<s:property value="user"/>
</body>
</html>
View Code

UserAction-conversion.properties位置:

我把版面排过来了

 

使用StrutsToTypeConverter:

package com.shensiyuan.struts.converter;

import java.util.Map;
import java.util.StringTokenizer;

import org.apache.struts2.util.StrutsTypeConverter;

import com.shensiyuan.struts.bean.User;

public class UserConverter2 extends StrutsTypeConverter {

    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        User user=new User();
            String content=values[0];
            StringTokenizer s=new StringTokenizer(content,";");
            String username=s.nextToken();
            String password=s.nextToken();
            user.setUsername(username);
            user.setPassword(password);
        return user;
    }

    @Override
    public String convertToString(Map context, Object o) {
        User user=(User)o;
        String userInfo="username: "+user.getUsername()+",password: "+user.getPassword();
        return userInfo;
    }

}
View Code

 

---------------------------------------------

 

使用转换器批量转换

input.jsp:

    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>Insert title here</title>
</head>
<body>

  <form action="user2" method="post">

     <h1>用户名和密码之间用“;”隔开</h1>

     userInfo1:<input type="text" name="user" /><br/>
     userInfo2:<input type="text" name="user" /><br/>
     userInfo3:<input type="text" name="user" /><br/>
     userInfo4:<input type="text" name="user" /><br/>
     <input type="submit" value="submit"/>"


 </form>

</body>
</html>
View Code

UserAction2.java:

package com.shensiyuan.struts.action;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;
import com.shensiyuan.struts.bean.User;

public class UserAction2 extends ActionSupport {
    private List<User> user;

    public void setUser(List<User> user) {
        this.user = user;
    }

    public List<User> getUser() {
        return user;
    }
    
    public String execute(){
        return SUCCESS;    
    }

}
View Code

注意换了一个Action,需要重新书写一个properties文件

UserConverter3:

package com.shensiyuan.struts.converter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.struts2.util.StrutsTypeConverter;

import com.shensiyuan.struts.bean.User;

public class UserConverter3 extends StrutsTypeConverter{

    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        ArrayList<User> user=new ArrayList<User>();
        for(String value:values){
            User u=new User();
            StringTokenizer stk=new StringTokenizer(value,";");
            String username=stk.nextToken();
            String password=stk.nextToken();
            u.setUsername(username);
            u.setPassword(password);
            user.add(u);
        }
        return user;
    }

    @Override
    public String convertToString(Map context, Object o) {
        ArrayList<User> user=(ArrayList<User>)o;
        StringBuffer sb=new StringBuffer();
        Iterator<User> it=user.iterator();
        for(;it.hasNext();){
            User u=it.next();
            sb.append("username:"+u.getUsername()+",password:"+u.getPassword()+"<br/> ");
        }
        return sb.toString();
    }

}
View Code


全局类型转换:

前面的类型转换只能在一个Action中使用,现在我们要使得类型转换器在整个项目中都可以使用,就需要使用全局转换。

与前面没有太大区别,不过是在src下面建立了一个xwork-conversion.properties,然后每次遇到对应的类型转换,就会通过properties找到对应的转换器

properties的代码:

#全局转换器  整个项目的该对象都会转换
#  key:全局被转换的对象类型  value:转换器名
com.shensiyuan.struts.bean.User=com.shensiyuan.struts.converter.UserConverter2
View Code

 

posted @ 2016-03-09 22:58  guodaxia  阅读(203)  评论(0编辑  收藏  举报