#Struts2知识复习之一

  1. 概述:struts2是一个基于MVC设计模型的轻量级web应用框架,它本质上相当于servlet。 它是 Struts1(早期基于MVC模式的轻量级Web框架) 和 WebWork(openSymphony组织的J2EE Web框架)技术的合并。 它的核心是WebWork,采用拦截器的机制来处理用户请求,使业务逻辑控制器与ServletAPI脱离。
  2. struts2优势:
    • 提供Exception异常处理机制
    • 提供良好的Ajax支持
    • Result方式的页面导航,通过Result标签实现重定向和页面跳转。
    • 开源,扩展性强
  3. web层框架(struts1,struts2,webwork,springMVC)都基于前端控制器的模式
    • 什么前端控制器模式? 概述:传统开发中,每一个请求都会对应一个Servlet,这样就会导致很多的Servlet。 而Struts2框架将所有请求都经过一个前端控制器,通过拦截器来过滤,实现部分功能后, 将剩下具体的操作提交到具体的Action进行处理。

struts2入门基本

1. Struts2开发包目录
	* apps:存放Struts2实例程序
	* docs:Struts2的API参考文档
	* lib:Struts2的核心类库,以及第三方插件类库。
	* src:Struts2的框架源码
2. web工程引入的struts2开发包
	概述:实际开发中,  因为我们不需使用lib目录下所有jar包,所以我们引入的是 
			  apps\struts2-blank\WEB-INF\lib 目录下的jar包。
	struts2开发jar包分析:
		struts2-core-2.3.24.jar  Struts2核心类库
		xwork-core-2.3.24.jar  webWork核心类库,Struts2构建的基础
		ognl-3.0.6.jar 对象图导航语言(Object Graph Navigation Language)  Struts2通过其读写对象的属性。
		freemarker-2.3.22.jar	Struts2标签模板使用的类库
		log4j-api-2.2.jar   Struts2日志管理组件依赖包的api
		log4j-core-2.2.jar  Struts2日志管理组件依赖包
		commons-fileupload-1.3.1.jar  Struts2文件上传组件依赖包
		commons-io-2.2.jar  Struts2的输出输入,传文件依赖的jar包
		commons-lang3-3.2.jar  包含一些数据类型工具,是对java.lang包的增强
		javassist-3.11.0.GA.jar	javascript字节码解析器
		asm-3.3.jar  操作字节码类库
		asm-commons-3.3.jar  提供基于事件的表现形式。 asm-tree-3.3.jar 提供基于对象的表现形式。

Struts2配置详解

& 基本配置环境搭建
	*struts.xml文件的约束:
		<!DOCTYPE struts PUBLIC
		"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
		"http://struts.apache.org/dtds/struts-2.3.dtd">
	*头标签:<struts></struts>
&  Struts2执行流程:
	从客户端发送的请求,会先经过前端控制器(核心过滤器 StrutsPrepareAndExecuteFilter )过滤器中执行一组拦截器,完成部分功能。
    执行完拦截器后,就会执行Action,返回一个结果视图,根据Result配置进行页面的跳转。
