简介

又拾起每天写博客的习惯了,之前一致忙于学后面的框架技术,所以在过年这段时间暂时更新博客了。现在又进入学习状态,所以还是坚持每天写博客和课上学习的保持一致。接下来暂时告别Web开发,进入框架技术学习。过年这段时间接触了一些,所以现在学起来还是得心应手的。期待接下来的学习,把自己的能力提升起来,fighting~~

 

理解Struts框架-简单自定义框架

自定义框架:主要掌握的知识(反射,常用数据结构与算法,设计模式)
MVC开发模式  (Controller前期项目是最复杂的地方)
Controller:  Servlet(控制器  if--else if---else if---else)
	*Servlet是可以直接访问的
Filter(过滤器也可以作为一个控制器)
	*Filter不能直接访问,/*代表这个FIlter能够过滤器所有用户请求

Struts1--------------->Struts2发展历程中,就是一个由控制器(Servlet------>Filter)
总结:
	使用自定义框架后,进行开发,程序员关注什么?
	view自己写
	控制器的Filter不用写  ,只关注业务控制器Action的实现类
	Model:自已写
 

Struts2概述及作用

1、是什么?
	Struts2是一个M(模型---域--范围模型)V(View视图)C(控制器)框架(模型2)。框架都是一个半成品。提高开发效率。
	Struts1是一个MVC框架,非常流行。有很大的缺点。此时一个webwork的框架设计超前,名气不是很大。Struts1+webworkd=struts2。用的是struts1的名字,但是与sruts1没啥关系,struts2的核心是webwork框架。
2、能干什么?
	web开发主要干的工作:
	获取请求参数
	封装到JavaBean
	验证和转换
	调用业务代码存数据
	转向某个页面展示结果
	表现层的开发技术

 

搭建Struts2开发环境

目录结构:
	a). apps:框架本身提供一些案例(学习)
	b). docs:框架本身提供的文档(指南和API)。不保证100%正确
	c). lib:框架需要的jar包及第三方的jar包(不要全拷贝)
	d). src:源码
Sturts2包介绍
	struts2-core-2.3.1.1.jar:Struts 2框架的核心类库
	xwork-core-2.3.1.1.jar:Command模式框架,WebWork和Struts2都基于xwork 
	ognl-3.0.3.jar:对象图导航语言(Object Graph Navigation Language), struts2框架通过其读写对象的属性
	reemarker-2.3.18.jar:Struts 2的UI标签的模板使用FreeMarker编写
	commons-logging-1.1.x.jar:ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。
	commons-fileupload-1.2.2.jar: 文件上传组件,2.1.6版本后需要加入此文件
	commons-io-2.0.1.jar:传文件依赖的jar包
	commons-lang-2.5.jar:对java.lang包的增强	StringUtils.isEmpty(str)
	javassist-3.11.0.GA.jar:动态代理的开发包

搭建步骤
	1. 新建一个JavaWeb工程
	2. 拷贝struts2运行所需的必要jar包。(方便办法:struts2发行包\apps\struts-blank.war,拷贝其中的lib下的所有jar)
	3. 在web.xml中配置核心过滤器:StrutsPrepareAndExcuteFilter(框架提供)
	4. 在WEB-INF\classes目录下建立一个名称为struts.xml的配置文件。内容如下:(可以从struts2发型包\apps\struts-blank.war中拷贝
	5. 把应用部署到Tomcat中,启动Tomcat,如果没有报错,说明搭建成功

 

执行过程和原理

wps74A9.tmp

1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求;
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);
3、接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请求是否需要调用某个Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用

配置struts.xml 提示问题

1. 如果安装Aptana编辑器 ,请不要用Aptana自带xml编辑器 编写struts2配置文件 
struts.xml提示来自于 DTD约束, 
如果可以上网,自动缓存dtd,提供提示功能
如果不能上网,也可以配置本地DTD提示\struts-2.3.20-all\struts-2.3.20\src\core\src\main\resources 
*** 导入DTD时,应该和配置DTD版本一致
2. struts2提示问题
	Preference中输入xml,查找Catalog,添加URI

 

Struts2的配置文件的位置和加载顺序

struts2 配置文件 由核心控制器加载 StrutsPrepareAndExecuteFilter  (预处理init(),执行过滤) 
	init_DefaultProperties(); // [1]   ----------  org/apache/struts2/default.properties 
	init_TraditionalXmlConfigurations(); // [2]  --- struts-default.xml,struts-plugin.xml,struts.xml
	init_LegacyStrutsProperties(); // [3] --- 自定义struts.properties 
	init_CustomConfigurationProviders(); // [5]  ----- 自定义配置提供
	init_FilterInitParameters() ; // [6] ----- web.xml 
	init_AliasStandardObjects() ; // [7] ---- Bean加载 

结论:
一、default.properties:在struts2-core-**.jar包中的org.pache.struts2.default.properties中(框架本身用的)
二、struts-default.xml:在struts2-core-**.jar包中(框架本身用的)
三、struts-plugin.xml:在struts2-**-plugin.jar包中(插件中,给插件用的)
四、struts.xml:在你应用的构建路径中(程序员进行配置的地方。推荐)
五、struts.properties:在你应用的构建路径中(程序员进行配置的地方)
六、web.xml:此处也可以对struts2框架进行配置(不建议。只建议配置过滤器)

* 后加载文件中struts2 常量会覆盖之前加载文件 常量内容 
   显示struts.action.extension在struts.xml中的取值 ,和web.xml中的取值

 

struts.xml中的常量配置

常用常量
truts.action.extension=action,,  框架要处理的后缀名称。
struts.devMode = true 开发着模式。实际运行时建议为false
struts.i18n.encoding=UTF-8 框架默认使用的编码。请求参数和输入响应
struts.serve.static.browserCache=true 静态资源要不要缓存。

其他常量
(response.setHeader():Expires;Cache-Control;Progma)
struts.ui.theme=xhtml 和显示结果有关,显示用的主题。simple等
struts.objectFactory = spring 指定实例化动作类的工厂(和Spring集成时用)
struts.enable.DynamicMethodInvocation = false 是否允许动态方法调用
struts.multipart.maxSize=2097152 文件上传时的大小限制

struts.xml动作类Action 相关配置

动作类的定义:
方式一:就是一个普通的POJO。不需要继承或实现任何的类或接口。
方式二:实现com.opensymphony.xwork2.Action
	该接口中定义了几个常量:
	String SUCCESS = "success";//执行成功时用
	String NONE = "none";//执行成功后,不转向任何的视图。比如文件下载。
	String ERROR = "error";//执行失败,遇到错误。
	String INPUT = "input";//输入验证失败或转换失败,转向输入原有页面。
	String LOGIN = "login";//没有登录时,转向的页面。
	public String execute() throws Exception;
	优点:可以使用常量,编码可以做到尽量统一。
方式三:(推荐)
	继承com.opensymphony.xwork2.ActionSupport(默认的动作类)


# 动作类的生命周期
	动作类每次访问都会重新被实例化,是线程安全的
# 动作方法:动作类中的定义的处理业务有关的方法
	特点(重要):public
 	返回值类型是String
 	方法没有任何的参数
# 动作方法通配符的匹配 *_* class="**.{1}" method="{2}"
# 动作方法的动态调用
	开启动态常量struts.enable.DynamicMethodInvocation = true
	在action的访问路径 中 使用 "!方法名"

 

 

Action中使用Servlet API

1、 在Action 中解耦合方式 间接访问 Servlet API  --------- 使用 ActionContext 对象
在struts2 中 Action API 已经与 Servlet API 解耦合 (没有依赖关系 )
* Servlet API 常见操作 : 表单提交请求参数获取,向request、session、application三个范围存取数据 
	actionContext = ActionContext.getContext();
	
	*本质分析是否存在线程安全问题? 不会有 答案原码:ActionContext  (使用ThreadLocal存储相关的值)

2、 使用接口注入的方式,操作Servlet API (耦合)
	ServletContextAware : 注入ServletContext对象
	ServletRequestAware :注入 request对象
	ServletResponseAware : 注入response对象
* 程序要使用哪个Servlet的对象,实现对应接口 
*本质分析 <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>

3、 在Action中直接通过 ServletActionContext 获得Servlet API(推荐)
	ServletActionContext.getRequest() : 获得request对象 (session)
	ServletActionContext.getResponse() : 获得response 对象
	ServletActionContext.getServletContext() : 获得ServletContext对象 
	* 静态方法没有线程问题,ThreadLocal

 

结果页面的配置

Action处理请求后, 返回字符串(逻辑视图名), 需要在struts.xml 提供 <result>元素定义结果页面 
1、 局部结果页面 和 全局结果页面 
<action name="result" class="cn.itcast.struts2.demo6.ResultAction">
  			<!-- 局部结果  当前Action使用 -->
 			<result name="success">/demo6/result.jsp</result> 
</action>
 
<global-results>
			<!-- 全局结果 当前包中 所有Action都可以用-->
			<result name="success">/demo6/result.jsp</result>
</global-results>

2、 结果页面跳转类型 
	* 在struts-default.xml 定义了 一些结果页面类型 
	* 使用默认type 是 dispatcher 转发 (request.getRequestDispatcher.forward)
	1)  dispatcher :Action 转发给 JSP
	2)  chain :Action调用另一个Action (同一次请求)
	3) redirect : Action重定向到 JSP
	4) redirectAction :Action重定向到另一个Action 

 

基于注解的struts2 开发

注解开发第一步 基于约定的自动扫描 

约定只解决Action访问和结果页面跳转问题 
* 在开发中需要为Action指定拦截器,进行更细节result配置 
* 约定不够灵活,注解的功能 是和 xml配置方式 等价的 

使用 @Action注解配置访问路径  @Result注解 配置结果页面 

<constant name="struts.convention.classes.reload" value="false" /> Action类文件重新自动加载

@ParentPackage 配置<package> extends 继承哪个包
@Namespace  配置包名称空间 必须以/开头的命名空间
       例如:
       @Namespace("/employee")
	@ParentPackage("struts-default")
	public class HelloAnn extends ActionSupport {

		@Actions(value={@Action(value="myAnn1",results=@Result(name="success",location="/02ann.jsp")),
				@Action(value="helloAnn1",results=@Result(name="success",location="/02ann.jsp"))		
		})
		public String add() throws Exception {
			System.out.println("HelloAnn--------->add()执行了");
			return SUCCESS;
		}
	}