当前位置: 首页 > 知识库问答 >
问题:

struts2文件上传松动参数

韩弘方
2023-03-14

使用Struts2.3.15.1

在struts2中实现文件上传。这是我已经做了很多次的事情,但是,我试图包括一些健全的检查(即最大文件大小)。我有fileUpload拦截器作为堆栈中的最后一个拦截器(即struts.xml)。我的堆栈包括一些内部拦截器以及validationWorkflowStack。我在struts中设置了以下属性。属性文件:

struts.multipart.maxSize = 2000000

除了文件上传,我还在表单中传递一些其他参数。表格定义为:

<s:form action="addResource" method="post" enctype="multipart/form-data"> 
  <s:hidden name="rfqId" value='%{rfq.id}' />
  <s:file name="uploadFile" id="uploadFile" label="File" size="40" value=""/>
  ....
</s:form>

我相信我们都知道,validationWorkflow Stack包括params拦截器,它将请求参数设置到操作上。这里的问题是,当上传的文件超过maxsize时,没有参数可供参数拦截器设置。我已经走过了,在actionContext中什么都没有。这并不好,因为我需要这些参数来处理将导致的INPUT错误。

我错过什么了吗?

共有3个答案

宿嘉
2023-03-14

尝试在早期阶段进行javascript检查:

<!DOCTYPE html>
<html>

    <head>
    <script type="text/javascript">
    function checkSize(max_img_size)
    {
        var input = document.getElementById("upload");
        // check for browser support (may need to be modified)
        if(input.files && input.files.length == 1)
        {           
            if (input.files[0].size > max_img_size) 
            {
                alert("The file must be less than " + (max_img_size/1024/1024) + "MB");
                return false;
            }
        }

        return true;
    }
    </script>
    </head>
    <body>
    <form action="demo_post_enctype.asp" method="post" enctype="multipart/form-data" 
    onsubmit="return checkSize(2097152)">    
    <input type="file" id="upload" />
    <input type="submit" />

    </body>
    </html>
余歌者
2023-03-14

以下是我如何解决这个问题的。我不会称之为解决方案

归鹤龄
2023-03-14

根据更新的文档,现在可以使用新的JakartaStreamMultiPartRequest解决问题:

从Struts 2.3.18版本开始,添加了一个新的多部分请求实现——JakartaStreamMultiPartRequest。它可以用来处理大型文件,请参阅WW-3025了解更多详情,但您可以简单设置

<constant name="struts.multipart.parser" value="jakarta-stream" />

在struts中。xml开始使用它。

从链接的JIRA主体:

当任何大小限制超过,立即FileUploadBase.SizeLimitExceededExcema或FileUploadBase。抛出FileSizeLimitExceededExcture,并终止对多部分请求的解析,而不提供用于进一步处理的请求参数。

这基本上使得任何web应用程序都不可能优雅地处理超出大小限制的情况。

我的建议是,请求解析应该始终完成,以交付请求参数。超出大小限制的情况/异常可能会被收集以供以后检索,FileSizeLimitExeedException应映射到FileItem,以允许在应用程序级别对FileItem进行一些验证。如果上传的文件太大,这将允许将上传输入字段标记为错误。

事实上,我为此做了一个补丁(见附件)。有了这个补丁,在大小限制超过的情况下,公共文件总是完成请求解析,只有在完成解析后,如果检测到异常,才会引发异常。

克里斯·克兰福德的评论是:

我正在为Struts2开发一个新的多部分解析器,我正在调用JakartaStreamMultiPartRequest。

此多部分解析器的行为与现有的雅加达多部分解析器相同,只是它使用Commons FileUpload Streaming API,而不是将最大请求大小检查委托给File Upload API,而是在内部完成,以避免Upload API打破循环迭代和参数丢失的现有问题。

太棒了,谢谢大家:)

旧答案

我想这是由于不同的行为

  • 超过其最大定义大小的单个文件(或多个文件),然后可以在正常过程结束时使用输入结果重定向回,并且

首先解析文件时(应取决于文件在页面中的顺序),如果文件超出了多部分请求大小的限制,则不会读取其他字段(表单字段),因此不会返回输入结果。

Struts2使用Jakarta实现的MultiPartUrestWrapper:

struts。多部分。解析器-此属性应设置为扩展MultiPartRequest的类。目前,该框架附带雅加达FileUpload实现。

你可以在Struts2官方网站或这里找到源代码(更快地谷歌);这就是发布多部分表单时所说的:

 public void parse(HttpServletRequest request, String saveDir) throws IOException {
        try {
            setLocale(request);
            processUpload(request, saveDir);
        } catch (FileUploadBase.SizeLimitExceededException e) {
            if (LOG.isWarnEnabled()) {
                LOG.warn("Request exceeded size limit!", e);
            }
            String errorMessage = buildErrorMessage(e, new Object[]{e.getPermittedSize(), e.getActualSize()});
            if (!errors.contains(errorMessage)) {
                errors.add(errorMessage);
            }
        } catch (Exception e) {
            if (LOG.isWarnEnabled()) {
                LOG.warn("Unable to parse request", e);
            }
            String errorMessage = buildErrorMessage(e, new Object[]{});
            if (!errors.contains(errorMessage)) {
                errors.add(errorMessage);
            }
        }
    }

