对commons fileupload组件的简单封装
我们要取得possess传过来的value,一般我们是这么写的:xml 代码
- <input type="text" name="possess">
但是在commons fileupload中我们却需要这么处理:java 代码
- String possess = request.getParameter("possess")
java 代码
- DiskFileItemFactory factory = new DiskFileItemFactory();
- //Create a new file upload handler
- ServletFileUpload upload = new ServletFileUpload(factory);
- String possess = "";
- try ...{
- List items = upload.parseRequest(request);
- Iterator iterator = items.iterator();
- while(iterator.hasNext())...{
- FileItem item = (FileItem)iterator.next();
- if(item.isFormField())...{
- String fieldName = item.getFieldName();
- String value = item.getString();
- if(fieldName.equals("possess"))...{
- possess = value;
- }
- }
- }
- } catch (FileUploadException e) ...{
- e.printStackTrace();
- }
按照上面处理的话,很是不爽,因此我想包装一下,使得使用起来符合我们的习惯。
总体设计思想:
1.我们可以像以前那样,传入控件的name,就可以取得该控件的value,因此我想可以遍历所有FileItem,然后把他们存入一个Map中(key中存入fieldname,value中存入该控件的value),这样就可以达到以上目的了。具体实现:
2.在该包装类中,我们还要可以设置一些值,从而我们可以更改commons fileupload中的一些配置。
根据以上要求,我写出了一个MutiFileUpload类,代码如下,稍后再做详细解释。
java 代码
- package chb.commons.fileupload.web;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- /**
- * @author chb
- *
- */
- public class MutiFileUpload extends HttpServlet{
- private static final long serialVersionUID = 670829239023754119L;
- protected Map//保存普通form表单域
- protected Map//保存上传的文件
- /**
- * The directory in which uploaded files will be stored, if stored on disk.
- */
- private int sizeThreshold = DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD;
- /**
- * The maximum size permitted for the complete request, as opposed to
- * {@link #fileSizeMax}. A value of -1 indicates no maximum.
- */
- private long sizeMax = -1;
- private String encoding = "utf-8";//字符编码,当读取上传表单的各部分时会用到该encoding
- public String getEncoding() {
- return encoding;
- }
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
- public long getSizeMax() {
- return sizeMax;
- }
- public void setSizeMax(long sizeMax) {
- this.sizeMax = sizeMax;
- }
- public int getSizeThreshold() {
- return sizeThreshold;
- }
- public void setSizeThreshold(int sizeThreshold) {
- this.sizeThreshold = sizeThreshold;
- }
- public void parse(HttpServletRequest request){
- parameters = new HashMap
- files = new HashMap
- //Create a factory for disk-based file items
- DiskFileItemFactory factory = new DiskFileItemFactory();
- //Set factory constraints
- factory.setSizeThreshold(sizeThreshold);
- //factory.setRepository(repository);
- //Create a new file upload handler
- ServletFileUpload upload = new ServletFileUpload(factory);
- //Set overall request size constraint
- upload.setSizeMax(sizeMax);
- upload.setHeaderEncoding(encoding);
- try {
- List items = upload.parseRequest(request);
- Iterator iterator = items.iterator();
- while(iterator.hasNext()){
- FileItem item = (FileItem)iterator.next();
- if(item.isFormField()){
- String fieldName = item.getFieldName();
- String value = item.getString();
- parameters.put(fieldName, value);
- }else{
- String fieldName = item.getFieldName();
- files.put(fieldName, item);
- }
- }
- } catch (FileUploadException e) {
- e.printStackTrace();
- }
- }
- /** 得到上传文件的文件名
- * @param item
- * @return
- */
- public String getFileName(FileItem item){
- String fileName = item.getName();
- fileName = replace(fileName,"\\","/");
- fileName = fileName.substring(fileName.lastIndexOf("/")+1);
- return fileName;
- }
- /**字符串替换
- * @param source
- * @param oldString
- * @param newString
- * @return
- */
- public static String replace(String source, String oldString, String newString) {
- StringBuffer output = new StringBuffer();
- int lengthOfSource = source.length();
- int lengthOfOld = oldString.length();
- int posStart = 0;
- int pos;
- while ((pos = source.indexOf(oldString, posStart)) >= 0) {
- output.append(source.substring(posStart, pos));
- output.append(newString);
- posStart = pos + lengthOfOld;
- }
- if (posStart < lengthOfSource) {
- output.append(source.substring(posStart));
- }
- return output.toString();
- }
- }
以上代码很简单,看过commons FileUpload组件API的程序员,应该都能看明白。值得注意一下的是:编码问题(setHeaderEncoding),这个方法是从 FileUploadBase类里继承的, 根据其说明,当读取上传表单的各部分时会用到该encoding,如果没有指定encoding则使用系统缺省的encoding。建议在这里设置成utf-8,并把jsp的charset也设置成utf-8,否则可能会出现乱码。测试demo
好了,下面我就写个简单的demo吧,说明一下MutiFileUpload的用法。
1.新建一个jsp页面,注意设置form表单的enctype,如下:
xml 代码
- <form id="form1" method="post" action="../servlet/UploadServlet" enctype="multipart/form-data">
- <tr>
- <td width="25%" align="right">上传图片:td>
- <td>
- <input id="file1" type="file" NAME="file1" style="width:300px;">
- td>
- tr>
- <tr>
- <td width="25%" align="right">上传音频:td>
- <td>
- <input id="file2" type="file" NAME="file2" style="width:300px;">
- td>
- tr>
- <tr align="center" valign="middle">
- <td height="60" colspan="2">
- <input type="submit" id="BtnOK" value="确认上传">
- <button onclick="javascript:window.opener == null;window.close();">取消上传button> td>
- tr>
- <tr align="center" valign="middle">
- <td height="60" colspan="2">
- <input type="text" name="possess" value="private">
- td>
- tr>
- form>
2.新建一个UploadServlet并继承自 MutiFileUpload,如下:
java 代码
- public class UploadServlet extends MutiFileUpload ...{
- }
3.然后在post方法中如下处理:选择上传文件,然后我们就可以在/root/upload下看到我们上传的文件了。java 代码
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- parse(request);
- System.out.println(parameters.get("possess"));
- Iterator iterator = files.values().iterator();
- while(iterator.hasNext()){
- FileItem item = (FileItem) iterator.next();
- String fileName = getFileName(item);
- File file = new File("/root/upload/"+fileName);
- try {
- item.write(file);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
好了,先写到这里吧,具体应用时,我们可能需要很多变通,比如集成到spring,hibernate中,关键是给出一个想法,我们可以对他进行包装变更,使其更适合我们的系统。