`
lyy3323
  • 浏览: 89556 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

悲剧的一个BUG!STRUTS2 上传 问题。

阅读更多
悲剧的一个BUG····STRUTS2 上传 问题。
-------------------------
搞了大半天,总是奇怪问题的现象,最后附录自己的思考过程。
---------------------------------------
现象:

由于当用户在上传文件的时候,由于文件在上传过程中流还没传送完毕结果客户端就断开了链接(可能耗时比较久,造成浏览器假死的状态,然后用户强制关闭了浏览器的进程),导致上传组件抛出异常,而且这个异常在关闭上传页面之后再打开的时候还是存在,引起上传的功能点崩溃。


----------------------分析-------------------
原因分析:

原先使用 struts2 自带的common-fileupload 组件上传文件。

当文件上传出错时(包括强行关闭浏览器导致的流关闭错误),会产生actionerror对象 。

在进入Action之前 会 经过  validate  方法,

validate  方法 检测到 actionerror  后,会直接转向input页面,导致错误信息一直出现,从而导致上传组件不可用。只能通过服务器重启来解决。
(PS:spring 配置的action是单列)





---------STRUTS2源码--------

源码大家自己去看吧。
大概流程就是


FilterDispatcher--->Dispatcher--->MultiPartRequestWrapper

然后交由Apache的commons-fileupload组件来解析了。
在MultiPartRequestWrapper的构造方法中,会调用MultiPartRequest(默认为JakartaMultiPartRequest类)的parse方法来解析请求。

--------------------------------------------------------------
解决方案如下:

1. 覆盖组件中的JakartaMultiPartRequest方法,丢弃error对象。
(据说还诡异的出现问题。)

2. 修改action类,重写validate ()方法,清除ErrorsAndMessages 。 


3. 更换组件。采用smartupload组件(但是这个组件对大文件上传存在着内存溢出的问题,只支持到100M 左右)




所以妥妥的  方案2.。。。。。。。。。。。



---------------方案一-----------------


    public void parse(HttpServletRequest servletRequest, String saveDir)
            throws IOException {
        DiskFileItemFactory fac = new DiskFileItemFactory();
        // Make sure that the data is written to file
        fac.setSizeThreshold(0);
        if (saveDir != null) {
            fac.setRepository(new File(saveDir));
        }

        // Parse the request
        try {
            ServletFileUpload upload = new ServletFileUpload(fac);
            upload.setSizeMax(maxSize);
            List items = upload.parseRequest(createRequestContext(servletRequest));

            for (Object item1 : items) {
                FileItem item = (FileItem) item1;
                if (log.isDebugEnabled()) log.debug("Found item " + item.getFieldName());
                if (item.isFormField()) {
                    log.debug("Item is a normal form field");
                    List<String> values;
                    if (params.get(item.getFieldName()) != null) {
                        values = params.get(item.getFieldName());
                    } else {
                        values = new ArrayList<String>();
                    }

                    // note: see http://jira.opensymphony.com/browse/WW-633
                    // basically, in some cases the charset may be null, so
                    // we're just going to try to "other" method (no idea if this
                    // will work)
                    String charset = servletRequest.getCharacterEncoding();
                    if (charset != null) {
                        values.add(item.getString(charset));
                    } else {
                        values.add(item.getString());
                    }
                    params.put(item.getFieldName(), values);
                } else {
                    log.debug("Item is a file upload");

                    // Skip file uploads that don't have a file name - meaning that no file was selected.
                    if (item.getName() == null || item.getName().trim().length() < 1) {
                        log.debug("No file has been uploaded for the field: " + item.getFieldName());
                        continue;
                    }

                    List<FileItem> values;
                    if (files.get(item.getFieldName()) != null) {
                        values = files.get(item.getFieldName());
                    } else {
                        values = new ArrayList<FileItem>();
                    }

                    values.add(item);
                    files.put(item.getFieldName(), values);
                }
            }
        } catch (FileUploadException e) {
            log.error(e);
            e.printStackTrace();
//注意此处的修改~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            //errors.add(e.getMessage());
        }
    }



方案1的方法:别忘记了配置struts.xml的bean ,和struts.properties.




--------------思考过程---------------
1. 为什么关闭浏览器后,问题依旧存在。。
    自然会想到单列~~~~~~~~~~~~

2. 为什么后续问题不进ACTION
   自然会想到拦截·····是什么拦截呢?(结合源码分析中的error对象,
这个对象校验使用到,那么 自然而然 变成是 校验拦截)



3.结合起来,问题就不奇怪了·········
,要发现问题现象和JAVA领域知识相结合。




分享到:
评论
39 楼 yagesi 2011-01-29  
看来你不了解STRUTS的设计思想,有点类似于EJB有状态的SESSIONBEAN,所以STRUTS1和STRUTS2的很大不同时STRUTS2的ACTION类有属性。如果是单例,那么其他用户岂不是可以读到另外用户的信息,STRUTS是线程安全的,用单例悲剧...
38 楼 dwangel 2011-01-29  
Struts2 是从webwork来的,一开始Action就是每个请求创建一个的。

楼主 主要是不仔细看文档,想当然了。
37 楼 wangking717 2011-01-29  
wangchengyong 写道
不要过度用单例,struts2的action不要用单例

不要一杆子打死一堆人,什么时候用单列,什么时候用prototype,当有状态的时候用prototype,显然上传组件的时候,每个人都各自上传自己的文件,互不影响就用prototype,如果没有状态的情况,建议singleton
36 楼 wad12302 2011-01-28  
caoxudong818 写道
lyy3323 写道
spring 里的action 配置 相信大家基本都是配的单列。


都是singleton吗?

以前没见过,孤陋寡人了。


与spring集成
struts1 是 single

struts2 是 prototype
35 楼 dwangel 2011-01-28  
http://struts.apache.org/2.x/docs/spring-plugin.html

<bean id="bar" class="com.my.BarClass" singleton="false"/>
这个是针对老的spring的,明确的说了,不是singleton……
34 楼 guofengcn 2011-01-28  
这种帖子都发?最好回去搞明白这些东西再回来发帖...
33 楼 joyfun 2011-01-28  
从你这个bug来看你这系统是bug一堆呀  明显是设计问题 估计也没几个用户
用单例会导致你系统里面一旦出现一个用户出现文件上传错误 整个系统都不能用这个action上传了
32 楼 fatesymphony 2011-01-28  
struts2整合spring,action不能为单例,不是不建议,是根本不能为单例。

在说了上传文件出错时?不应该产生actionerror吗????
31 楼 sniciq 2011-01-28  
在Spring里面配置BEAN的时候用 scope="prototype"
还有!建议你写个Servlet来处理上传!
30 楼 supben 2011-01-28  
楼主 action配置单例还这么振振有词。
如果这都不配置prototype,那 prototype在什么情况下配置? spring给这个配置不是没用了没
29 楼 javabkb 2011-01-28  
第一:action很少用单例,你里面的成员变量怎么办?
第二:smartUpload现在很少用,以前刚开始做上传时就被smartUpload上传大小问题纠结了好久
28 楼 xhdwell 2011-01-28  
lanxia39 写道
lyy3323 写道
Agrael 写道
是你自己弄的悲剧,struts2的action需要是prototype的。你配置成singleton的当然会保留之前的状态。验证的时候有那个Error的状态自然会错。

spring 里的action 配置 相信大家基本都是配的单列。

项目配置的问题。

我也不明白为什么把action配置成singleton有什么好处。

struts1.x中的action通常情况下,我们只会定义成员函数,不会定义成员变量,是一个无状态的类对象,也就是只有成员函数,没有成员变量,不会引起并发和线程访问问题,设置为单例,可以节省内存空间,提高执行效率,而struct2,action定义为一个普通的javaben,具有状态,如果定义成单例会引起并发和线程访问问题。当然你也可以按照struct1.x的方式来用struct2

正解.
27 楼 yangguo 2011-01-28  
最烦这种原理都没搞清就动不动看源码来解决问题的伪牛了。
26 楼 lyy3323 2011-01-28  
呵呵~~~~~
统计一下 大家公司项目的里action在SPRING 中的配置情况好吗?
呵呵,和struts2有什么关系?
是SPRING的错误配置造成的OK?
25 楼 hunterkevin 2011-01-28  
自己的问题,非要算在struts2上。
24 楼 adaikiss 2011-01-28  
struts2 action单例?我也孤陋寡闻了
23 楼 xrqsjj 2011-01-28  
这样的帖子蛮好的,大家讨论的这么激烈,干嘛要隐藏呢,难道大家都是神马
22 楼 jansel 2011-01-28  
一定不能是单例,Action都基本上是一个JavaBean,怎么会是单例呢?
21 楼 JE帐号 2011-01-28  
看来是从struts直接转过来的.struts2这点上有质的不同.
20 楼 kyfxbl 2011-01-28  
lyy3323 写道
Agrael 写道
是你自己弄的悲剧,struts2的action需要是prototype的。你配置成singleton的当然会保留之前的状态。验证的时候有那个Error的状态自然会错。

spring 里的action 配置 相信大家基本都是配的单列。

项目配置的问题。

我也不明白为什么把action配置成singleton有什么好处。


简直是笑话,struts2的action配成单例?还说相信大家基本都是配单例?

action里全是各种实例变量,必须是scope=prototype

相关推荐

    struts2上传必备jar包,避免出现struts2的升级漏洞!自己吃亏后分享

    这个bug是由Struts2上传文件后return SUCCESS后报的错误: java.lang.AbstractMethodError: be.telio.mediastore.ui.upload.GarryMultiPartRequest.cleanUp()V at org.apache.struts2.dispatcher.multipart....

    那位高手辨别一个,这个是不是advStringGrid控件的一个BUG!

    情况是这样的:新建一个Delphi7项目,拖入一个advStringGrid控件和一个button控件,创建窗体时,指定表格一行四列,然后,在Button的点击事件中,添加如下代码!然后,运行,点击一次Button就会随机填入一些数据!可...

    Struts2_s2-016&017&ognl2.6.11_patch漏洞补丁

    -- 为修复struts2 s2-016、s2-017漏洞,重写DefaultActionMapper --&gt; &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="myDefaultActionMapper" class=...

    Bug管理系统 struts2+sping2.5+hibernate3(2-2)

    本程序是作者学习struts spring hibernate构架后为了练习开发的一个小程序。开发此程序的目的是为了验证框架技术在项目中的应用。本程序尽量包含了开发当中遇到的一些问题及解决方案。同时欢迎广大网友到作者的群内...

    struts2官方中文帮助文档最新修复Bug版(绝版)

    Struts2是一个非常著名的Java Web框架,它基于MVC(Model-View-Controller)设计模式,为开发人员提供了构建企业级应用的强大工具。Struts2官方中文帮助文档是开发者了解和学习该框架的重要参考资料,其最新修复Bug...

    struts2-016/017漏洞解决

    Struts2是一个非常流行的Java Web开发框架,它提供了一种模型-视图-控制器(MVC)架构,便于开发者创建动态、数据驱动的Web应用程序。然而,任何软件都可能存在安全漏洞,Struts2也不例外。"struts2-016/017漏洞"指...

    XSS转码 && struts2 property标签的bug

    标题 "XSS转码 && struts2 property标签的bug" 指向的是一个关于Web安全的话题,特别是针对Struts2框架的一个特定安全问题。XSS(Cross-site scripting)是Web应用中的常见安全漏洞,而Struts2是Java开发中的流行MVC...

    Struts2 Struts2 超好的Struts2 pdf 文档

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java web应用程序框架,它在Web开发领域中被广泛使用。这个“超好的Struts2 pdf 文档”很可能包含了关于Struts2的全面介绍、核心概念、配置、拦截器、结果...

    Struts2的bug----------关于Struts2中找不到Action的

    Struts2是一个流行的Java web框架,它为构建MVC(模型-视图-控制器)架构的应用程序提供了便利。然而,正如标题所示,“Struts2的bug——关于Struts2中找不到Action的”,这个问题可能困扰了许多开发者。在Struts2...

    struts2-json-plugin-2.3.15.1 -Lee修复bug版.jar

    struts2-json-plugin-2.3.15.1 -Lee修复bug版.jarstruts2-json-plugin-2.3.15.1 -Lee修复bug版.jarstruts2-json-plugin-2.3.15.1 -Lee修复bug版.jarstruts2-json-plugin-2.3.15.1 -Lee修复bug版.jar

    struts2_S016_S017_repair

    官方描述: ... ... 官方建议修复方案:升级到最新版本 struts-2.3.15.1 但通常现有系统升级,可能导致不稳定及与其他...鉴于此csdn网友jzshmyt整理了一种既可以不用升级现有struts版本,有能完美解决这两个漏洞的方案,

    Struts2中文乱码问题最终解决方案

    但在Struts 2.1.6版本中,这个配置对POST请求的中文乱码问题无效,这是一个已知的bug。升级到2.1.8.1或更高版本可以修复这个问题,因为官方已经改进了过滤器处理字符编码的方式。 2. **POST乱码问题**: POST请求...

    Struts2SpringUnitDemo单元测试

    Struts2SpringUnitDemo是一个示例项目,展示了如何在Java应用程序中将Struts2和Spring框架进行集成,并进行单元测试。这两个框架都是Java Web开发中的关键组件,Struts2负责控制层逻辑,Spring则提供了全面的依赖...

    Struts2权威指南完整版

    相对于2007年发布的Struts 2.0,Struts 2.1改变较大,Struts 2.1不仅修正了Struts 2.0中少量Bug(这些Bug在《Struts 2.1权威指南》第一版中已经指出)。而且新增了REST、Convention和Java Templates,这些都是Struts 2...

    最新struts2 版本2.5.13

    Struts2是Apache软件基金会旗下的一个开源框架,主要用于构建企业级Java Web应用程序。这个框架基于Model-View-Controller(MVC)设计模式,提供了一种结构化的开发方式,简化了Web应用的开发流程。最新版本为2.5.13...

    Java白板程序(有Bug,真的有Bug!!!)

    )"的资源显然聚焦于一个包含错误的Java程序,可能是用于教学或实际项目中的一个白板应用。白板程序通常指的是用于画图、演示或教学目的的软件,而在这里,它显然存在一些需要修复的编程问题。 首先,我们来谈谈...

    struts2+spring集成bug——使用AOP时可能遇到的问题分析

    但有些Struts2的插件或者拦截器可能期望动作类是一个接口,这可能导致问题。确保你知道哪种代理模式正在被使用,并且它与你的代码兼容。 4. **依赖注入问题**:Spring的依赖注入可能会在Struts2的生命周期中出现...

    bug tracker system!!!!

    bug tracker system!!!!bug tracker system!!!!bug tracker system!!!!bug tracker system!!!!bug tracker system!!!!bug tracker system!!!!

    struts2辅助jar包

    Struts2是一个流行的Java web应用程序框架,用于构建和维护可扩展、高效且易于维护的Web应用。在开发基于Struts2的应用时,除了主要的Struts2核心库外,还需要依赖一些辅助的JAR包来确保项目的正常运行。标题提到的...

    struts2 框架的核心jar包(struts-2.3.16版本)

    具体到struts-2.3.16版本,这是Struts2的一个稳定版本,包含了多个组件和修复的bug,旨在提供更高效、更安全的开发环境。 核心jar包是Struts2框架的基础,主要包括以下几个关键组件: 1. **struts2-core.jar**:这...

Global site tag (gtag.js) - Google Analytics