然后,这就是它循环多部分项目的地方,包括文件和表单字段:

   private void processUpload(HttpServletRequest request, String saveDir) throws FileUploadException, UnsupportedEncodingException {
        for (FileItem item : parseRequest(request, saveDir)) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Found item " + item.getFieldName());
            }
            if (item.isFormField()) {
                processNormalFormField(item, request.getCharacterEncoding());
            } else {
                processFileField(item);
            }
        }
    }

在FileUploadBase中,每个项目的实现都将结束:

 FileItemStreamImpl(String pName, String pFieldName,
                    String pContentType, boolean pFormField,
                    long pContentLength) throws IOException {
                name = pName;
                fieldName = pFieldName;
                contentType = pContentType;
                formField = pFormField;
                final ItemInputStream itemStream = multi.newInputStream();
                InputStream istream = itemStream;
                if (fileSizeMax != -1) {
                    if (pContentLength != -1
                            &&  pContentLength > fileSizeMax) {
                        FileSizeLimitExceededException e =
                            new FileSizeLimitExceededException(
                                format("The field %s exceeds its maximum permitted size of %s bytes.",
                                       fieldName, fileSizeMax),
                                pContentLength, fileSizeMax);
                        e.setFileName(pName);
                        e.setFieldName(pFieldName);
                        throw new FileUploadIOException(e);
                    }
                    istream = new LimitedInputStream(istream, fileSizeMax) {
                        @Override
                        protected void raiseError(long pSizeMax, long pCount)
                                throws IOException {
                            itemStream.close(true);
                            FileSizeLimitExceededException e =
                                new FileSizeLimitExceededException(
                                    format("The field %s exceeds its maximum permitted size of %s bytes.",
                                           fieldName, pSizeMax),
                                    pCount, pSizeMax);
                            e.setFieldName(fieldName);
                            e.setFileName(name);
                            throw new FileUploadIOException(e);
                        }
                    };
                }
                stream = istream;
            }

如您所见,它处理文件大小上限和请求大小上限的方式非常不同;

我已经看了源代码的乐趣,但你真的可以确认(或纠正)这一假设,试图调试MultiPARCestWrapper,看看里面发生的事情是否是我认为正在发生的事情...祝你好运,玩得开心。

 类似资料:
  • 主要内容:创建视图文件:,创建action类:,配置文件:,错误消息:Struts 2框架提供了内置支持处理文件上传使用基于HTML表单的文件上传。上传一个文件时,它通常会被存储在一个临时目录中,他们应该由Action类进行处理或移动到一个永久的目录,以确保数据不丢失。 请注意,服务器有一个安全策略可能会禁止写到目录以外的临时目录和属于web应用的目录。 在Struts中的文件上传是通过预先定义的拦截文件上传拦截器这是可通过org.apache.struts2.in

  • 主要内容:1. 动作类,2. 结果页面,3. struts.xml,4. 示例,参考在Struts2, <s:file> 标签用于创建一个HTML文件上传组件,允许用户从本地磁盘选择文件,并将其上传到服务器。在本教程中,您将创建与文件上传组件JSP页面,设置最大大小和允许上传文件的内容类型,并显示上传文件的详细信息。 这里创建一个Web工程:strut2uploadfile,来演示在多个复选框如何设置的默认值,整个项目的结构如下图所示: 1. 动作类 Action类的文件上传,声

  • 我是一个使用struts2文件上传和我的动作类包含3私人文件与getter和setters 我有一些疑问要澄清 > 每当我使用myFileVariableName“FileName”(如果文件变量是myFile,那么文件名变量是MyFileFileFileName,如果文件是xxx,那么文件名是xxxFileName),我就会得到输出,如果我对此格式(即myFileVariableName“Fil

  • 本文向大家介绍struts2实现多文件上传,包括了struts2实现多文件上传的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了struts2实现多文件上传的具体代码,供大家参考,具体内容如下 首先搭建好struts2的开发环境,导入struts2需要的最少jar包 新建upload.jsp页面,注意一定要把表单的enctype设置成multipart/form-data 新建一个Up

  • 本文向大家介绍Struts2+uploadify多文件上传实例,包括了Struts2+uploadify多文件上传实例的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Struts2+uploadify多文件上传的具体代码,供大家参考,具体内容如下 首先我这里使用的是  Jquery  Uploadify3.2的版本 导入相关的CSS  JS   接下来是  上传的 JSP 页面代码

  • 主要内容:1. 动作类,2. 结果页面,3. struts.xml,4. 示例,参考在上章节Struts2 文件上传示例, 用户允许选择一个文件并上传到服务器。在本教程中,您将学习如何允许用户将多个文件上传到服务器。 这里创建一个Web工程:strut2uploadfiles,来演示在多个复选框如何设置的默认值,整个项目的结构如下图所示: 1. 动作类 在Action类,可以使用列表或数组以存储上传的文件。 FileUploadAction.java 2. 结果页面 使用<s:f