Servlet的生命周期是“初始化->init->service->destroy->卸载”。

这里大家都知道,我们在web.xml里面定义一个servlet的时候,我们能够给他们设置一个“load-on-startup” 的值。假设 Servlet 的 load-on-startup 配置项大于 0,那么在 Context 容器启动的时候就会被实例化。而且tomcat给每个servlet载入而且实例化一个对象(注解:也就是说。我们用户在web.xml里面配置的每个servlet都会被实例成一个servlet对象)

a, 以下的配置表示会有两个servlet对象被实例化。即使他们相应的是同一个servlet class

 1 <?

xml version="1.0" encoding="UTF-8"?>
2 <web-app version="2.5"
3 xmlns="http://java.sun.com/xml/ns/javaee"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
7 <servlet>
8 <servlet-name>ServletTest1</servlet-name>
9 <servlet-class>web.servlet.ServletTest1</servlet-class>
10 </servlet>
11
12 <servlet-mapping>
13 <servlet-name>ServletTest1</servlet-name>
14 <url-pattern>/servlet/ServletTest1</url-pattern>
15 </servlet-mapping>
16
17 <servlet>
18 <servlet-name>ServletTest2</servlet-name>
19 <servlet-class>web.servlet.ServletTest1</servlet-class>
20 </servlet>
21
22 <servlet-mapping>
23 <servlet-name>ServletTest2</servlet-name>
24 <url-pattern>/servlet/ServletTest1</url-pattern>
25 </servlet-mapping>
26 </web-app>

b, 以下的配置表示仅仅会有一个servlet被实例化

 1 <?

xml version="1.0" encoding="UTF-8"?>
2 <web-app version="2.5"
3 xmlns="http://java.sun.com/xml/ns/javaee"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
7 <servlet>
8 <servlet-name>ServletTest1</servlet-name>
9 <servlet-class>web.servlet.ServletTest1</servlet-class>
10 </servlet>
11
12 <servlet-mapping>
13 <servlet-name>ServletTest1</servlet-name>
14 <url-pattern>/servlet/ServletTest1</url-pattern>
15 </servlet-mapping>
16
17 <servlet-mapping>
18 <servlet-name>ServletTest1</servlet-name>
19 <url-pattern>/servlet/ServletTest1</url-pattern>
20 </servlet-mapping>
21 </web-app>

Tomcat容器对Servlet的实现採用的是单例模式,对于一个Servlet类,永远仅仅有一个servlet对象存在

1. Struts1

Struts1是对Java web servlet接口的直接实现,即继承了tomcat对Servlet的实现。每个struts1里面的action都相应一个的是一个servlet class。所以这里的action在被Tomcat实例化之后也是单例的。这就是struts1产生多线程问题的解决办法

2. Struts2

上面我们了解了Struts1里面的多线程问题,那Struts2是怎么解决问题的呢?事实上道理很easy,原因就是Strtus2会获取到用户的http请求。然后负责给每一个请求实例化一个Action 对象,可是大家注意。这里的action对象和Struts1里面的action对象全然不是一个概念。struts1里面的action类就是一个servlet类。而这里的action类仅仅是一个普通的java
class。这也就是为什么Struts1里面的action是线程不安全的,而struts2里面的action是线程安全的原因。

那我们在回头来看看struts2对servlet的处理和struts1有什么不同。看过前面分析的读者肯定知道,struts1的 action对servlet没有进行不论什么的包装,它是直接实现的Java WEB API 里面的servlet 接口。

所以才会有线程安全的问题,可是struts2底层帮我们封装了Servlet,使开发者不用直接接触Servlet。

详细做法是:Strtus2截获servlet请求,然后给每一个请求实例化一个Action对象,请求结束之后销毁Action对象。

------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------

在Struts1中的Action安全问题具体解释:

