关于struts2的大概

本文详细介绍了Struts2的MVC架构,包括核心组件如Actions、拦截器、值栈、结果类型和配置文件的使用。Struts2通过Actions实现数据传递,拦截器提供预处理和后处理逻辑,值栈用于存储和访问数据。此外,文章还讨论了结果类型的内部转发和重定向,以及如何自定义拦截器栈。最后提到了Struts2在全局结果、文件上传下载等方面的便利性。
摘要由CSDN通过智能技术生成

一、Struts2 MVC架构

MVC:模型(model)-视图(view)-控制器(controller)。

在MVC模式下,控制器接收了所有来自应用程序的请求后,调用模型去准备视图所需要的数据,然后视图使用由控制器提供的数据最终生成一个可视的响应。

Struts2的MVC主要通过五个核心部分进行实现:(1)操作Actions(2)拦截器Interceptors(3)值栈Value Stack/OGNL(4)结果Result/结果类型(5)视图

下面会详细介绍上面提到的内容。

二、文件l配置

1.web.xml文件配置

在web.xml中配置如下:

 <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>
<url-pattern>中的/*表示拦截所有的web请求,把这个请求发送到org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter进行处理。StrutsPrepareAndExecuteFilter这个类称为核心处理器,用来解析请求,把请求映射到相应的Action中。

2.struts.xml文件配置

(1)先看一个例子:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
  <package name="helloWorld" namespace="/" extends="struts-default">
  	<action name="hello" class="action.HelloWorldAction" method="execute">
  		<result name="success">helloWorld.jsp</result>
  	</action>
  </package>
</struts>

<struts>是根标签。

<package>标签声明不同的包,当项目分为不同的模块时可以定义多个不同name的package。name是package的唯一标志;extends指定package继承另一package的所有配置,默认是extends="struts-default";abstract是定义package是抽象的,当abstract为true时表名这个package不能被用户使用;namespace表示Action的唯一命名空间,即在调用这个Action的时候需要加上namespace这个前缀。

<action>定义我们要访问的每个url,以及定义在访问这个url时将要访问的类;默认执行的是这个类里面的execute()方法,如果要执行这个类里面的其他方法,则加上method属性,让method等于你要执行的那个方法名即可。

<result>标签表示在执行完操作以后返回到浏览器的内容,result有name和type两个属性,下面会详细解释这个标签。

(2)还有另一种使用struts.xml的方法,如下:

 <struts>
<!--这里要介绍的是分模块配置,即在此xml下用include表示每个模块,再在每个模块下进行配置package之类的 ,要注意的是每个xml下配置的package名字是不一样的-->
 <include file="zichan.xml"></include>
 <include file="cheliang.xml"></include> 
</struts>
即我们可以定义多个xml文件,用以上方式把它们导入。

三、Actions

Action是struts2的核心,每个url都会映射到特定的action。

action的两个重要功能:(1)action能把数据从请求传递到视图(2)action协助框架确定哪个结果应该呈现在响应请求的视图中。

struts对action的唯一要求是有一个无参数方法返回String或者Result对象,而且必须是pojo(即Javabean对象),如果没有指定的无参数方法则默认是execute方法。

一般我们定义action,都会继承ActionSupport类,这个类继承了6个接口,其中Action接口如下:

public interface Action {
 public static final String SUCCESS = "success";
 public static final String NONE = "none";
 public static final String ERROR = "error";
 public static final String INPUT = "input";
 public static final String LOGIN = "login";
 public String execute() throws Exception;
 }
看一个简单的例子:

HelloNameAction.java

package action;
import com.opensymphony.xwork2.ActionSupport;
/*
 * struts2 get/set自动获取设置数据
 */
public class HelloNameAction extends ActionSupport{
private String name;

