Jakarta commons fileupload 구성 요소는 HTTP 요청 및 응답을 처리할 수 있습니다. 파일 업로드를 처리하는 데 자주 사용되지만 최근에는 파일 업로드를 사용자 정의하고, MIME 정보를 직접 조립하고, 파일 업로드 시 사용자 정의 헤드 노드를 추가하는 경우 fileupload 구성 요소가 발견되었습니다. fileupload 구성 요소의 소스 코드를 주의 깊게 분석한 결과 핵심 메서드가 FileUploadBase 파일의 findNextItem 메서드에 있음을 발견했습니다. 문제는 fileupload 구성 요소가 사용자 정의된 헤드 노드를 구문 분석한 후 이를 전달하는 것을 잊어버렸다는 것입니다. FileItemStreamImpl을 약간 수정하면 버그가 수정될 수 있습니다.
다음과 같이 코드 코드를 복사합니다 .
/**파싱 파일 목록
* nex 항목이 있는 경우 해당 항목을 찾기 위해 호출됩니다.
* @return 다음 항목이 발견되면 True이고, 그렇지 않으면 False입니다.
* @throws IOException I/O 오류가 발생했습니다.
*/
개인 부울 findNextItem()이 IOException을 발생시킵니다.
만약 (eof) {
거짓을 반환;
}
if (현재항목 != null) {
currentItem.close();
현재항목 = null;
}
을 위한 (;;) {
부울 nextPart;
if (skipPreamble) {
nextPart = multi.skipPreamble();
} 또 다른 {
nextPart = multi.readBoundary();
}
if (!nextPart) {
if (currentFieldName == null) {
// 외부 멀티파트 종료 -> 더 이상 데이터 없음
eof = 사실;
거짓을 반환;
}
// 내부 멀티파트 종료 -> 외부 멀티파트 구문 분석으로 돌아갑니다.
multi.setBoundary(경계);
현재필드이름 = null;
계속하다;
}
FileItemHeaders 헤더 = getParsedHeaders(multi.readHeaders());
if (currentFieldName == null) {
// 외부 멀티파트를 구문 분석하고 있습니다.
String fieldName = getFieldName(헤더);
if (필드 이름 != null) {
String subContentType = headers.getHeader(CONTENT_TYPE);
if (subContentType != null
&& subContentType.toLowerCase()
.startsWith(MULTIPART_MIXED)) {
currentFieldName = 필드이름;
// 이 필드 이름과 연결된 여러 파일
byte[] subBoundary = getBoundary(subContentType);
multi.setBoundary(subBoundary);
SkipPreamble = true;
계속하다;
}
String fileName = getFileName(헤더);
currentItem = 새 FileItemStreamImpl(파일 이름,
fieldName, headers.getHeader(CONTENT_TYPE),
fileName == null, getContentLength(headers));
notifier.noteItem();
itemValid = true;
사실을 반환;
}
} 또 다른 {
String fileName = getFileName(헤더);
if (파일 이름 != null) {
//여기 코드를 수정해야 합니다.
//이것은 원본 코드이며 헤더가 전달되지 않았습니다.
//currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers));
//이것은 새로운 코드입니다. 헤더를 전달해야 합니다.
currentItem = new FileItemStreamImpl(fileName, currentFieldName,headers.getHeader(CONTENT_TYPE),false, getContentLength(headers),headers);
notifier.noteItem();
itemValid = true;
사실을 반환;
}
}
multi.discardBodyData();
}
}
/**원본 코드, FileItemHeaders 정보가 손실되는 버그가 있습니다.
* 새 인스턴스를 생성합니다.
* @param pName 항목 파일 이름 또는 null입니다.
* @param pFieldName 항목 필드 이름입니다.
* @param pContentType 항목 콘텐츠 유형 또는 null입니다.
* @param pFormField 항목이 양식 필드인지 여부입니다.
* @param pContentLength 항목 콘텐츠 길이(알려진 경우) 또는 -1
* @throws IOException 파일 항목 생성에 실패했습니다.
*/
FileItemStreamImpl(문자열 pName, 문자열 pFieldName,
문자열 pContentType, 부울 pFormField,
긴 pContentLength)는 IOException을 발생시킵니다.
이름 = p이름;
필드명 = pFieldName;
콘텐츠 유형 = pContentType;
formField = pFormField;
final ItemInputStream itemStream = multi.newInputStream();
InputStream istream = itemStream;
if (fileSizeMax != -1) {
if (pContentLength != -1
&& pContentLength > fileSizeMax) {
FileUploadException e =
새로운 FileSizeLimitExceededException(
"필드" + 필드 이름
+ " 허용된 최대값을 초과했습니다 "
+ " 크기 " + fileSizeMax
+ " 문자.",
pContentLength, fileSizeMax);
새로운 FileUploadIOException(e)을 던져라;
}
istream = 새로운 LimitedInputStream(istream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
IOException이 발생합니다. {
itemStream.close(true);
FileUploadException e =
새로운 FileSizeLimitExceededException(
"필드" + 필드 이름
+ " 허용된 최대값을 초과했습니다 "
+ " 크기 " + pSizeMax
+ " 문자.",
p카운트, pSizeMax);
새로운 FileUploadIOException(e)을 던져라;
}
};
}
스트림 = istream;
}
/** FileItem 생성, 코드 수정, FileItemHeaders 정보 손실 버그 해결
* @param pName
* @param pFieldName
* @param pContentType
* @param pFormField
* @param pContentLength
* @param 헤더
* @throwsIOException
*/
FileItemStreamImpl(문자열 pName, 문자열 pFieldName,
문자열 pContentType, 부울 pFormField,
긴 pContentLength,FileItemHeaders 헤더)는 IOException {을 발생시킵니다.
이름 = p이름;
필드명 = pFieldName;
콘텐츠 유형 = pContentType;
formField = pFormField;
if(헤더!=null){
this.headers = 헤더;
}
final ItemInputStream itemStream = multi.newInputStream();
InputStream istream = itemStream;
if (fileSizeMax != -1) {
if (pContentLength != -1
&& pContentLength > fileSizeMax) {
FileUploadException e =
새로운 FileSizeLimitExceededException(
"필드" + 필드 이름
+ " 허용된 최대값을 초과했습니다 "
+ " 크기 " + fileSizeMax
+ " 문자.",
pContentLength, fileSizeMax);
새로운 FileUploadIOException(e)을 던져라;
}
istream = 새로운 LimitedInputStream(istream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
IOException이 발생합니다.
itemStream.close(true);
FileUploadException e =
새로운 FileSizeLimitExceededException(
"필드" + 필드 이름
+ " 허용된 최대값을 초과했습니다 "
+ " 크기 " + pSizeMax
+ " 문자.",
p카운트, pSizeMax);
새로운 FileUploadIOException(e)을 던져라;
}
};
}
스트림 = istream;
}