假设你的代码所在的进程中有多个线程在同一时候执行,而这些线程可能会同一时候执行这段代码。假设每次执行结果和单线程执行的结果是一样的,并且其它的变量的值也和预期的是一样的,就是线程安全的。

  或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的运行结果存在二义性,也就是说我们不用考虑同步的问题。

  线程安全问题都是由全局变量及静态变量引起的。

若每一个线程中对全局变量、静态变量仅仅有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同一时候运行写操作,一般都须要考虑线程同步。否则就可能影响线程安全。

 Action类

Action类真正实现应用程序的事务逻辑。它们负责处理请求。

在收到请求后。ActionServlet会:为这个请求选择适当的Action,假设须要,创建Action的一个实例,调用Action的perform()方法,假设ActionServlet不能找到有效的映射,它会调用默认的Action类(在配置文件里定义)。

假设找到了ActionServlet将适当的ActionMapping类转发给Action,这个Action使用ActionMapping找到本地转发。然后获得并设置ActionMapping属性。

依据servlet的环境和被覆盖的perform()方法的签名,ActionServlet也会传送ServletRequest对象或HttpServletRequest对象。

  全部Action类都扩展org.apache.struts.action.Action类。而且覆盖类中定义的某一个perform()方法。有两个perform()方法:

  处理非HTTP(一般的)请求:

<span style="font-family:Microsoft YaHei;font-size:14px;">public ActionForward perform(ActionMapping action,
AcionForm form,
ServletRequest request,
ServletResponse response)
throws IOException,ServletException
</span>

  处理HTTP请求:

<span style="font-family:Microsoft YaHei;font-size:14px;">public ActionForward perform(ActionMapping action,
AcionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException,ServletException </span>

Action类必须以“线程安全”的方式进行编程,由于控制器会令多个同一时候发生的请求共享同一个实例,对应的,在设计Action类时就须要注意下面几点:

不能使用实例或静态变量存储特定请求的状态信息,它们会在同一个操作中共享跨越请求的全局资源,假设要訪问的资源(如JavaBean和会话变量)在并行訪问时须要进行保护,那么訪问就要进行同步,Action类的方法

  除了perform()方法外,还有下面方法:

  能够获得或设置与请求相关联的区域:

<span style="font-family:Microsoft YaHei;font-size:14px;">public Locale getLocale(HttpServletRequest request)

public void setLocale(HttpServletRequest request,Localelocale) </span>

  为应用程序获得消息资源:public MessageResources getResources()

  检查用户是否点击表单上的“取消”键,假设是,将返回true:public
Boolean isCancelled(HttpServletRequest request)

  当应用程序错误发生时,Action类可以使用以下方法存储错误信息:

public void saveErrors(HttpServletRequestrequest,ActionErrors errors)

ActionError实例被用来存储错误信息。这种方法在错误keyword下的请求属性列表中存储ActionError对象。通过使用在struts标记库中定义的自己定义标记,JSP页可以显示这些错误信息,稍后我们就介绍。

 ActionForm类

  框架如果用户在应用程序中为每一个表单都创建了一个ActionForm bean。对于每一个在struts-config.xml文件里定义的bean。框架在调用Action类的perform()方法之前会进行下面操作:

(1)在相关联的keyword下,它检查用于适当类的bean实例的用户会话,假设在会话中没有可用的bean,它就会自己主动创建一个新的bean并加入到用户的会话中。

(2)对于请求中每一个与bean属性名称相应的參数,Action调用相应的设置方法。

(3)当Action
perform()被调用时,最新的ActionForml
bean传送给它,參数值就能够马上使用了。

(4)ActionForm类扩展org.apache.struts.action.ActionForm类。程序开发者创建的bean可以包括额外的属性。并且ActionServlet可能使用反射(同意从已载入的对象中回收信息)訪问它。

ActionForm类提供了还有一种处理错误的手段。提供两个方法:

<span style="font-family:Microsoft YaHei;font-size:14px;">Public ActionErrors validate(ActionMappin mapping,
ServletRequest request)
Public ActionErrors validate(ActionMappin mapping,
HttpServletRequest request) </span>

  你应该在自己的bean里覆盖validate()方法。并在配置文件中设置<action>元素的validate为true。在ActionServlet调用Action类前,它会调用validate(),假设返回的ActionErrors不是null,则ActinForm会依据错误keyword将ActionErrors存储在请求属性列表中。

  假设返回的不是null。并且长度大于0,则依据错误keyword将实例存储在请求的属性列表中,然后ActionServlet将响应转发到配置文件<action>元素的input属性所指向的目标。

  假设须要运行特定的数据有效性检查。最好在Action类中进行这个操作,而不是在ActionForm类中进行。

  方法reset()可将bean的属性恢复到默认值:

<span style="font-family:Microsoft YaHei;font-size:14px;">public void reset(ActionMapping mapping,HttpServletRequestrequest)

public void reset(ActionMapping mapping,ServletRequestrequest) </span>

  典型的ActionFrom bean仅仅有属性的设置与读取方法(getXXX),而没有实现事务逻辑的方法。

仅仅有简单的输入检查逻辑,使用的目的是为了存储用户在相关表单中输入的最新数据。以便能够将同一网页进行再生,同一时候提供一组错误信息,这样就能够让用户改动不对的输入数据。而真正对数据有效性进行检查的是Action类或适当的事务逻辑bean。

3.6 ActionForward类

  目的是控制器将Action类的处理结果转发至目的地。

Action类获得ActionForward实例的句柄,然后可用三种方法返回到ActionServlet,所以我们能够这样使用findForward():

ActionServlet依据名称获取一个全局转发,ActionMappin实例被传送到perform()方法,并依据名称找到一个本地转发,还有一种是调用以下的一个构造器来创建它们自己的一个实例:

<span style="font-family:Microsoft YaHei;font-size:14px;">public ActionForward()

public ActionForward(String path)

public ActionForward(String path,Boolean redirect)</span>

----------------------------------------------------------------------------------------------------------------

在struts应用的生命周期中RequestProcessor仅仅能保证一个Action实例,全部的其它请求都共享这个实例,因此Aciton是多线程进行工作,可是有一个保证正常和安全工作的前提是,Action不能有这种实例变量。拥有状态的实例,尤其是拥有业务对象状态的实例. 假设要用到那些有状态的实例,唯一和最好的办法是在Action类中,仅在Action类的execute()方法中使用局部变量,对于每一个调用
execute()方法的线程,JVM会在每一个线程的堆栈中创建局部变量,因此每一个线程拥有独立的局部变量,不会被其它线程共享.当线程运行完 execute()方法后。它的局部变量就会被销毁.

如今项目中的做法:Action调用一个业务用例服务,这个服务本身没有变量,这个服务来保证实现一个模型层的业务逻辑.假设Action类的实例变量是必须设定的话,须要採用JAVA同步机制对訪问共享资源的代码块进行同步.

----------------------------------------------------------------------------------------------------------------------

struts的action是非线程安全的。不要在action中定义实例变量。

在spring的配置文件里,能够配置action为线程安全。即每次调用都生成一个新的实例,而不是仅仅用一个实例。

bean中设置singleton="true"

由于控制器会令多个同一时候发生的请求共享同一个实例,所以最好不要在Action中使用实例或静态变量存储特定请求的状态信息。假设要訪问相关的资源。最好进行同步操作。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

struts1和struts2安全线的更多相关文章

  1. jsp\struts1.2\struts2 中文件上传(转)

    jsp\struts1.2\struts2 中文件上传 a.在jsp中简单利用Commons-fileupload组件实现 b.在struts1.2中实现c.在sturts2中实现现在把Code与大家 ...

  2. Struts1与Struts2的12点区别

    Struts1与Struts2的12点区别  1) 在Action实现类方面的对比:Struts 1要求Action类继承一个抽象基类:Struts 1的一个具体问题是使用抽象类编程而不是接口.Str ...

  3. 浅析Struts1和Struts2的Action线程安全问题 转

    浅析Struts1和Struts2的Action线程安全问题  转 http://blog.csdn.net/virgoboy2004/article/details/5876133 [问题描述]最近 ...

  4. Struts1和Struts2的区别和对比(完整版)

    Struts2其实并不是一个陌生的Web框架,Struts2是以Webwork的设计思想为核心,吸收了Struts1的优点,因此,可以认为Struts2是Struts1和Webwork结合的产物. 简 ...

  5. Struts1、Struts2和SpringMVC剖析【转载】

    前段框架用了不少,今天就来做个总结.网上关于Struts1.Struts2.SpringMVC的文章有很多,这里的内容就是基于它们,来做个比较. 这三个框架是按照上面的顺序,依次出现的,它们都是对MV ...

  6. Struts2五、Struts1与Struts2的区别

    Struts1和Struts2的区别和对比: Action 类:  • Struts1要求Action类继承一个抽象基类.Struts1的一个普遍问题是使用抽象类编程而不是接口,而struts2的Ac ...

  7. Struts1和Struts2对照

    最近学习Struts1和Struts2.好多人.提到非常多的信息. Struts2不从Struts1进化. Struts2的前身WebWork. 呢,看了一些资料,下边就来比較比較. 一.架构分析 S ...

  8. Struts1和Struts2的区别和对比

    Struts1和Struts2的区别和对比: Action 类: • Struts1要求Action类继承一个抽象基类.Struts1的一个普遍问题是使用抽象类编程而不是接口. • Struts 2  ...

  9. struts1和struts2和springMVC的区别和介绍

    MVC是web开发常用的模式,M即模型层(Model):主要由javabean来实现.V即视图层(View):主要由jsp.velocity.freemarker等.C即控制层(Controller) ...

