您的位置:首页 > 编程语言 > Java开发

轻量级JavaEE企业应用实战(九)

2015-12-18 15:43 399 查看

Struts2介绍

1.下载Struts2

2.将Struts2的lib下的 common-fileupload.jar 、commons-io.jar、freemarker.jar、javassist.ga.jar、ognl.jar、struts2-core.jar和xwork-core.jar加入到应用的WEB-INF\lib路径下(上述jar包省略版本)

3.编辑WEB应用的web.xml文件,配置Struts2的核心Filter

//定义Struts2的核心Filter
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
//让Struts2的核心Filter拦截所有请求
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


Struts2的常量配置

除了使用struts.xml管理配置之外,还可以使用struts.properties文件来管理常量,该文件定义了Struts2的大量常量,可以通过改变这些常量来满足应用的需求

常用常量配置:

struts.configuration //指定配置文件的配置管理器,默认的是org.apache.struts2.config.DefaultConfiguration
struts.locale //web应用默认的Locale,默认是en_US
struts.i18n.encoding //指定web应用的默认编码集,该常量对处理中文请求参数十分有效,对于使用中文参数,应设置为GBK祸GB2312
...


Struts2回默认加载类加载路径下的

struts.xml //开发者定义的默认配置文件

struts-default.xml //Struts 2框架自带的配置文件

struts-plugin.xml //Struts 2插件默认配置文件

所以,在这几种配置文件中都可以进行常量的配置

此外,还可以通过web应用的web.xml来加载Struts2常量

<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
<init-param>
<param-name>struts.custom.i18n.resources</param-name>
<param-value>mess</param-value>
</init-param>
</filter>


通常Struts2按如下顺序加载Struts常量:

struts-default.xml //在struts2-core-2.1.2.jar中

struts-plugin.xml //在struts2-Xxx-2.1.2.jar等Struts2插件jar中

struts.xml //web应用默认struts配置文件

struts.properties //struts2默认配置文件

web.xml //web应用配置文件

包含其他配置文件

<include file="struts-xxx.xml" /> //模块化方式管理配置文件


Action实现

为了用户开发Action更加规范,Struts2提供了一个借口Action,黎明定义了一些结果字符串以及execute,ActionSupport继承了这个借口,这就是execute方法为何是Action中默认处理用户请求的方法的原因

public interface Action {
public static final String ERROR = "error";
...
public String execute() throws Exception;
}

public class ActionSupport implements Action, Validateable,ValidationAware,TextProvider,LocaleProvider,Serializable {
...
}


Action访问Servlet API

Struts2提供了一个ActionContext类来访问,Servlet API

原因:

该类中引入了servlet中的ServletContext、PageContext、HttpServletRequest、HttpServletResponse作为方法中的参数

最终实现在ServletActionContext中

尽管可以通过ActionContext访问Servlet,毕竟不是直接获取Servlet API,所以Struts2又提供了几个接口直接访问Servlet API:

ServletContextAware //直接访问web应用的ServletContext实例

ServletRequestAware //直接访问用户请求的HttpServletRequest实例

ServletResponseAware //直接访问服务器相应的HttpServletResponse实例

注:

上述几个接口都需要用户的Action中对其方法进行重写,其参数为servletContext、request、response,相当于对servlet进行了封装

servletActionContext访问Servlet API

方法:
static PageContext getPageContext();
static HttpServletRequest getRequest();
static HttpServletResponse getResponse();
static ServletContext getServletContext();


servletActionContextActionContext的实质,实际上都是一样的,下边来看内部实现:

servletActionContext中的几个方法,以pageContext为例
public static PageContext getPageContext() {
return (PageContext)ActionContext.getContext().get(PAGE_CONTEXT);
}


接下来看ActionContext

static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>();

public static getContext() {
return actionContext.get();
}


解析:

ActionContextThreadLocal是实现ThreadLocal的一个内部类.ThreadLocal可以命名为”线程局部变量”,它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突.这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.

servletContext和ActionContext联系

两者中有着一些重复的功能,在我们的Action中,该如何去抉择呢?

我们遵循的原则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问Servlet的相关对象

注意:在使用ActionContext时有一点要注意: 不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null;同样,HttpServletRequest req = ServletActionContext.getRequest()也不要放在构造函数中,也不要直接将req作为类变量给其赋值。至于原因,我想是因为前面讲到的static ThreadLocal actionContext = new ActionContextThreadLocal(),从这里我们可以看出ActionContext是线程安全的,而ServletActionContext继承自ActionContext,所以ServletActionContext也线程安全,线程安全要求每个线程都独立进行,所以req的创建也要求独立进行,所以ServletActionContext.getRequest()这句话不要放在构造函数中,也不要直接放在类中,而应该放在每个具体的方法体中(eg:login()、queryAll()、insert()等),这样才能保证每次产生对象时独立的建立了一个req
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: