目录
一、架构
下图为struts2的执行流程图。
以下为执行流程在框架代码中的体现。
再接着就是执行拦截器的后处理,完成后通过HttpServletResponse将数据传递给浏览器响应。
二、框架搭建
step1:引入jar包。
step2:在web.xml中配置struts2的核心过滤器。
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
step3:提供struts.xml配置文件(放在classpath下)。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!--
name:包名,必填属性,用于别的包引用此包的唯一标识
namespace:命名空间
默认值:""
跟名称空间:"/"
带名称的名称空间:"/demo"
extends:可选,表示该包继承自其他包
struts-default:struts框架提供的包
abstract:可选值,表示该包是否为抽象包
false:默认值
true:设置为true后,该包不能包含Action定义。
-->
<package name="test" extends="struts-default">
<!--
Action:工作单元
name:URL请求名
class:对应Action类的全路径类名
method:执行该类对用的方法的方法名
converter:指定类型转换器的类
-->
<action name="demoAction" class="com.frank.web.action.DemoAction" method="index">
<!--
result
name:方法执行后返回的结果名
type:响应类型
dispatcher:默认值,转发
redirect:重定向
chain:转发到Action
redirectAction:重定向到Action
。。。
-->
<result name="toDemo" type="redirect">/demo1/demo1.jsp</result>
</action>
</package>
</struts>
常量配置
- 在struts.xml文件中通过< constant>元素配置常量。
<!-- 国际化,可用于处理post请求中文乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 指定请求后缀名 -->
<constant name="struts.action.extension" value="action"/>
<!-- 开发模式,更新配置不用重启tomcat,编码阶段开启便于调试 -->
<constant name="struts.devMode" value="true"/>
- 在struts.properties中配置。
- 在web.xml中通过< init-param>元素配置常量。注意:必须要放在filter标签下。
step4:创建Action类。
- 直接是简单的POJO类。
- 继承ActionSupport类(封装了很多实用的工具,建议使用)。
- 实现Action接口。
三、Action访问
1.配置method实现
这种配置限制很大,一个action元素只能提供一个方法。
<action name="userUpdate" class="com.frank.web.action.UserAction" method="update"/>
<action name="userAdd" class="com.frank.web.action.UserAction" method="add"/>
<action name="userDelete" class="com.frank.web.action.UserAction" method="delete"/>
2.通配符配置
<!--
user_*:*表示占位符,可以为user_add、user_update
{1}:表示*的值,若为user_add,那么就表示add
-->
<action name="user_*" class="com.frank.web.action.UserAction" method="{1}">
</action>
3.动态方式访问
struts2中是默认不开启的(说明性能不好),需要配置常量开启。
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<action name="userAction" class="com.frank.web.action.UserAction">
</action>
访问方式:${pageContext.request.contextPath}/userAction!add.action
四、Struts2访问Servlet的API
1.通过ActionContext.getContext()访问。
2.通过ServletActionContext访问。
3.通过特定接口访问。 ServletRequestAware,ServletResponseAware,ServletContextAware,SessionAware
五、Struts2的数据封装
1.属性驱动:注意,使用属性驱动的时候,一定要提供setter方法。如果属性是一个对象的话,还需要提供getter方法,因为Struts2框架需要通过getter方法获取该对象,在进行数据封装。
2.模型驱动:需要实现ModelDriven< T>接口,泛型替换为你要封装的对象。注意,需要手动构建对象,手动注入。
public class DemoAction extends ActionSupport implements ModelDriven<User>{
private User user = new User();
@Override
public User getModel() {
return user;
}
public String index() {
ActionContext.getContext().getSession();
//ServletActionContext.getReuqest();
return "toDemo";
}
}
3.封装集合类型数据
public class DemoAction extends ActionSupport{
private List<User> list;
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
}
<input name="list[0].name">
<input name="list[0].age">
<input name="list[1].name">
<input name="list[1].age">
public class DemoAction extends ActionSupport{
private Map<String,User> map;
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
}
<input name="map['one'].name">
<input name="map['one'].age">
<input name="map['two'].name">
<input name="map['two'].age">
六、值栈
struts2的值栈是通过OGNL表达式实现的。OGNLValueStack包含两个部分,值栈和Map(ognl上下文)。
在struts2中ActionContext和ValueStack是互相引用的关系。
1.获取值栈对象
- 通过ActionContext获取
ValueStack valueStack = ActionContext.getContext().getValueStack();
- 通过request域获取
ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
2.存入数据
- 向值栈中存入数据:通过为Action类的属性提供getter方法。
public class DemoAction extends ActionSupport{
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String index() throws Exception {
code = "0427";
return SUCCESS;
}
}
- 向map集合中存放数据
public class DemoAction extends ActionSupport{
public String index() throws Exception {
ActionContext.getContext().put("name", "张三");
ActionContext.getContext().getSession().put("user", new User("zhangsan",18));
ActionContext.getContext().getApplication().put("user1", new User("lisi",20));
return super.execute();
}
}
3.jsp取数据
引入标签库
<%@ taglib uri="/struts-tags" prefix="s" %>
<s:property value="code"/>//从值栈中取
<s:property value="#name"/>//从request域中取
<s:property value="#session.user.name"/>//从session域中取
<s:property value="#session.user.age"/>
<s:property value="#application.user1.name"/>//从application域中取
<s:property value="#application.user1.age"/>
<s:property value="#parameters.ppp"/> //从传递的参数中取
<br/>
//EL表达式取值
${code }
${name }
${user.name }
${user.age }
${user1.name }
${user1.age }
${param.ppp }
<s:debug></s:debug>
七、拦截器
struts2的拦截器是可插拔的,拦截器是AOP(面向切面编程)的一种实现。
1.定义拦截器
如下拦截器实现一个用户是否登录的判断,登录过,则放行,没有登录则重定向到登录页面。
public class LoginInterceptor extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
User user = (User) ActionContext.getContext().getSession().get("user");
if (user != null) {
return invocation.invoke();
}
return "toLogin";
}
}
2.struts.xml配置
<interceptors>
<!-- 注册定义的拦截器 -->
<interceptor name="loginInterceptor" class="com.frank.web.interceptor.LoginInterceptor">
<!--
excludeMethods:放行的方法
includeMethods:指定哪些方法需要拦截
-->
<param name="excludeMethods">login,register</param>
</interceptor>
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<!-- defaultStack为struts框架定义的拦截器栈 -->
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="loginInterceptor"/>
</interceptor-stack>
</interceptors>
<!-- 定义默认拦截器栈 -->
<default-interceptor-ref name="myStack"/>
<!-- 定义全局结果集 -->
<global-results>
<result name="toLogin" type="redirect">/demo/login.jsp</result>
</global-results>
结束,又是整理一整天,知识满满。