1. struts.xml文件配置
	(1)常量配置(使用<content></content>)
		注:所有常量配置都可在struts2-core-2.3.24.jar包下的/org/apache/struts2/default.properties文件中找到
		常量的配置属性:
		方式一(基于struts.xml文件)
			<1> i18n:国际化编码,解决Post提交乱码。
					示例:
					<constant name="struts.i18n.encoding" value="UTF-8"></constant> 
			<2> struts.action.extension=action,,  指定访问action时的后缀名, action,, 为默认值
					action,,	代表后缀名为action或空	(两个  ,  符号代表空)。
					示例:
					<constant name="struts.action.extension" value="action,,"></constant> 
			<3>struts.devMode = false(默认) 指定struts2是否以开发模式运行,开发模式具有以下优点:
					1.热加载主配置文件(不需要重启即可生效)
					2.提供更多错误信息输出,方便开发时的调试
					示例:
					<constant name="struts.devMode" value="true"></constant> 
			<4>配置动态方法调用是否开启
				     示例:struts.enable.DynamicMethodInvocation = false(默认)  默认是关闭,使用需手动开启
					 分析:
							配置后浏览器访问服务器数据的格式为:Action类后 + !+对应的方法名
							如:http://localhost/struts2_01/dynamic/Demo1Action!query
					这种动态方法常量配置会导致  地址栏的名称怪异,不利于SEO搜索引擎的检索
		方式二(基于web.xml文件)
			配置struts2的编码为utf-8到整个web应用中
			<context-param>
				<param-name>struts.i18n.encoding</param-name>
				<param-value>UTF-8</param-value>
		    </context-param>
		方式三(基于  在src下重写一个常量配置文件 default.properties覆盖框架已有的常量配置文件)
	(2)基本配置
		<package	name="" namespace="" extends="struts-default">
				<action name="" class=""  method="">
					<result name="success">/xxx.jsp</result>
				</action>
		</package>
		细述:
			<1>父标签package,将多个Action封装到一个包里。其属性如下:
				   * name:包名,起到标识作用,随便起但不能重复。	
				   * namespace:给Action的访问路径定义一个命名空间。
				   * extend:继承Struts2框架下的一个指定包struts-default的所有配置
								该属性标识 该包是否为抽象,若为true则说明该包不能独立运行,只是专门被继承的 
			<2>一级子标签<action>,配置action类。其属性如下:
					* name:决定了action的资源访问名
					* class:action的完整类名
					* method:调用actionl类中哪个方法来处理请求。
			<3>一级子标签<default-action-ref>
					<default-action-ref name="xx.dd.Demo2Action"></default-action-ref>
					当访问找不到包下的ation,会使用Demo2Action作为默认的action处理请求
			<3>二级子标签<result>,结果配置
					* name属性:标识处理结果的名称,与Action类方法的返回值对应
					* type属性:指定调用哪一个result类来处理结果,默认使用 转发 进行结果处理。
									  &  结果处理方式:
												  1 type="dispatcher"  请求转发
												  2 type="redirect"     重定向
												  3 重定向到另一个Action(常用)
														<!--在重定向到Demo1Action中,把本Demo3Action中的参数name值:tom传递给Demo1Action-->
														<result name="success" type="redirectAction">
															<param name="actionName">Demo1Action</param>
															<param name="namespace">/</param>
														<!--如果添加的参数struts看不懂,可以通过把参数附加到重定向的路径之后进行参数传递
																如果参数是动态的,可以使用${}包裹ognl表达式,动态取值
														-->
															<param name="name">${name}</param>
														</result>
												  4 请求转发到另一个Action(不常用了解即可)
													<result name="success" type="chain"> 
														<!--跳转到的Action名称-->
															<param name="actionName">Demo1Action</param>
														<!--跳转到的Action命名空间-->
															<param name="namespace">/</param>
													 </result>
									  & <result>标签体内容:填写跳转页面的相对路径
			<4>二级子标签<interceptor-ref >
					<!--3 为action单独指定哪个拦截器(栈)
						注意:此拦截器只作用于此 action中   此刻action中拥有21个拦截器。(自定义1个+默认的20个)-->
					<interceptor-ref name="myStack"></interceptor-ref>
	(3)引入src路径下其他的struts.xml文件,格式如下:
			<include file="xxx/xxx/struts.xml"></include>
	(4)配置拦截器,格式如下:
			<!--自定义拦截器的配置-->
			<interceptors>
				<!--1 注册拦截器-->
				<interceptor name="myinterceptor3" class="cn.itheima.interceptor.MyInterceptor3"></interceptor>
				<!--2 注册拦截器栈-->
				<interceptor-stack name="myStack">
					<!--自定义拦截器的拦截器栈的引入建议放在默认20拦截器栈的前面
						因为如果自定义拦截器存在错误信息,后面的拦截器会帮忙处理-->
					<interceptor-ref name="myinterceptor3">
						<!--指定哪些方法不拦截-->
						 <!-- <param name="excludeMethods">add,delete</param> -->
						 <!--指定哪些方法需要拦截,两者只能取其一进行配置-->
						 <param name="includeMethods">add,delete</param>
					</interceptor-ref>
					<!--引用默认的20个拦截器栈-->
					<interceptor-ref name="defaultStack"></interceptor-ref>
				</interceptor-stack>
			</interceptors>
			<!--3 指定框架使用自定义拦截器栈   -->
			<default-interceptor-ref name="myStack"></default-interceptor-ref>
2. 配置核心过滤器
	概述:所有的WEB框架都有基于 前端控制器(核心过滤器)模式的特点。
	示例:
			<!--struts2核心过滤器(struts2的核心是基于webwork的过滤器) -->
			<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>
3. Struts2配置文件加载顺序
	概述:每次从客户端发送请求到服务器都要经过Struts2的核心过滤器StrutsPrepareAndExecuteFilter,该过滤器有预处理和执行的功能。
	* 预处理主要用来加载配置文件,对应过滤器的init()方法。
	* 执行用来执行一组拦截器完成部分功能,对应拦截器的doFilter()方法。
	详解doFilter()方法中对Struts2配置文件的加载顺序:
		(1)先加载struts.xml文件,对应配置action以及常量等。
		(2)后加载struts.properties文件,对应配置常量等。
		(3)最后加载web.xml文件,对应配置核心过滤器以及常量。

Action类的编写

1  概述:Action作为框架的核心类,也作为业务逻辑控制器,实现对用户请求处理,每一次请求都对应一个独立的Action类工作单元.
		  Action类是一个POJO类(plain ordinary java object  简单的java类)具有一部分getter/setter方法,不继承任何父类,不实现任何接口
		  有一个共有无参构造(默认)  和一个execute方法(public权限修饰,字符串返回类型,方法为空参)。
		  满足上述要求的POJO类可算作Action类实现。除此之外,Struts2框架还提供了Action类的其他实现方式。
2  Action类的实现
	(1)方式一:实现Action(com.opensymphony.xwork2.Action)接口
				   代码示例:
					public class HelloAction implements Action {
						@Override
						public String execute() throws Exception {
							System.out.println("hello world!");
							return "success";
						}
					}
		但是由于该接口定义了一个execute方法以及五个基本常量:
		* SUCESS	 成功跳转  	* NONE 不跳转   	* ERROR  跳转到错误处理页面
		* INPUT	数据校验时要跳转的路径       * LOGIN	跳转到登录页面
		为开发者提供帮助小,实际开发一般不用,而是使用继承ActionSupport类。
	(2)方式二:继承ActionSupport类
					代码示例:	
					public class HelloAction extends ActionSupport {
					}
		ActionSupport类本身实现了Action接口,除此还实现其他接口,为用户提供更多的功能。
		实际上,ActionSupport是Struts2的默认Action处理类,继承该类可简化Action开发。
3 Action类的访问
	(1)使用通配符 *  配置Action动态方法(解决一个Action类处理一个模块中多个请求)
		示例:
				<action name="Demo1Action_*" class="xxxx.Demo1Action" method="{1}">
					<result name="success">/hello.jsp</result>
				</action>
		分析:
				Demo1Action_* 的* 为 Action类的 方法名,与method="{1}"(取出第一个通配符的内容)中的 1 对应,
				若Demo1Action_*_*    则method="{2}"
		扩展:值得一提,<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant>
				  常量配置是实现另一种Action方法的方式