一、action开发的几种方式
1.继承ActionSupport类
2.实现Action接口
3.不继承类也不实现任何接口
二、通配符
1.通配符{1}代表第一个*
<!-- 通配符: http://locahost:8080/struts02/user_login -->
<action name="user_*" class="cn.itcast.b_config2.UserAction" method="{1}">
</action>
1.动态方法调用,即不配置action的method属性,直接通过url的形式传入方法名,即!方法名,不安全
<!-- 动态方法调用: http://locahost:8080/struts02/user!login
<action name="user" class="cn.itcast.b_config2.UserAction">
<result name="success">/index.jsp</result>
</action>
-->
2.全局跳转视图,先去对应的action中寻找,如果没有再去全局配置中寻找
<!-- 配置全局跳转视图 -->
<global-results>
<result name="success">/index.jsp</result>
</global-results>
3.不配置class
<!-- 什么情况不配置class? 即处理的aciton -->
<!-- 答案: 当只是需要跳转到WEB-INF下资源的时候。 -->
<action name="test2">
<result name="success" type="redirect">/WEB-INF/index.jsp</result>
</action>
四、路径匹配原则
五、Struts常量
1.默认后缀:
struts1默认后缀是.do,struts2默认后缀是.action
2.修改默认的访问后缀,在下面的配置中,访问的url可以以action、do或者不写结尾
<constant name="struts.action.extension" value="action,do,"></constant>
3.其它常量
<!-- 0. 请求数据编码 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 1. 修改Struts默认的访问后缀 -->
<constant name="struts.action.extension" value="action,do,"></constant>
<!-- 2. 修改xml自动重新加载 -->
<constant name="struts.configuration.xml.reload" value="true"/>
<!-- 3. 开启动态方法调用 (默认不开启)-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<!-- 4. 修改上传文件的最大大小为30M -->
<constant name="struts.multipart.maxSize" value="31457280"/>
六、Struts中对数据操作
方式1: 直接拿到ServletApi, 执行操作
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext application = ServletActionContext.getServletContext();
// 操作
request.setAttribute("request_data", "request_data1");
session.setAttribute("session_data", "session_data1");
application.setAttribute("application_data", "application_data1");
方式2: 通过ActionContext类(练习使用,业务较少的时候)
package cn.itcast.c_data;
import java.util.Map;
import javax.servlet.ServletContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
* 数据处理
* @author Jie.Yuan
*
*/
public class DataAction_bak extends ActionSupport{
@Override
public String execute() throws Exception {
// 【推荐:解耦的方式实现对数据的操作】
// Struts中对数据操作,方式2: 通过ActionContext类
ActionContext ac = ActionContext.getContext();
// 得到Struts对HttpServletRequest对象进行了封装,封装为一个map
// 拿到表示request对象的map
Map<String,Object> request = ac.getContextMap();
// 拿到表示session对象的map
Map<String, Object> session = ac.getSession();
// 拿到表示servletContext对象的map
Map<String, Object> application = ac.getApplication();
// 数据
request.put("request_data", "request_data1_actionContext");
session.put("session_data", "session_data1_actionContext");
application.put("application_data", "application_data1_actionContext");
return SUCCESS;
}
}
方式3: 实现接口的方法(适合业务方法比较多的情况,优化的时候)
package cn.itcast.c_data;
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
/**
* 数据处理, 方式3: 实现接口的方法
* @author Jie.Yuan
*
*/
public class DataAction extends ActionSupport implements RequestAware, SessionAware, ApplicationAware{
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
// struts运行时候,会把代表request的map对象注入
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
// 注入session
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
// 注入application
@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}
@Override
public String execute() throws Exception {
// 数据
request.put("request_data", "request_data1_actionAware");
session.put("session_data", "session_data1_actionAware");
application.put("application_data", "application_data1_actionAware");
return SUCCESS;
}
}
七、请求数据自动封装
实现原理:参数拦截器
实现方式:Jsp表单数据填充到action中的属性或对象中的属性
1.新建实体类并生成get、set方法
package cn.itcast.d_type;
import java.util.Date;
public class User {
// 封装请求数据
private String name; // 必须给set / get可以不用给
private String pwd;
private int age;
private Date birth;
public void setName(String name) {
this.name = name;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public void setAge(int age) {
this.age = age;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public String getName() {
return name;
}
public String getPwd() {
return pwd;
}
public int getAge() {
return age;
}
public Date getBirth() {
return birth;
}
}
2.开发action,给出get、set方法
package cn.itcast.d_type;
import java.util.Date;
/**
* Struts核心业务: 请求数据自动封装以及类型转换
* @author Jie.Yuan
*
*/
public class UserAction {
// 对象类型,一定给get方法
private User user;
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
// 处理请求
public String register() {
System.out.println(user.getName());
System.out.println(user.getPwd());
System.out.println(user.getAge());
System.out.println(user.getBirth());
return "success";
}
}
3.配置struts.xml文件
<package name="type" namespace="/" extends="struts-default">
<action name="user_*" class="cn.itcast.d_type.UserAction" method="{1}">
<result name="success">/index.jsp</result>
</action>
</package>
4.新建register.jsp页面
<form action="${pageContext.request.contextPath }/user_register.action" method="post">
用户名:<input type="text" name="user.name"><br/>
密码:<input type="text" name="user.pwd"><br/>
年龄:<input type="text" name="user.age"><br/>
生日:<input type="text" name="user.birth"><br/
<input type="submit" value="注册">
</form>
输入网站:http://localhost:8080/项目名/
register.jsp,输入测试数据即可(date类型struts默认只支持yyyy-MM-dd类型)
八、类型转换
struts对于jsp提交的数据,会自动转换成action中属性的类型,对于基本数据类型和日期类型会自动转换,但日期类型只支持yyyy-MM-dd格式,所以要自定义类型转换器,转换器包括局部类型转换器和全局类型转换器(先首先在局部类型转换器中进行查找,如果没有再去全局类型转换器中查找)
局部转换器的开发步骤:
1.写转换器类
2.配置转换器类(在同包的action目录下,新建一个properties文件,名称为action名称-conversion)
3.配置文件的内容:要转换的属性=转换器类全路径
全局转换器的开发步骤:
1.写转换器类
2.配置转换器类(在src目录下新建properties文件,名称为xwork-conversion.properties)
3.配置文件的内容:要转换的全名=转换器类全路径
下面是一个全局转换器的代码
1.新建转换器类:
package cn.itcast.d_type;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
/**
* 自定义类型转换器类
*
* @author Jie.Yuan
*
*/
public class MyConverter extends StrutsTypeConverter {
// 新需求: 要求项目中要支持的格式,如: yyyy-MM-dd/yyyyMMdd/yyyy年MM月dd日..
// 先定义项目中支持的转换的格式
DateFormat[] df = { new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyyMMdd"),
new SimpleDateFormat("yyyy年MM月dd日") };
/**
* 把String转换为指定的类型 【String To Date】
*
* @param context
* 当前上下文环境
* @param values
* jsp表单提交的字符串的值
* @param toClass
* 要转换为的目标类型
*/
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
// 判断: 内容不能为空
if (values == null || values.length == 0) {
return null;
}
// 判断类型必须为Date
if (Date.class != toClass) {
return null;
}
// 迭代:转换失败继续下一个格式的转换; 转换成功就直接返回
for (int i=0; i<df.length; i++) {
try {
return df[i].parse(values[0]);
} catch (ParseException e) {
continue;
}
}
return null;
}
@Override
public String convertToString(Map context, Object o) {
return null;
}
}
2.配置转换器类文件xwork-conversion.properties
java.util.Date=cn.itcast.d_type.MyConverter