	public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
@Override
public String execute() throws Exception {
	// TODO Auto-generated method stub
	System.out.println("执行了HelloNameAction的默认方法");
	return SUCCESS;
}
}
struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
  <package name="helloWorld" extends="struts-default">
  	<action name="helloName" class="action.HelloNameAction">
  		<result name="success">helloName.jsp</result>
  	</action>
  </package>
</struts>
helloName.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${name},你好!
</body>
</html>
login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="helloName" method="post">
用户名:<input type="text" name="name"/>
<input type="submit" value="登录">
</form>
</body>
</html>
结果:


一个package里面可以配置多个action。
四、结果类型

<result>标签扮演的是视图的角色,action负责业务逻辑,<result>标签就是显示视图。
<result >中的type属性:

(1)type默认是dispatche,内部转发,它使用RequestDispatcher.forward()方法,内部转发参数是可以传递过去的

<a href="hello?name=ltt">这个ltt可以带过去

(2)type="redirect",重定向,底层调用的是response.sendRedirect(),重定向的参数是带不过去的

<a href="hello!r?name=ltt">这个ltt是不可以带过去
(3)type="chain",链条,即在一个action里面再请求另一个action,如下

<result name="hello" type="chain">hello2</result>
....
<action name="hello2"..>
(4)type="redirectAction"重定向到一个action,这和上面的区别是,redirectAction数据是带不到第二个action里面去的。


<result >中的name属性:

SUCCESS:Action正确的执行完成,返回相应的视图,success是 name属性的默认值;
NONE:表示Action正确的执行完成,但并不返回任何视图;
ERROR:表示Action执行失败,返回到 错误处理视图;
INPUT:Action的执行,需要从前端界面获取参数,INPUT就是代表这个参数输入的界面,一般在应用中,会对这些参数进 行验证,如果验证没有通过,将自动返回到该视图;
LOGIN:Action因为用户没有登陆的原因没有正确执行,将返回该登陆视图,要求用户进行 登陆验证。

五、拦截器

1.拦截器可以实现:

在调用action之前提供预处理逻辑。
在调用action后提供后处理逻辑。
捕获异常,以便可以执行备用处理。

2.struts2框架给我们定义了很多拦截器,自己可以查文档看。

<interceptor name="fileUpload">这就是一个fileUpload拦截器

拦截器栈:里面定义了很多拦截器,下面就是一个我们自定义的拦截器栈,我们默认使用的都是struts2定义的叫做defaultStack的拦截器栈。

<interceptor-stack name="myStack">
  	   <interceptor-ref name="loginInterceptor"></interceptor-ref>
  	    <interceptor-ref name="defaultStack"></interceptor-ref>
  </interceptor-stack>
<interceptors></interceptors>这一对标签里面定义拦截器以及拦截器栈:

<interceptors>
  	<interceptor name="myInterceptor" class="interceptor.MyInterceptor"></interceptor>
  	<interceptor name="loginInterceptor" class="interceptor.LoginInterceptor"></interceptor>
  	<interceptor-stack name="myStack">
  	   <interceptor-ref name="loginInterceptor"></interceptor-ref>
  	   <interceptor-ref name="defaultStack"></interceptor-ref>
  	</interceptor-stack>
 </interceptors>
<default-interceptor-ref name="myStack"></default-interceptor-ref>这个标签就是配置默认使用的拦截器栈。
3.自己写一个拦截器:

拦截器都要实现Interceptor接口,例子如下:

package interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
/*
 * 自定义拦截器
 * 拦截器就是在执行action之前和之后要执行的动作	
 */
public class MyInterceptor implements Interceptor{
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("MyInterceptor销毁");
	}
	@Override
	public void init() {
		// TODO Auto-generated method stub
		System.out.println("MyInterceptor初始化");

	}
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("Action执行之前");
		String result=invocation.invoke();
		System.out.println("Action执行之后");
		return result;
	}
}
在执行action之前先执行这个拦截器,invocation.invoke()是执行目标结果的返回的是success或者error,这个结果是传递给result标签里面的name的,如果执行完这个拦截器以后还有拦截器则接着执行拦截器,如果没有拦截器了就接着执行action里面的动作,把action里面的执行结果返回给String result=invocation.invoke()这个result,通过拦截器把这个result返回到struts.xml中的result标签里面的name。