随机推荐

  1. java I/O库的设计模式

    在java语言 I/O库的设计中,使用了两个结构模式,即装饰模式和适配器模式.      在任何一种计算机语言中,输入/输出都是一个很重要的部分.与一般的计算机语言相比,java将输入/输出的功能和使 ...

  2. POJ 1775 Sum of Factorials (ZOJ 2358)

    http://poj.org/problem?id=1775 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1334 题目大意: ...

  3. 【24.67%】【codeforces 551C】 GukiZ hates Boxes

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. [D3] Create Labels from Numeric Data with Quantize Scales in D3 v4

    Sometimes data needs to be converted from a continuous range, like test scores, to a discrete set of ...

  5. php javascript的ajax

    先说基础一点的get类型的ajax function loadXMLDoc() { var xmlhttp;//首先判断浏览器是否支持xmlhttprequest,因为ie56不是这个对象,是acti ...

  6. Android 输入框弹出样式

    在androidMainfest.xml文件里 在Activity中设置 [A]stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置 [B]stateU ...

  7. html5-6 Frame框架窗口类型

    html5-6  Frame框架窗口类型 一.总结 一句话总结: 1.点左侧的a链接如何打开右侧页面? <a href='user/index.html' target='right'>& ...

  8. 基于 Android NDK 的学习之旅-----资源释放

    做上一个项目的时候因为与C引擎交互频繁,有时候会突然莫名其妙的的整个应用程序直接挂掉.因为我是学Java 开始的,所以对主动释放内存没多大概念(GC直接帮忙回收),后查询原因才知道是因为JNI 有些对 ...

  9. 于 Android NDK 的学习之旅-----数据传输(基本数据类型和数组传输)

    之前的一些文章都有涉及到上层和中间层的数据传输,简单来说,也就是参数和返回值的使用.因为中间层要做的最多的也就是数据传输与转换,下面来介绍下这方面的知识. 数据传输可分为 基本数据类型传输 和 引用数 ...

  10. winfrom RichTextBox每行字体的颜色

    public static void AppendTextColorful(this RichTextBox rtBox, string text, Color color, bool addNewL ...