Struts框架功能:
- 请求数据自动封装
- 文件上传的功能
- 国际化功能简化
- 数据校验功能
一 Struts开发步骤
1.1 引入jar包(下载)
commons-fileupload-1.2.2.jar 【文件上传相关包】
commons-io-2.0.1.jar
struts2-core-2.3.4.1.jar 【struts2核心功能包】
xwork-core-2.3.4.1.jar 【Xwork核心包】
ognl-3.0.5.jar 【Ognl表达式功能支持表】
commons-lang3-3.1.jar 【struts对java.lang包的扩展】
freemarker-2.3.19.jar 【struts的标签模板库jar文件】
javassist-3.11.0.GA.jar 【struts对字节码的处理相关jar】
1.2 配置web.xml
<!-- 引入struts核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.3 开发action
在项目的src文件下添加structs.xml文件
步骤:
1 创建action类,一般继承ActionSupport类
2 添加业务方法,处理具体的请求,必须返回String,方法不能有参数
public class HelloAction extends ActionSupport {
// 处理请求
public String execute() throws Exception {}
public String add(){}
}
配置structs.xml
<!--
package 定义一个包。 包作用,管理action。(通常,一个业务模板用一个包)
name 包的名字; 包名不能重复;
extends 当前包继承自哪个包,一定要继承struts-default
struts-default在struts-default.xml中定的包
abstract
表示当前包为抽象包; 抽象包中不能有action的定义,否则运行时期报错
abstract=true 只有当当前的包被其他包继承时候才用!
action 配置请求路径与Action类的映射关系
name 请求路径名称
class 请求处理的aciton类的全名
method 请求处理方法
result
name action处理方法返回值
type 跳转的结果类型,标签体中指定跳转的页面,默认是转发
-->
<struts>
<package name="user" extends="struts-default" >
<action name="login" class="cn.itcast.b_execute.UserAction" method="login">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
1.4 执行流程
服务器启动:
1. 加载项目web.xml
2. 创建Struts核心过滤器对象, 执行filter → init()
struts-default.xml, 核心功能的初始化
struts-plugin.xml, struts相关插件
struts.xml 用户编写的配置文件
访问:
3. 用户访问Action, 服务器根据访问路径名称,找对应的aciton配置, 创建action对象
4. 执行默认拦截器栈中定义的18个拦截器
5. 执行action的业务处理方法
1.5 Struts配置
配置都是在struts.xml中配置的
通配符配置
//因为 name中的*可以有多个 {1}代表第一个*的值
<action name = "user_*" class="cn.itcast.a.config.UserAction" method = "{1}">
<result name = "login">/login.jsp</result>
<result name = "register">/register.jsp</result>
</action>
<!-----全局配置-------->
<struts>
<package name="user" extends="struts-default" >
//配置拦截器
<interceptors>
<interceptor name = "loginCheck" class = "cn.itcast.interceptor.UserCheckInterceptor">
</interceptor>
<interceptor-stack name = "myStack">
<interceptor-ref name = "defaultStack"></interceptor-ref>
<interceptor-ref name = "loginCheck"></interceptor-ref>
</interceptor-stack>
</interceptors>
//执行拦截器
<default-interceptor-ref name = "myStack"></default-interceptor-ref>
//配置全局跳转视图
<global-results>
//如果<action>里面没有配置<result>就会调用这个
<result name = "success">/index.jsp</result>
<global-results>
//修改默认访问后缀
//访问后缀是.action或者.do或者不带后缀 如http://localhost:8080/user_login.action
<constant name = "struts.action.extension" value = "action,do,"></constant>
//请求数据的编码
<constant name = "struts.i18n.encoding" value = "UTF-8"/>
</package>
</struts>
<!-----总配置:引入其他模块的struts配置文件-------->
<include file = "cn/itcast/a_config/config.xml"
action各项默认值
<package name="user" extends="struts-default" >
//class 默认执行的action在struts-default有配置<default-class-ref class="com.opensymphony.xwork2.ActionSupport"/>
//method 默认为execute,默认的返回值为success
<action name="login" class="cn.itcast.b_execute.UserAction" method="login">
//type默认为dispatcher
<result name="success" type="">/index.jsp</result>
</action>
</package>
1.5 数据处理
请求数据自动封装以及类型转换
数据的自动封装是通过拦截器(<interceptor name ="params">
)做的
public class User
{
private String name;
private Date birth;
//必须要有set方法
public void setName(String name)
{
this.name = name;
}
public void setBirth(String birth)
{
this.birth = birth;
}
}
public calss UserAction extends ActionSupport {
private User user;
public void setUser(User user)
{
this.user = user;
}
public User getUser()
{
return user;
}
public String register()
{
System.out.println(user.getName);
}
}
register.jsp中的写法
<body>
<form action = "${pageContext.request.contextPath}/user_register.action" method="post">
用户名:<input type='text' name = "user.name">
生日:<input type='text' name = "user.birth">
</form>
</body>
保存数据到域对象中
public String execute() throws Exception
{
//第一种方法
//直接拿到servlet相关的api
HttpServletRequest request = ServletActionContext.getRequest();//拿到request
ServletContext context = ServletActionContext.getServletContext();//拿到context
HttpSession session = request.getSession();//拿到session
//第二种方法(常用)
//通过ActionContext类
ActionContext ac = ActionContext.getContext();
//拿到表示request对象的map
Map<String,Object> ac_request = ac.getContextMap();
//拿到表示session对象的map
Map<String,Object> ac_session = ac.getSession();
//拿到表示servletContext对象的map
Map<String,Object> ac_application = ac.getApplication();
//把数据存到域对象中
ac_request.put("request_data","data1");
ac_session.put("session_data","data2");
ac_application.put("applic_data","data3");
//第三种方式 action类实现接口RequestAware,SessionAware,ApplicationAware
//2.调用Service处理业务逻辑,拿到数据结果
//3.数据保存到域中
return "success";
}
类型转换
需求:将表单提交的日期格式转换为指定的格式
//自定义一个类继承StrutsTypeConverter
public class MyConverter extends StrutsTypeConverter
{
//把String转换为指定的类型,表单提交的参数都是字符串
//values 表单提交的字符串值
//toClass 要转换为的目标类型(即成员变量的类型)
@Override
public Object convertFromString(Map context, String[] values, Class toClass)
{
if(values==null||values.length==0) return null;
if(Date.class!= toClass) return null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
return sdf.parse(values[0]);
}
}
在项目src目录下建立:xwork-conversion.properties文件
在properties中添加:需要转换的类类型 = 转换器类的权限定名
如:java.util.Date = cn.itcast.converter.DateConverter
1.6 Struts中文件上传
public class FileUpload extends ActionSupport
{
//对应表单:<input type ="file" name="file1">
private File file1;
//文件名 固定格式 **FileName
private String file1FileName
//文件类型
private String file1ContentType;
public void setFile1(File file1)
{
this.file1 = file1;
}
public void setFile1FileName(String file1FileName)
{
this.file1FileName = file1FileName;
}
public void setFile1ContentType(String file1ContentType)
{
this.file1ContentType = file1ContentType;
}
public String execute() throws Exception {
//获取上传的目录路径
String path = ServletActionContext.getServletContext().getRealPath("/upload");
//创建目标文件对象
File destFile = new File(path,file1FileName);
//把上传的文件,拷贝到目标文件中
FileUtils.copyFile(file1,destFile);
return "success";
}
}
修改上传文件大小限制
//stucts的默认最大大小是2M
//在struts.xml中修改 默认最大大小为30M
<constant name="struts.multipart.maxSize" value ="30157280"/>
限制文件上传的类型
//在struts.xml中修改 修改拦截器配置
<action name="fileUploadAction" calss = "cn.itcast.e_fileupload.FileUpload">
<interceptor-ref name="defaultStack"/>
//限制上传的文件的扩展名
<param name="fileUpload.allowedExtensions">txt,jpg</param>
</interceptor-ref>
</action>
1.7 自定义拦截器
public class HelloInterceptor implements Interceptor{
// 启动时候执行
public HelloInterceptor(){
System.out.println("创建了拦截器对象");
}
// 启动时候执行
@Override
public void init() {
System.out.println("执行了拦截器的初始化方法");
}
// 拦截器业务处理方法 (在访问action时候执行? 在execute之前执行?)
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("2. 拦截器,业务处理-开始");
// 调用下一个拦截器或执行Action (相当于chain.doFilter(..)
// 获取的是: execute方法的返回值
String resultFlag = invocation.invoke();
System.out.println("4. 拦截器,业务处理-结束");
return resultFlag;
}
@Override
public void destroy() {
System.out.println("销毁....");
}
}
拦截器配置
<?xml version="1.0" encoding="UTF-8" ?>
<struts>
<package name="hello" extends="struts-default">
<!-- 【拦截器配置】 -->
<interceptors>
<!-- 配置用户自定义的拦截器 -->
<interceptor name="helloInterceptor" class="cn.itcast.a_interceptor.HelloInterceptor"></interceptor>
<!-- 自定义一个栈: 要引用默认栈、自定义的拦截器 -->
<interceptor-stack name="helloStack">
<!-- 引用默认栈 (一定要放到第一行)-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 引用自定义拦截器 -->
<interceptor-ref name="helloInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 【执行拦截器】 -->
<default-interceptor-ref name="helloStack"></default-interceptor-ref>
<!-- Action配置 -->
<action name="hello" class="cn.itcast.a_interceptor.HelloAction">
<result name="success"></result>
</action>
</package>
</struts>