Struts 2学习笔记配置详解

Struts 2配置详解

本章针对Struts2框架搭建, 项目结构的配置文件解析…及一些Action 配置文件更高级的操作…

web.xml

众所周知, Struts2框架是基于MVC模式。
基于MVC模式框架的核心就是控制器对所有请求进行统一处理.Struts2的控制器;
StrutsPrepareAndExecuteFilter由ServletAPI中的Filter充当。
当web容器的接收到登录请求后,将请求交由在web.xml中配置的过滤 StrutsPrepareAndExecuteFilter.
web.xml
目前无论哪种 MVC框架, 都离不开web.xml 文件的配置
(web.xml文件并不是 Struts2框架特有的文件, 只有在web应用中配置了web.xml 文件, MVC框架才可以真正与web应用融合…)

实例

<?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_2_5.xsd" id="WebApp_ID" version="2.5">
 
 <!-- 省略了其它web.xml的基础配置... -->
	
  <!-- Struts2过滤器 -->
  <!-- 作用:启动加载struts.xml文件-->
	<filter>
		<filter-name>struts</filter-name>
		<!-- Struts2核心控制器类:
				早期还是:org.apache.struts2.dispatcher.FilterDispatcher
		 -->
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  <!-- 现在! -->
	</filter>
	
	<filter-mapping>
		<filter-name>struts</filter-name>
		<url-pattern>/*</url-pattern>		<!-- /*: 任何请求都要经过.. -->
	</filter-mapping>

</web-app>

<!-- 
	StrutsPrepareAndExecuteFilter :
		作为一个Filter(过滤器),在web应用中运行,它负责拦截所有用户的请求,过滤用户请求到对应的 Action中执行;
		在根据,Action 返回的"逻辑视图名" 响应指定的页面...如果请求是以 ".action" 结尾,该请求会被输入到Struts2框架进行处理..
		可以包含一些初始化参数,经常使用如 config 加载XML的形式配置文件。
		如果没有设置 StrutsPrepareAndExecuteFilter ,默认加载Struts2的配置文件: struts-default.xml struts-plugin.xml struts.xml 进行讲解..
-->

Struts2 的核心控制器: web.xml 因为 Filter 基本不会变,所以个人对于这个文件基本都是学会了。后面直接cope;

Action控制器 和 Struts2配置文件; (本篇重点)

Action

在Struts2框架中,控制器是由两个部分组成的:

核心控制器:用于拦截用户请求,对请求进行处理。(web.xml)
业务控制器:调用相应的请求Model类,实现业务处理…返回结果; (定义的action Java类)
对于开发者来说:
Struts2的主要编码工作就是, Action类; (之前学习两种方式,实现Action接口 继承ActionSupport类常用 )
开发者每完成一个Action类, 都需要在struts.xml中配置对应的 <action />
页面发送请求——经过web,xml过滤——Struts2配置文件: 处理——
找到对应的xxaction类 一系列操作后返回一个"逻辑视图名"——至Struts2配置文件根据result 找到对应响应页面…;

Struts2配置文件 (struts.xml)

struts.xml 就是 Struts2的核心配置文件 !
包含 action result 等配置, 主要负责对页面请求管理,分配到对应的 Action类中;
一个经典的Struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- struts.xml声明部分,工具没有配置的DTD文件,可以直接cope下面的... -->
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<!-- struts.xml根节点 -->   
<struts>
	
	<!-- 请求参数的编码方式 -->
	<constant name="struts.i18n.encoding" value="UTF-8"/> 
	<!-- 文件上传最大值 -->
    <constant name="struts.multipart.maxSize" value="104857600" />
	<!-- 所有匹配*.action的请求都由struts2处理 -->
    <constant name="struts.action.extension" value="action" />
    <!-- ...省略其它... -->
	
	<package name="one" namespace="/" extends="struts-default" >
		<!-- action:用于接收页面的请求,指定对应的action类中执行...(package中可以配置多个)
				name:根据页面请求根据name找到指定的action 	class:指定对于action java类进行执行;
		  -->	
		<action name="" class="" >
			<result name="" >/响应页面</result>		<!-- 根据 xxxaction类,返回的逻辑视图名指定对于的响应页面... -->			
			<!-- 都建议加个/ 不然默认是namespace="中指定路径下响应页面"  /:表示根目录下响应页面; -->	
		</action>	
	</package>
	
	<package name="tow" namespace="/" extends="one" >			<!-- 包2继承了包1, -->
	</package>
	
	<package name="three" namespace="/" extends="struts-default" >
		<action name="" class="" >
			<result name="" >相应页面</result>		
		</action>	
		<!-- ...省略其它操作... -->
	</package>

	<!--不指定路径,默认在src下时的方式-->
	 <include file="struts01.xml"/>
	 <!--配置文件在具体包中时的方式-->
    <include file="com/wsm/action/struts-02.xml"/>		<!-- 假设在com.wsm.action包下; -->
</struts>

<!-- 
	<struts> 	元素是文件的根元素,所有其他元素都放在 <struts></struts> 中。
	<constant> 	元素用于进行常量配置。可以改变Struts2 框架的一些行为,从而满足不同应用的需求:name="常量名"  value="常量值"
	<package>	提供了将多个Action组织为一个模块的方式;
		name		package名称,必须是唯一的 package可以扩展,一个struts.xml中可以有多个package 执行时从上往下匹配...
		namespace	package命名空间,通常都是 "/"表示请求为 项目名/请求名; 进行匹配       如果为"/wsm"则页面请求只有为:项目名/wsm/请求名; 才能进入对应包中匹配;
					假设:   namespace="/wsm"  页面发送一个请求:localhost:8080/项目名/页面.jsp; 它会去struts.xml中寻找包,namespace="/" 的进行匹配; /:表示的就是项目根目录下的请求!
		extends		继承:一般要求必须继承struts-default的包. 或一个包继承另一个包!(如上实例)
					可在 struts2-core-2.3.16.3.jar中查看struts-default.xml 中声明Struts2核心功能; 一般不会轻易替换!
		abstract	是否为抽象包,让别人继承用的,没有任何action子元素的包就可以声明为抽象包。
	
	<include> 	元素用于在一个 struts.xml 配置文件中包含其他的配置文件。(随着一个项目的时间...越来越大一个struts.xml必定会非常臃肿)
				为了提高可读性,Struts2 允许将一个配置文件拆分为多个配置文件,但Struts程序默认只读:struts.xml名的文件;
				所有都是在 struts.xml 中引入其它不同名字但是存在相同功能的配置文件:<include file="struts01.xml"/>	   		
 -->

同一个Action类 实现多个方法;

method属性:

在之前的程序中。
每实现一个功能都需要去创建一个 Action类, 并完成相应的方法();在struts.xml 中配置 < action> 太恶心了吧!
如何同一个Action类 实现多个方法
为了减少Action 的数量:通常在一个Action 中编写不同的方法,对应处理不同的请求;
这里我感觉不是很难!就不写实例了…

需要注意的是struts.xml`文件

		<!-- 登录 -->
		<action name="login" class="定义的JavaAction类" method="login" >
			<result name="ok" >/index.jsp</result>		
			<result name="no" >/login.jsp</result>
			<result name="err" >/err.jsp</result>	
		</action>
		<!-- 注册 -->
		<action name="register" class="定义的JavaAction类" method="register" >
			<!-- 根据返回的逻辑视图匹配对应页面.. -->
			<result name="ok" >/login.jsp</result>		
			<result name="no" >/login.jsp</result>
			<result name="err" >/err.jsp</result>		
		</action>
		<!-- 
			观察上面两个 <action> 
				name="不同,表示页面不同的请求" 
				class="相同的Action类,根据不同的请求确指定同一个Action类" 
				method="不同,确定执行Action类中的具体的方法";
			如果请求的url是 login 则执行类中的 login();方法
			如果请求的url是 register 则执行类中的 register();方法
		 -->

好处:

减少了程序中的 Action类
一旦Action 中需要添加新的方法还需要在 struts.xml 中编写对应的 < action method=“指定方法名” > 即可…
小提示:Struts2根据action元素中的method属性查找执行方法的两种途径:

  1. 查找与 method属性值一致的方法名;
  2. 查找 doMethod();形式的方法名;

假设:<action ... method="login" >
优先寻找 login(); 如果找不到会寻找 doLogin(); 方法, L 大写欸~

Action动态方法调用:

为了减少配置 Action类的数量, 还可以通过动态方法进行处理。
这个感觉更牛, 解决了定义多个 Action类 还有struts.xml 不用在频繁定义:< action/>
实现:

  1. 首先要在struts.xml 中开启动态方法调用:
    <constant value="true" name="struts.enable.DynamicMethodInvocation"/> 默认是不开启的
    且该Action中所有方法都是普通的 没有重载. 都返回值String
  2. 页面发送请求的方式也有一点变化!就是根据请求来确认请求的方法的!重点
    页面请求方式: 请求Action类名! 类中方法名;形式进行请求
  3. 该方式对 Action类 struts.xml 没有太大影响,而是对请求方式有讲究
    Action类中定义多个方法,对应多个不同的功能…
    sturts.xml 只是对: <action name="action名" class="指定的action类" > 有讲究;
    请求以:action名!方法名[.后缀]; 形式请求, 根据action名找到对应的Action类, 方法名指定对应的方法…[.后缀]可选:.action jsp…

假设: 页面一条请求:userAction!login;
框架将调用 UserAction名对应类的 login(); 方法. struts.xml 根据方法返回"逻辑视图名" 响应对应页面!

Action中通配符的使用:

在配置 < action… /> 时候,一般需要指定 name class 和 method属性;
name属性, 使用支持通配符 在 class 和 method 也支持使用表达式…(另一种动态方法调用)

		<action name="*User" class="com.zb.action.UserAction" method="{1}">
			<result name="返回逻辑视图">/{1}_User.jsp</result>			<!-- 响应页面,允许使用{1} 表达式; -->
			<result name="err">/err.jsp</result>
		</action>
		<!-- 
			name:	请求名,可以用通配符 *xxx 表示,一般都是 *Action类名;
			class:	没啥变化就是指定对应的Action类,对于特殊的项目结构.. 它也支持使用 {1} 表达式...进行特殊操作;
			method:执行的方法...一般都是用 {1};
			
			假设: 	以上面实例为例子发送一条请求: addUser 
					通过name进行比较请求符合条件 *User   结果:		*  等于add
					而{1} 表达式,表示的值就是 *:				   	{1}等于* 	 
			所以:
					method="{1}",就直接表示请求的是该 Action类中的 add();
					通用如果对于不同请求,不同的 class="action类"; 的操作也可以通过该方法进行特殊处理..
			要求:	
					使用该方法需要满足条件: 请求的URL是   方法名+固定name名; 
					正好对应的是  *name;     进行匹配Action类...
		 -->

配置默认的Action:

Struts2 对于请求, 如果请求了一个并不存在的请求, 则页面报错: HTTP 404错误!
Struts2 对于这种异常处理使用

<!-- 默认引用 -->
	<package name="default" namespace="/" extends="struts-default" >
		<default-action-ref name="defaultAction"></default-action-ref>
		<!-- 默认action的配置, 用户输入不匹配的action地址, 则默认执行的路径 页面响应!-->
		<action name="defaultAction">
			<result>/err.jsp</result>
		</action>
	</package>
<!--
	每个包都只能有一个 default-action-ref
		default-action-ref 的name属性指定包下的一个 <action name="xx" >
	如果一个struts.xml中有多个包~每个包下都有default-action-ref:
		由字package —— 父package寻找,找到停止...
-->

Result配置:

Struts2 通过在 struts.xml 文件中使用< result …/> 元素配置结果:
Result 由两个部分组成:

  1. name=”页面返回的逻辑视图名“ 对应的一个结果页面; <result name="逻辑视图" >/结果页面.jsp</result>
  2. Result的type 属性, 结果类型。。。

常用结果类类型:
dispatcher类型

  1. 最常用的结果类型, 默认类型;后台使用RequestDispatcher转发请求; (转发懂吧会携带参数那种…)
    但是很多情况下, 转发并不一定实用!

redirect类型

  1. redirect结果类型, 是指内部使用 HttpServletResponse对象的sendRedirect()将请求重定向至指定的URL
    这意味着, 在页面重新发送一次请求: Action实例/属性 request作用域属性都将丢失~

redirectAction类型

  1. redirectAction 与 redirect 类似,都是指重定向!
    但使用 redirectAction 类型主要用于重定向到另一个 Action!!(不是页面! 且原请求中的数据将会丢失~)
    也就是说:<result name="返回逻辑视图" type="redirectAction" >/action请求</result>
    当前一次请求处理完成后, 重定向Action 相当于又发送了一条对应Action 的请求!持续操作…

动态结果

动态结果指:
你不指定执行后的结果是那一个情况下, 只有在运行时才知道结果…作为视图显示给用户…
即, 在配置时候使用表达式: 在运行时, 框架根据表达式的值确定要使用的结果集;
举例:
同一个登录页面, 却有两个不同的角色;
普通用户登录去到 user页面
管理员登录去到 admin页面

定义UserAction

public class UserAction extends ActionSupport {
	//全局变量
	private String nextDispose;
	//登录方法
	public String login() {
		...
		//判断是否 管理员
		if(user.isManager()){
			nextDispose = "admin";
		}else{
			nextDispose = "user";
		}
		return SUCCESS;
	}
	//get/set方法();
	public String getNextDispose(){
		return nextDispose;
	}
	...
}

struts.xml

<struts>
	<package name="default" extends="struts-default">
		<!-- 框架通过重定向Action 方式又对Action发送了一次请求! 
				而且请求的Action  来源于: ${nextDispose} 相当于调用Action中的getNextDispose方法,获取重定向Action
		  -->
		<action name="login"
			class="cn.houserent.action.UserAction" method="login">
			<result name="success"  type="redirectAction">${nextDispose}</result>
			<result name="error">/page/error.jsp</result>
		</action>
		
		<!-- 请求或重定向请求 admin -->
		<action name="admin" class="com.wsm.action.admin">
			<result name="xxx">/响应页面.jsp</result>
		</action>
		<!-- 请求或重定向请求 user-->
		<action name="user" class="com.wsm.action.user">
			<result name="xxx">/响应页面.jsp</result>
		</action>
	
	</package>
</struts>

全局结果

在一些情况下,多个action 可能需要同一个 < result /> 返回结果!
例如:
每一个项目都有一个专门对异常处理的页面, 而实现方式是每一个Action类运行时出现异常。
返回error之类的字符, < result name=“error”>/err.jsp< /result > 指定一个结果异常页面;
对于这种需要频繁冗余的操作,可以设值为全局结果 来使用!
在包中定一个全局结果 任何一个action类返回对应字符,都指向全局结果指定的结果页面…一定程度上减少代码;

<struts>
	<package name="default" extends="struts-default">
	<!-- 全局的result配置,公共的配置: 只要java代码中的return: "error";
	 	 统一去err.jsp页面,减少每一个action的result的配置
	-->
		<global-results>
			<result name="error">/err.jsp</result>
		</global-results>
	</package>
</struts>
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java.慈祥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值