使用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错误。
我错过什么了吗?
尝试在早期阶段进行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>
以下是我如何解决这个问题的。我不会称之为解决方案。
根据更新的文档,现在可以使用新的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