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>
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; } }
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>
struts.xml:
<action name="login" class="com.shensiyuan.struts.action.LoginAction">
<result name="success">/result.jsp</result>
</action>
当前台页面为这种格式的时候,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); }
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>
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; } }
struts.jsp:
<action name="user" class="com.shensiyuan.struts.action.UserAction">
<result name="success">/output.jsp</result>
</action>
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; } }
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; } }
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>
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; } }
---------------------------------------------
使用转换器批量转换
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>
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; } }
注意换了一个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(); } }
全局类型转换:
前面的类型转换只能在一个Action中使用,现在我们要使得类型转换器在整个项目中都可以使用,就需要使用全局转换。
与前面没有太大区别,不过是在src下面建立了一个xwork-conversion.properties,然后每次遇到对应的类型转换,就会通过properties找到对应的转换器
properties的代码:
#全局转换器 整个项目的该对象都会转换
# key:全局被转换的对象类型 value:转换器名
com.shensiyuan.struts.bean.User=com.shensiyuan.struts.converter.UserConverter2