一、Struts2简介
Struts2是Struts1的下一代产品,但Struts2与Struts1的体系结构却差别巨大,Struts2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计使得业务逻辑能够与Servlet API完全脱离开。它吸收了Struts1和WebWork两者的优势。支持更多的表现层技术,如FreeMarker,velocity等,采用一种更加松耦合的设计,使Action不再与Servlet耦合,同时Srruts2也是一个良好的MVC框架。
谈谈MVC?
工作原理:用户通过浏览器发出请求到视图View,然后View转发请求到控制器Controller,Controller根据请求调用对应的模型Model,模型Model对请求进行业务处理并返回数据结果给控制器,控制器Controller再选择对应的视图响应给用户。
MVC.png
二、第一个入门程序
对应步骤如下:
- 1、先导入Struts2框架需要的架包。
- 2、编写web.xml文件进行Struts2的FilterDispatcher核心拦截器配置,如下拦截所有用户请求。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Struts2Demo01</display-name>
<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>
</web-app>
- 3、创建对应的jsp页面或者其他表现层技术写页面,下面使用了Struts2的封装好的表单元素标签,和普通的表单标签的样式和效果有所区别。
//login.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录页面</title>
</head>
<body>
<s:form action="loginAction" method="POST">
<s:textfield name="uname" label="用户名 " />
<s:password name="pwd" label="密码" />
<s:submit value="登录" />
<s:reset value="重置" />
</s:form>
</body>
</html>
//index.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>成功页面</title>
</head>
<body>
<%-- 登陆成功,欢迎你,管理员:${sessionContext.uname }; --%>
欢迎你,<s:property value="uname" />,登录成功。
</body>
</html>
- 4、创建对应的Action类来对请求进行处理,execute()是Action类默认的自动执行方法,用来处理请求,还有validate()方法是验证器方法,在处理请求前会先自己执行这个方法。返回的SUCCESS和INPUT 是struts常量,根据这个常量去strus.xml配置文件找响应页面。
package action;
import java.util.*;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private String uname;
private String pwd;
public LoginAction(){
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
//默认的execute方法
public String execute() throws Exception{
Map map;
if(uname.equals("小江") && pwd.equals("111")){
map = ActionContext.getContext().getSession();
map.put("uname",getUname());
return SUCCESS;
}else{
return INPUT;
}
}
//验证器方法,提交 表单后,在execute方法前先执行
public void validate(){
if(uname==null || uname.equals("")){
addFieldError("uname","用户名不能为空");
}
if(pwd==null || pwd.equals("")){
addFieldError("pwd","密码不能为空");
}
if(!uname.equals("小江")){
addFieldError("uname","用户名错误");
}
if(!pwd.equals("111")){
addFieldError("pwd","密码错误");
}
}
}
- 5、在src目录下创建一个struts.xml文件来管理配置Action类
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<package name="Struts2Demo01" extends="struts-default">
<action name="loginAction" class="action.LoginAction">
<result name="success">/index.jsp</result>
<result name="input">/login.jsp</result>
</action>
</package>
</struts>
- 6、部署web程序到Tomcat即可以通过浏览器以URL方式运行访问
整个过程是:jsp页面转发请求,根据struts.xml配置文件找到对应的Action类进行业务逻辑处理,最后再找到对应的响应页面。
三、OGNL表达式和值栈详解
1、什么是值栈(ValueStack)?
值栈就是对应每一个请求对象的轻量级内存数据中心,是OGNL表达式存取数据的地方,值栈和请求是一一对应的,值栈封装了一次请求所需要的所有数据,这种一一对应的关系使值栈能够线程安全地为每个请求提供公共的数据存取服务。
2、值栈的作用和生命周期?
值栈可作为一个数据中转站,用于前后台传递数据。
ValueStack贯穿整个Action的生命周期,每个Action类都拥有一个ValueStack对象,与Action生命周期保持一致,其随着request的创建而创建,销毁而销毁。
3、什么是OGNL表达式?
OGNL全称是对象图导航语言,使用OGNL表达式可简化数据的访问操作。
OGNL结构具有三要素:①表达式(OGNL会根据表达式去对象取值,即“做什么”)、②根对象(OGNL的操作对象,即“对谁操作”)、③上下文环境(即”OGNL规定了操作在哪里进行”,实质OGNL上下文是一个Map类型的容器)
值栈的2种获取方式
- 在request中获取值栈
ValueStack vs = (ValueStack)ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
- 在ActionContext中获取值栈
ValueStack vs = ActionContext.getContext().getValueStack();
值栈的内部结构(PS:既然是栈,存取数据就遵循先进后出的压入原则。)
ValueStack对象包含2个逻辑部分
- 1、ObjectStack(对象栈):是CompoundRoot类型,是一个ArrayList集合,struts2把动作和相关对象压入ObjectStack中。root实际上是一个ArrayList,与ObjectStack对应。
- 2、ContextMap(Map栈):是OgnlContext类型,是一个Map集合,struts2把映射关系压入ContextMap中。context对象实际是一个Map,与ContextMap对应。
Struts2引入值栈的主要应用:将Action中的数据再页面中显示出来,在页面中与Action进行数据交换。
采用以下2种方式交换数据,struts2会直接将对象自动存储到ValueStack中。
- 1、属性驱动:每次请求访问Action对象时,Action中的属性对象会被自动压入ValueStack中。
- 2、模型驱动:Action类实现ModelDriven接口,则ModelDrivenInterceptor拦截器会生效,将model对象压入ValueStack中。
使用OGNL访问静态属性和静态方法
记得要在struts.xml文件中开启访问静态方法的支持
,然后通过@类全路径@静态属性访问,@类全路径@静态方法
<struts>
<!-- 开启静态方法的支持 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
</struts>
网友评论