1. 静态注入
静态参数注入是由一个叫做staticParams的拦截器完成的。
public class Demo1Action extends ActionSupport{
private String name = "窦虎";
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String execute(){
System.out.println(name);
return null;
}
}
struts.xml中的配置
<package name = "p1" extends="struts-default">
<action name = "action1" class = "com.zzxb.action.Demo1Action">
<!-- 相当于调用Demo1Action的实例的setName("杨洋") -->
<param name = "name">杨洋</param>
</action>
</package>
2. 动态参数注入:使用用户界面输入的值
是由一个叫做params的拦截器完成的
2.1 动作类作为模型对象:动作类中存储着用户输入的数据
form表单:
<form action = "${pageContext.request.contextPath}/action2" method = "post">
用户名:<input name = "name"/><br/>
<input type = "submit" value = "保存"/>
</form>
struts.xml
<action name = "action2" class = "com.zzxb.action.Demo2Action">
</action>
//动作类作为实体对象
public class Demo2Action extends ActionSupport{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String execute()throws Exception{
System.out.println(name);
return NONE;
}
}
动作类中的变量String name
要与表单中<input name = "name">
相一致。
2.2 动作类和模型分开(开发常用)
动作类:处理用户的请求
模型(Entity):封装数据
User (Entity)
//模型
public class User implements Serializable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString(){
return "User [name=" + name + ", age=" + age + "]";
}
}
Action
public class Demo3Action extends ActionSupport {
//没有初始值null,框架会通过反射实例化
private User user = new User();
public User getUser(){
return user;
}
public void setUser(User user){
this.user = user;
}
public String execute()throws Exception{
System.out.println(user);
return NONE;
}
}
jsp页面
<form action = "${pageContext.request.contextPath}/action3" method = "post">
用户名:<input name = "user.name"><br/>
年龄:<input name = "user.age"/><br/>
<input type = "submit" value = "保存"/>
</form>
配置文件
<!-- 动态参数注入:动作类和模型分开 -->
<action name="action3" class="com.itheima.action.Demo3Action"></action>
3. 模型驱动(ModelDriven)
是有一个叫做modelDriven的拦截器完成的
动作类和模型肯定是分开的
jsp页面
“name”,”age”要和模型对象的属性保持一致
<form action = "${pageContext.request.contextPath}/action4" method = "post">
用户名:<input name = "name"/><br/>
年龄:<input name = "age"/><br/>
<input type = "submit" value = "保存"/>
</form>
动作类:
public class Demo4Action extends ActionSupport implements ModelDriven<User>{
private User user = new User(); //一定要实例化
//获取模型对象的引用
public User getModel(){
return user;
}
public User getUser(){
return user;
}
public void setUser(User user){
this.user = user;
}
public String execute()throws Exception{
System.out.println(user);
return NONE;
}
}
4. 配合集合封装参数
应用场景:批量添加数据时使用
动作类:
//配合集合使用
public class Demo5Action extends ActionSupport {
private List<User> users = new ArrayList<User>();
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public String execute() throws Exception {
System.out.println(users);
return NONE;
}
}
表单:
<form action="${pageContext.request.contextPath}/action5" method="post">
用户名:<input name="users[0].name"/>年龄:<input name="users[0].age"/><br/>
用户名:<input name="users[1].name"/>年龄:<input name="users[1].age"/><br/>
用户名:<input name="users[2].name"/>年龄:<input name="users[2].age"/><br/>
用户名:<input name="users[3].name"/>年龄:<input name="users[3].age"/><br/>
<input type="submit" value="注册"/>
</form>
5. 封装数据的类型转换
前提:动作类要继承ActionSupport
5.1 认知
写数据:用户输入的数据String类型的。EntityBean 有其他类型。
String ———–>其他数据类型
读数据:封装数据在EntityBean,显示都是String类型
其他类型———>String
5.2 基本类型自动转换
java.util.Date<————————->java.lang.String 互转。
Struts2中默认按照本地格式(yyyy-MM-dd)进行转换
5.3 类型转换失败后(开发会用)
框架会自动转向一个 name=input 的逻辑视图。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="user" extends="struts-default">
<action name="regist" class="com.zzxb.action.UserAction" method="regist">
<!-- Redirect After Post -->
<result name="success" type="redirect">/index.jsp</result><!-- 注册成功 -->
<result name="error" type="redirect">/message.jsp</result><!-- 失败 -->
<!-- 转换失败会由拦截器自动转向该视图,用于数据的回显和错误消息提示 -->
<result name="input">/regist.jsp</result>
</action>
</package>
</struts>
5.3.1 数据的回显:使用Struts2的标签库
<s:form action = "regist">
<s:textfield name = "username" label = "用户名" requiredLabel="true" requiredPosition="left"></s:textfield>
<s:password name="password" label="密码"></s:password>
<s:radio list="#{'0':'女','1':'男'}" name = "gender" label="性别"></s:radio>
<s:textfield name="birthday" label="生日"></s:textfield>
<s:textfield name="email" label="邮箱"></s:textfield>
<s:submit value="注册"></s:submit>
</s:form>
5.3.2 数据回显:不借助Struts2的标签库,需要使用EL表达式获取原来的值
<form action="${pageContext.request.contextPath}/regist.action" method="post">
用户名:<input type="text" name="username" value="${username}"/><br/>
密码:<input type="text" name="password" value="${password}"/><br/>
性别:<input type="radio" name="gender" value="0"/>女
<input type="radio" name="gender" value="1"/>男<br/>
生日:<input type="text" name="birthday" value="${birthday}"/><br/>
邮箱:<input type="text" name="email" value="${email}"/><br/>
<input type="submit" value="注册"/>
</form>
5.3.3 错误消息提示(与i18n有关)
Struts2框架内部所有的错误消息,会封装到Map中,只要Map中有数据,都会转向一个name=input的逻辑视图,此功能用于类型转换和用户输入校验。
导入struts2的标签库,使用<s:filedError/>
、<s:actionError/>
5.4 错误消息提示的中文问题
在属性所属类的包中,建立”类名_zh_CN.properties(User_zh_CN.properties)”的配置文件,内容如下:
“birthday”是属性名称
invalid.fieldvalue.birthday=\u54C8\u54C8\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u65E5\u671F\u683C\u5F0F
5.5 自定义类型转换器
以日期类型MM/dd/yyyy为例
5.5.1 继承类
编写一个类,继承DefaultTypeConverter类,覆盖convertValue(Map<String,Object> context,Object value,class toType)
方法
建议编写一个类,继承StrutsTypeConverter类
public class MyDateConverter extends StrutsTypeConverter{
private DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
/**
*把String转换为Date类型
*/
public Object convertFromString(Map context,String[] values,Class toClass){
String sdate = values[0];
return df.parse(sdate);
}
/**
*把Date类型转换为String
*/
public String convertToString(Map context,Object o){
Date d = (Date)o;
return df.formate(d);
}
}
5.5.2 注册类型转换器
a、局部类型转换器:针对属性
在属性所在的类的包中,建立”类名-conversion.properties”的配置文件
文件内容:
birthday=com.zzxb.converter.MyDateConverter
b、全局类型转换器:针对转换的类型
at the top of classpath,建立一个固定名称为”xwork-conversion.properties”的配置文件
文件内容:
java.util.Date=com.zzxb.converter.MyDateConverter