封装请求参数
一、属性封装
只要在Action中提供与参数对应的set方法即可自动封装
<body>
<form action="/struts2-demo2/param/Demo1Action.do" method="post" >
<input type="text" name="name" /><input type="submit" value="gogo"/>
</form>
</body>
方式一:
package cn.hcx.d_param;
import java.util.Arrays;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class Demo1Action extends ActionSupport{
public String execute(){
//获得参数方式1(昨天讲过)
//1 获得封装参数的map
Map<String, Object> params = ActionContext.getContext().getParameters();
//2获得参数
String[] names = (String[]) params.get("name");
System.out.println(Arrays.toString(names));
return SUCCESS;
}
}
方式二:
package cn.hcx.d_param;
import java.util.Arrays;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.sun.net.httpserver.Authenticator.Success;
//action 可以作为封装数据的javaBean来使用.
//servlet可以吗? 不可以=> 只有个 Servlet实例
//action为什么可以? 一个线程对应一个Action对象
public class Demo2Action extends ActionSupport{
private String name;
public String getName() {
return name;
}
//接受表单提交参数,只需要在Action中准备与提交键相同的属性,即可.
//struts2 会自动将提交的值赋值到属性中
public void setName(String name) {
this.name = name;
}
//第2中获得参数方式(爽)
public String execute(){
System.out.println(name);
return SUCCESS;
}
}
struts.xml:
<struts>
<package name="param" namespace="/param" extends="struts-default" >
<action name="Demo1Action" class="cn.hcx.d_param.Demo1Action" method="execute" >
<result name="success" type="dispatcher" >/param/demo1.jsp</result>
</action>
<action name="Demo2Action" class="cn.hcx.d_param.Demo2Action" method="execute" >
<result name="success" type="dispatcher" >/param/demo2.jsp</result>
</action>
<action name="Demo3Action" class="cn.hcx.d_param.Demo3Action" method="execute" >
<result name="success" type="dispatcher" >/param/demo3_2.jsp</result>
</action>
</package>
</struts>
二、自动类型转换
struts会自动转换8大基本数据类型和对应包装类.以及Date类型
其中date类型对数据提交格式有要求: yyyy-MM-dd
package param;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class Demo3Action extends ActionSupport{
private int age;
private double money;
private boolean married;
private char sex;
private Date birthday;
public String execute(){
System.out.println(age+"==>"+money+"==>"+married+"==>"+sex+"==>"+birthday);
return SUCCESS;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public boolean isMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
<body>
<form action="/struts2demo2/param/Demo3Action.action" method="post">
年龄:<input type="text" name="age" /><br>
工资:<input type="text" name="money" /><br>
婚否:<input type="text" name="married" /><br>
性别:<input type="text" name="sex" /><br>
生日:<input type="text" name="birthday" /><br>
<input type="submit" value="gogo"/>
</form>
</body>
<body>
<!-- <form action="/struts2-demo2/param/Demo3Action.do" method="post" >
年龄:<input type="text" name="age" /><br>
工资:<input type="text" name="money" /><br>
婚否:<input type="text" name="married" /><br>
性别:<input type="text" name="sex" /><br>
生日:<input type="text" name="birthday" /><br>
<input type="submit" value="gogo"/>
</form> -->
<s:form action="Demo3Action" namespace="/param" >
<s:textfield name="age" label="年龄" ></s:textfield>
<s:textfield name="money" label="工资" ></s:textfield>
<s:textfield name="married" label="婚否" ></s:textfield>
<s:textfield name="sex" label="性别" ></s:textfield>
<s:textfield name="birthday" label="生日" ></s:textfield>
<s:submit value="gogo" label="年龄" ></s:submit>
</s:form>
</body>
struts.xml:
<action name="Demo3Action" class="param.Demo3Action" method="execute">
<result name="success" type="dispatcher">/param/demo3.jsp</result>
</action>
struts中的mvc:
三、容器数据封装
容器:数组、List、Set、Map等
1、jsp表单
<form action="${pageContext.request.contextPath}/demo2Action" method="post">
Map<br/>
<input type="text" name="userMap['u001'].userName"/> <br/>
<input type="text" name="userMap['u001'].userPwd"/> <br/>
<input type="text" name="userMap['u002'].userName"/> <br/>
<input type="text" name="userMap['u002'].userPwd"/> <br/>
List<br/>
<input type="text" name="userList[0].userName"/> <br/>
<input type="text" name="userList[0].userPwd"/> <br/>
<input type="text" name="userList[1].userName"/> <br/>
<input type="text" name="userList[1].userPwd"/> <br/>
Array<br/>
<%-- request.getParameterValues("username") --%>
<input type="checkbox" name="hobby" value="抽烟"/>
<input type="checkbox" name="hobby" value="喝酒"/>
<input type="checkbox" name="hobby" value="烫头"/> <br/>
<input type="submit" value="提交"/>
</form>
2、action类
public class Demo2Action extends ActionSupport {
//封装到Map ,必须提供getter,所有封装需要使用同一个Map对象
private Map<String,User> userMap;
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public Map<String, User> getUserMap() {
return userMap;
}
//封装到List,必须提供getter,,所有封装需要使用同一个List对象
// * List<User> 和 User[] 等效的
private List<User> userList;
public void setUserList(List<User> userList) {
this.userList = userList;
}
public List<User> getUserList() {
return userList;
}
//数组,不需要提供getter,直接一次性封装数据,使用String[] request.getParameterValues("hobby")
private String[] hobby;
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
@Override
public String execute() throws Exception {
System.out.println(userMap);
System.out.println(userList);
System.out.println(hobby);
System.out.println(Arrays.toString(hobby));
return "none";
}
}
四、类型转换
默认支持类型转换:
l 字符串 <--> 指定类型 之间转换
字符串 转成 指定类型:表单提交,浏览器发送服务器
指定类型 转成 字符串:标签回显,服务器发送浏览器
l 指定类型
8个基本类型、以及包装类
时间 Date,字符串有格式要求:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss
数组、List、Map
方案1:实现接口:TypeConverter,有一个方法,但参数过多。
方法2:继承默认实现类:DefaultTypeConverter 。提供简洁方法convertValue(Object , Class)
convertValue(Object value , Class toType)
#1 表单提交,浏览器发送到服务器。浏览器发送的肯定字符串String,需要转换成指定的类型。例如Date类型
参数1:value,表示浏览器发送的数据。类型是String[] ,底层使用request.getParameterValues("...")
参数2:toType,表示需要转换的类型,java.uilt.Date类型
** 操作
// 如果toType是 Date类型,表示希望将字符串转成 时间
if(toType == java.util.Date.class){
//获得数据
String[] params = (String[])value;
//转成成时间
}
#2 标签回显,服务器发送浏览器,类型之前已经从字符串转成时间,现在希望将时间再转换成 字符串。
参数1:value,表示服务器已经转成好的时间。类型Date。
参数2:toType,表示需要转换的类型,String类型
** 操作
if(toType == String.class){
// 将数据强转时间
Date date = (Date)value;
// 格式化
}
执行流程:
转换器:
告知struts自定义的转换器
1、局部转换器:只对当前Action类有效。
限制:
只能对action类的属性进行转化,不能对javabean中属性转换
位置:action类同包
名称:actionClass-conversion.properties
actionClass: action类的类名
conversion.perperties:固定值
内容:属性=转换器
在对应action所属的包下创建一个前缀名与对应action名一样的-conversino.properties: 即简短类名-conversion.properties
birthday=cn.hcx.d_param.MyDateConverter
键:要转换的属性名称
值:转换器的完整类名
这样在转换属性的时候,struts会使用自己指定的转换器来转换
2、全局转换器:对所有的Action类有效
位置:src
名称:xwork-conversion.properties
内容:需要转换的类=转换器在src下建一个文件:命名:xwork-conversion.properties
package cn.hcx.d_param;
import java.lang.reflect.Member;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import com.opensymphony.xwork2.conversion.TypeConverter;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
public class MyDateConverter extends DefaultTypeConverter {
@Override
//参数1: 待转换的对象
//参数2: 需要被转换成的类型
public Object convertValue(Object value, Class toType) {
try {
//1 创建sdf 格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
//2 判断参数2 的 类型
if(toType == Date.class){
// Date.class=> 字符串转日期
// 2012/12/12 => Date.class
String[] params = (String[]) value;
return sdf.parse(params[0]);
}
if(toType == String.class){
// String.class = > 日期转字符串
// Date => 2012/12/12
Date date = (Date) value;
return sdf.format(date);
}
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
throw new RuntimeException("不可楞!!");
}
}