类型转换
1.什么是类型转换?
View层提交过来的数据与后台程序无法自动完成它们之间的数据类型转换,需要开发者用代码来完成,这个完成的过程就是类型转换。
比如JSP阶段学习到的:
String ages = request.getParameter(“age”); int age = Integer.parseInt(ages); |
这里将String类型转换成int类型,就是硬编码实现了转换。
Struts 2的类型转换分:自动类型转换、自定义类型转换。
自动类型转换由struts2提供。
自定义类型转换需要编写转换器。
2.Struts2内置自动类型转换器
表单中所有输入的值都将作为String类型提交到相应的Action,至于如何将这些String类型转换为Action中的属性的类型是需要做一些判断的,Struts2中默认有一个类型转换器,可以帮助我们完成大部分的自动转换操作。其支持的从String类型转换的目标类型如下:
String和boolean、Boolean | 完成字符串与布尔值之间的转换 |
String和char、Character | 往常字符串与字符之间的转换 |
String和int、Integer | 完成字符串与整型之间的转换 |
String和long、Long | 完成字符串与长整型值之间的转换 |
String和double、Double | 完成字符串与双精度浮点值的转换 |
String和float、Float | 完成字符串和单精度浮点之间的转换 |
String和Date | 完成字符串和日期类型之间的转换,可以接收yyyy-MM-dd格式字符串 |
String和数组 | 可以将多个同名参数,转换到数组中 |
String和Map、List | 支持将数据保存到List或者Map集合 |
在Action中的属性类型,如果是以上这些类型,那么从客户端提交的过来的字符串就可以默认使用该机制自动转换成对应的类型,完成自动赋值。如果不是上述的类型,那么就需要自定义类型转换器来实现显式的转换类型。
案例1:
View代码:
<form action="${pageContext.servletContext.contextPath}/converterAction.action"> 用户名:<input type="text" name="name"><br> 密码:<input type="password" name="password"><br> 年龄:<input type="text" name="age"><br> 生日:<input type="text" name="birthday"><br> 兴趣:<input name="hobby" type="checkbox" value="音乐">音乐 <input name="hobby" type="checkbox" value="电影">电影<br> <input type="submit" value="提交"> </form> |
Action代码:
public class ConverterAction extends ActionSupport { private String name; private String password; private int age; private Date birthday; private String[] hobby; //此处省略setter和getter方法
@Override public String execute() throws Exception { //输出属性值,发现从form表单中接收到的String类型数据已自动转换 System.out.println(“姓名:”+this.name); System.out.println(“密码:”+this.password); System.out.println(“年龄:”+this.age); System.out.println(“生日:”+this.birthday); for(String s: hobby){ System.out.println(s); } return SUCCESS; } } |
Struts.xml
<struts> <package name="mypackage" extends="struts-default"> <action name="converterAction" class="com.zking.ConverterAction"> <result name="success">/success.jsp</result> </action> </package> </struts> |
案例2:类型是一个对象时
View代码:
<s:form method="post" action="converterAction"> <s:textfield name="walker.username" label="用户名"/> <s:textfield name="walker.age" label="年龄"/> <s:submit value="提交"/> </s:form> |
Walker代码:
public class Walker { private String username; private int age; //此处省略setter和getter方法 } |
Action代码:
public class ConverterAction extends ActionSupport { private Walker walker; //此处省略setter和getter方法
@Override public String execute() throws Exception { //输出属性值,发现从form表单中接收到的String类型数据已自动转换 System.out.println(walker.username); System.out.println(walker.age); return SUCCESS; } } |
3.基于OGNL的类型转换
对于非基本类型,我们使用默认的转换机制是不能解决问题的。
Action代码:
//其中walker是一个符合Javabean规范的类,其具有两个属性username和age public class LoginAction extends ActionSupport { private Walker walker; public void setWalker(Walker w){ this.walker =w; } public Walker getWalker(){ return this.walker; } @Override public String execute() throws Exception{ return SUCCESS; } } |
Action实例的一个属性是自定义的类型Walker,那么login表单页面原有的代码肯定是不能生效的,因为指定的username和age在Action实例中是没有的。那么怎么将一个字符串赋值给Action实例属性呢?ognl语法是可以做到的。
View代码:
<s:form method="post" action="/login"> <s:textfield name="walker.username" label="用户名"/> <s:textfield name="walker.age" label="年龄"/> <s:submit value="提交"/> </s:form> |
在login页面使用ognl语法,walker.username指定了为Action实例属性walker的username属性传值,walker.age指定了为Action实例属性的walker的age属性传值。其实我们到这里可以看出来,使用ognl语法可以实现非基本类型的转换。
View代码:
<s:property value="walker.getUsername()"/> <s:property value="walker.getAge()"/> |
操作List集合:
//修改属性为一个list集合 public class LoginAction extends ActionSupport { private List<Walker> list; public void setList(List<Walker> w){ this.list =w; } public List<Walker> getList(){ return this.list; } @Override public String execute() throws Exception{ return SUCCESS; } } |
//修改了的login表单页面 <body> <s:form method="post" action="/login"> <s:textfield name="list[0].username" label="用户名"/> <s:textfield name="list[0].age" label="年龄"/> <s:textfield name="list[1].username" label="用户名"/> <s:textfield name="list[1].age" label="年龄"/> <s:submit value="提交"/> </s:form> </body> |
操作Map集合:
//修改后的LoginAction 页面 public class LoginAction extends ActionSupport { private Map<String,Walker> map; public void setMap(Map<String,Walker> w){ this.map =w; } public Map<String,Walker> getMap(){ return this.map; } @Override public String execute() throws Exception{ return SUCCESS; } } |
//login页面的表单传值 <body> <s:form method="post" action="/login"> <s:textfield name="map['1'].username" label="用户名"/> <s:textfield name="map['1'].age" label="年龄"/> <s:textfield name="map['2'].username" label="用户名"/> <s:textfield name="map['2'].age" label="年龄"/> <s:submit value="提交"/> </s:form> </body> |
4.自定义类型转换器
使用OGNL可以完成对非基本类型的转换,但本质上还是调用了struts的默认转换器。
利用OGNL可以完成大部分的类型转换在,但也有些极端是不能解决的,此时可以考虑自定义一个类型转换器来解析类型转换。