/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.citrus.service.upload.impl;
import java.io.File;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.citrus.service.AbstractService;
import com.alibaba.citrus.service.upload.UploadException;
import com.alibaba.citrus.service.upload.UploadParameters;
import com.alibaba.citrus.service.upload.UploadService;
import com.alibaba.citrus.service.upload.UploadSizeLimitExceededException;
import com.alibaba.citrus.service.upload.impl.cfu.DiskFileItemFactory;
import com.alibaba.citrus.service.upload.impl.cfu.ServletFileUpload;
import com.alibaba.citrus.util.HumanReadableSize;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
/**
* 这个service可以处理<code>multipart/form-data</code>格式的HTTP
* POST请求,并将它们转换成form字段或是文件。
*
* @author Michael Zhou
*/
public class UploadServiceImpl extends AbstractService<UploadService> implements UploadService {
private final UploadParameters params = new UploadParameters();
private ServletFileUpload fileUpload;
public File getRepository() {
return params.getRepository();
}
public HumanReadableSize getSizeMax() {
return params.getSizeMax();
}
public HumanReadableSize getFileSizeMax() {
return params.getFileSizeMax();
}
public HumanReadableSize getSizeThreshold() {
return params.getSizeThreshold();
}
public boolean isKeepFormFieldInMemory() {
return params.isKeepFormFieldInMemory();
}
public void setSizeMax(HumanReadableSize sizeMax) {
params.setSizeMax(sizeMax);
}
public void setFileSizeMax(HumanReadableSize fileSizeMax) {
params.setFileSizeMax(fileSizeMax);
}
public void setSizeThreshold(HumanReadableSize sizeThreshold) {
params.setSizeThreshold(sizeThreshold);
}
public void setKeepFormFieldInMemory(boolean keepFormFieldInMemory) {
params.setKeepFormFieldInMemory(keepFormFieldInMemory);
}
public void setRepository(File repository) {
params.setRepository(repository);
}
public String[] getFileNameKey() {
return params.getFileNameKey();
}
public void setFileNameKey(String[] fileNameKey) {
params.setFileNameKey(fileNameKey);
}
@Override
protected void init() {
params.applyDefaultValues();
getLogger().info("Upload Parameters: {}", params);
fileUpload = getFileUpload(params, false);
}
/**
* 判断是否是符合<a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>标准的
* <code>multipart/form-data</code>类型的HTTP请求。
*
* @param request HTTP请求
* @return 如果是,则返回<code>true</code>
*/
public boolean isMultipartContent(HttpServletRequest request) {
return org.apache.commons.fileupload.servlet.ServletFileUpload.isMultipartContent(request);
}
/**
* 解析符合<a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>标准的
* <code>multipart/form-data</code>类型的HTTP请求。
*
* @param request HTTP请求
* @return <code>FileItem</code>的列表,按其输入的顺序罗列
* @throws UploadException 如果解析时出错
*/
public FileItem[] parseRequest(HttpServletRequest request) {
return parseRequest(request, null);
}
/**
* 解析符合<a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>标准的
* <code>multipart/form-data</code>类型的HTTP请求。
* <p>
* 此方法覆盖了service的默认设置,适合于在action或servlet中手工执行。
* </p>
*
* @param request HTTP请求
* @param sizeThreshold 文件放在内存中的阈值,小于此值的文件被保存在内存中。如果此值小于0,则使用预设的值
* @param sizeMax HTTP请求的最大尺寸,超过此尺寸的请求将被抛弃。
* @param repositoryPath 暂存上载文件的绝对路径
* @param charset 用来解析HTTP header的编码字符集
* @return <code>FileItem</code>的列表,按其输入的顺序罗列
* @throws UploadException 如果解析时出错
*/
public FileItem[] parseRequest(HttpServletRequest request, UploadParameters params) {
assertInitialized();
ServletFileUpload fileUpload;
if (params == null || params.equals(this.params)) {
fileUpload = this.fileUpload;
} else {
fileUpload = getFileUpload(params, true);
}
List<?> fileItems;
try {
fileItems = fileUpload.parseRequest(request);
} catch (FileUpload.SizeLimitExceededException e) {
throw new UploadSizeLimitExceededException(e);
} catch (FileUpload.FileSizeLimitExceededException e) {
throw new UploadSizeLimitExceededException(e);
} catch (FileUploadException e) {
throw new UploadException(e);
}
return fileItems.toArray(new FileItem[fileItems.size()]);
}
/** 根据参数创建<code>FileUpload</code>对象。 */
private ServletFileUpload getFileUpload(UploadParameters params, boolean applyDefaultValues) {
if (applyDefaultValues) {
params.applyDefaultValues();
getLogger().debug("Upload Parameters: {}", params);
}
// 用于生成FileItem的参数
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(params.getRepository());
factory.setSizeThreshold((int) params.getSizeThreshold().getValue());
factory.setKeepFormFieldInMemory(params.isKeepFormFieldInMemory());
// 用于解析multipart request的参数
ServletFileUpload fileUpload = new ServletFileUpload(factory);
fileUpload.setSizeMax(params.getSizeMax().getValue());
fileUpload.setFileSizeMax(params.getFileSizeMax().getValue());
fileUpload.setFileNameKey(params.getFileNameKey());
return fileUpload;
}
}