快速解决commons-fileupload组件无法处理自定义head信息的bug
更新时间:2013年08月30日 09:23:21 作者:
问题在于fileupload组件解析完自定义的head节点后,却忘记传递到FileItemStreamImpl中了,稍作修订,即可修正该bug
Jakarta commons fileupload组件可以处理HTTP请求及响应,很多时候被用来处理文件上传,但是近期发现,当我们自定义文件上传、自己组装mime信息、文件上传时加入自定义head节点时,fileupload组件无法获得自定义的head节点,仔细分析了fileupload组件源代码后,发现核心方法在FileUploadBase文件的findNextItem方法中,问题在于fileupload组件解析完自定义的head节点后,却忘记传递到FileItemStreamImpl中了,稍作修订,即可修正该bug。
/**解析文件列表
* Called for finding the nex item, if any.
* @return True, if an next item was found, otherwise false.
* @throws IOException An I/O error occurred.
*/
private boolean findNextItem() throws IOException {
if (eof) {
return false;
}
if (currentItem != null) {
currentItem.close();
currentItem = null;
}
for (;;) {
boolean nextPart;
if (skipPreamble) {
nextPart = multi.skipPreamble();
} else {
nextPart = multi.readBoundary();
}
if (!nextPart) {
if (currentFieldName == null) {
// Outer multipart terminated -> No more data
eof = true;
return false;
}
// Inner multipart terminated -> Return to parsing the outer
multi.setBoundary(boundary);
currentFieldName = null;
continue;
}
FileItemHeaders headers = getParsedHeaders(multi.readHeaders());
if (currentFieldName == null) {
// We're parsing the outer multipart
String fieldName = getFieldName(headers);
if (fieldName != null) {
String subContentType = headers.getHeader(CONTENT_TYPE);
if (subContentType != null
&& subContentType.toLowerCase()
.startsWith(MULTIPART_MIXED)) {
currentFieldName = fieldName;
// Multiple files associated with this field name
byte[] subBoundary = getBoundary(subContentType);
multi.setBoundary(subBoundary);
skipPreamble = true;
continue;
}
String fileName = getFileName(headers);
currentItem = new FileItemStreamImpl(fileName,
fieldName, headers.getHeader(CONTENT_TYPE),
fileName == null, getContentLength(headers));
notifier.noteItem();
itemValid = true;
return true;
}
} else {
String fileName = getFileName(headers);
if (fileName != null) {
//这里代码要修订
//这是原来的代码,没有传入header
//currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers));
//这是新的代码,我们要传入header
currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers),headers);
notifier.noteItem();
itemValid = true;
return true;
}
}
multi.discardBodyData();
}
}
/**原始代码,存在丢失FileItemHeaders信息的bug
* Creates a new instance.
* @param pName The items file name, or null.
* @param pFieldName The items field name.
* @param pContentType The items content type, or null.
* @param pFormField Whether the item is a form field.
* @param pContentLength The items content length, if known, or -1
* @throws IOException Creating the file item failed.
*/
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) {
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + fileSizeMax
+ " characters.",
pContentLength, fileSizeMax);
throw new FileUploadIOException(e);
}
istream = new LimitedInputStream(istream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
throws IOException {
itemStream.close(true);
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + pSizeMax
+ " characters.",
pCount, pSizeMax);
throw new FileUploadIOException(e);
}
};
}
stream = istream;
}
/**创建FileItem,修订后的代码,解决丢失FileItemHeaders信息的bug
* @param pName
* @param pFieldName
* @param pContentType
* @param pFormField
* @param pContentLength
* @param headers
* @throws IOException
*/
FileItemStreamImpl(String pName, String pFieldName,
String pContentType, boolean pFormField,
long pContentLength,FileItemHeaders headers) throws IOException {
name = pName;
fieldName = pFieldName;
contentType = pContentType;
formField = pFormField;
if(headers!=null){
this.headers = headers;
}
final ItemInputStream itemStream = multi.newInputStream();
InputStream istream = itemStream;
if (fileSizeMax != -1) {
if (pContentLength != -1
&& pContentLength > fileSizeMax) {
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + fileSizeMax
+ " characters.",
pContentLength, fileSizeMax);
throw new FileUploadIOException(e);
}
istream = new LimitedInputStream(istream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
throws IOException {
itemStream.close(true);
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + pSizeMax
+ " characters.",
pCount, pSizeMax);
throw new FileUploadIOException(e);
}
};
}
stream = istream;
}
复制代码 代码如下:
/**解析文件列表
* Called for finding the nex item, if any.
* @return True, if an next item was found, otherwise false.
* @throws IOException An I/O error occurred.
*/
private boolean findNextItem() throws IOException {
if (eof) {
return false;
}
if (currentItem != null) {
currentItem.close();
currentItem = null;
}
for (;;) {
boolean nextPart;
if (skipPreamble) {
nextPart = multi.skipPreamble();
} else {
nextPart = multi.readBoundary();
}
if (!nextPart) {
if (currentFieldName == null) {
// Outer multipart terminated -> No more data
eof = true;
return false;
}
// Inner multipart terminated -> Return to parsing the outer
multi.setBoundary(boundary);
currentFieldName = null;
continue;
}
FileItemHeaders headers = getParsedHeaders(multi.readHeaders());
if (currentFieldName == null) {
// We're parsing the outer multipart
String fieldName = getFieldName(headers);
if (fieldName != null) {
String subContentType = headers.getHeader(CONTENT_TYPE);
if (subContentType != null
&& subContentType.toLowerCase()
.startsWith(MULTIPART_MIXED)) {
currentFieldName = fieldName;
// Multiple files associated with this field name
byte[] subBoundary = getBoundary(subContentType);
multi.setBoundary(subBoundary);
skipPreamble = true;
continue;
}
String fileName = getFileName(headers);
currentItem = new FileItemStreamImpl(fileName,
fieldName, headers.getHeader(CONTENT_TYPE),
fileName == null, getContentLength(headers));
notifier.noteItem();
itemValid = true;
return true;
}
} else {
String fileName = getFileName(headers);
if (fileName != null) {
//这里代码要修订
//这是原来的代码,没有传入header
//currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers));
//这是新的代码,我们要传入header
currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers),headers);
notifier.noteItem();
itemValid = true;
return true;
}
}
multi.discardBodyData();
}
}
/**原始代码,存在丢失FileItemHeaders信息的bug
* Creates a new instance.
* @param pName The items file name, or null.
* @param pFieldName The items field name.
* @param pContentType The items content type, or null.
* @param pFormField Whether the item is a form field.
* @param pContentLength The items content length, if known, or -1
* @throws IOException Creating the file item failed.
*/
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) {
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + fileSizeMax
+ " characters.",
pContentLength, fileSizeMax);
throw new FileUploadIOException(e);
}
istream = new LimitedInputStream(istream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
throws IOException {
itemStream.close(true);
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + pSizeMax
+ " characters.",
pCount, pSizeMax);
throw new FileUploadIOException(e);
}
};
}
stream = istream;
}
/**创建FileItem,修订后的代码,解决丢失FileItemHeaders信息的bug
* @param pName
* @param pFieldName
* @param pContentType
* @param pFormField
* @param pContentLength
* @param headers
* @throws IOException
*/
FileItemStreamImpl(String pName, String pFieldName,
String pContentType, boolean pFormField,
long pContentLength,FileItemHeaders headers) throws IOException {
name = pName;
fieldName = pFieldName;
contentType = pContentType;
formField = pFormField;
if(headers!=null){
this.headers = headers;
}
final ItemInputStream itemStream = multi.newInputStream();
InputStream istream = itemStream;
if (fileSizeMax != -1) {
if (pContentLength != -1
&& pContentLength > fileSizeMax) {
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + fileSizeMax
+ " characters.",
pContentLength, fileSizeMax);
throw new FileUploadIOException(e);
}
istream = new LimitedInputStream(istream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
throws IOException {
itemStream.close(true);
FileUploadException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + pSizeMax
+ " characters.",
pCount, pSizeMax);
throw new FileUploadIOException(e);
}
};
}
stream = istream;
}
您可能感兴趣的文章:
- java组件commons-fileupload实现文件上传、下载、在线打开
- Java组件commons fileupload实现文件上传功能
- JavaEE组件commons-fileupload实现文件上传、下载
- JSP组件commons-fileupload实现文件上传
- java组件commons-fileupload文件上传示例
- Apache Commons fileUpload文件上传多个示例分享
- java组件commons-fileupload实现文件上传
- commons fileupload实现文件上传的实例代码
- Apache Commons fileUpload实现文件上传之一
- Apache commons fileupload文件上传实例讲解
相关文章
Java 深入浅出分析Synchronized原理与Callable接口
Synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行,Runnable是执行工作的独立任务,但是不返回任何值。如果我们希望任务完成之后有返回值,可以实现Callable接口2022-03-03
Springboot+redis+Interceptor+自定义annotation实现接口自动幂等
本篇文章给大家介绍了使用springboot和拦截器、redis来优雅的实现接口幂等,对于幂等在实际的开发过程中是十分重要的,因为一个接口可能会被无数的客户端调用,如何保证其不影响后台的业务处理,如何保证其只影响数据一次是非常重要的,感兴趣的朋友跟随小编一起看看吧2019-07-07
IDEA2022版本创建maven web项目的两种方式详解
创建maven web项目有两种方式,一种是使用骨架方式,一种是不使用骨架的方式,本文结合实例代码给大家介绍了IDEA2022版本创建maven web项目的两种方式,需要的朋友可以参考下2023-02-02


最新评论