4.struts.xml中先定义的拦截器 先执行。

六、值栈

值栈就是一组对象,下面的就是我们设置的一些值栈:

public String execute() throws Exception {
	ActionContext actionContext=ActionContext.getContext();
	//获取狭义的指针,用来存储数据的
	ValueStack valueStack=actionContext.getValueStack();
	valueStack.set("name","ltt(valueStack里面的)");
	valueStack.set("age","18(valueStack里面的)");
	//session
	Map<String, Object> session = actionContext.getSession();
	session.put("name", "ltt(session)");
	session.put("age", "18(session)");
	//application
	Map<String, Object> application = actionContext.getApplication();
	application.put("name", "ltt(application)");
	application.put("age", "18(application)");
	//javabean对象
	person=new Person("pl",18);
	//List
	persons=new ArrayList<Person>();
	persons.add(new Person("listPerson1",23));
	persons.add(new Person("listPerson2",24));
	//Map
    PersonMap=new LinkedHashMap<>();
    PersonMap.put("first", new Person("mapPerson1",23));
    PersonMap.put("second", new Person("mapPerson2",23));
	return SUCCESS;
}
我们用OGNL来在页面上获取上面的值,OGNL是一种强大的表达式语言,用于引用和操作值栈上的数据,还可用于数据传输和类型转换,下面的就是获取上面的值
</head>
<%
request.setAttribute("name", "ltt(request)");
request.setAttribute("age","18(request)");
%>
<body>
获取狭义上的值栈数据:<s:property value="name"/>
<s:property value="age"/><br/>
请求参数:<s:property value="#parameters.name"/>
<s:property value="#parameters.age"/><br/>
request:<s:property value="#request.name"/>
<s:property value="#request.age"/><br/>
session:<s:property value="#session.name"/>
<s:property value="#session.age"/><br/>
application:<s:property value="#application.name"/>
<s:property value="#application.age"/><br/>
<!-- attr属于顺序取值,按照page,request,session,application的方式取值 -->
attr取值:<s:property value="#attr.name"/>
<s:property value="#attr.age"/><br/>
ognl访问javaBean对象:<s:property value="person.name"/>
<s:property value="person.age"/><br/>
ognl访问List集合:<s:property value="persons[0].name"/>
<s:property value="persons[0].age"/><br/>
<s:property value="persons[1].name"/>
<s:property value="persons[1].age"/><br/>
ognl访问Map:<s:property value="PersonMap['first'].name"/>
<s:property value="PersonMap['first'].age"/><br/>
<s:property value="PersonMap['second'].name"/>
<s:property value="PersonMap['second'].age"/><br/>
</body>
总结:OGNL访问ActionContext数据

#parameters.name 访问请求参数的数据
#request.name 访问request的数据
#session.name 访问session的数据
#application.name 访问application的数据
#attr.age attr属于顺序取值,按照page,request,session,application的方式取值
ognl还可以访问javabean对象,list,map
以及访问静态方法和静态变量,但是如果要访问静态方法,必须在struts.xml中添加一句配置:
  <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant> 
访问静态属性的规则:@包加类名@静态属性,比如:访问静态属性: <s:property value="@common.MyStatic@str"/><br/>

七、其他

(1)全局变量

每个action都会返回错误界面或者成功界面时,我们可以把公共的拿出来作为全局变量。在<global-results>标签中配置,如下:

  	<global-results>
  	  		<result name="error">error.jsp</result>
  	</global-results>
(2)自定义验证

(3)文件上传下载等都很方便

八、结合之前的jsp&servlet编写的小项目,用struts2改写了一遍,发现最大的方便就是从页面取值,直接定义javabean对象就可以通过struts2默认的拦截器自动获得相对应的取值



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值