过滤器灵活使用实现上传功能

package com.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

/**
 * Copyright(c),2000-2009,

 * FileName:com.util.CharFilter.java
 *  * @author
 * @Date 2009-6-24
 * @Description 字符过滤器
 * @version 1.00
 * @see
 */
public class CharFilter implements Filter{

 /**请求对象*/
 private HttpServletRequest request;
 /**上传组件*/
 private Upload upload;

 public void destroy() {}
 /**
  * 过滤方法
  * @param arg0 请求方法
  * @param arg1 响应方法
  * @param arg2 请求传递到过滤器链
  */
 public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
  this.request = (HttpServletRequest)arg0;

  //设置响应对象
  HttpServletResponse response = (HttpServletResponse)arg1;
  response.setContentType("text/html;charset=gbk");

  this.mkDir();

  MyRequest myRequest = new MyRequest();
  arg2.doFilter(myRequest, response);
 }

 /**
  * 判断是否是上传文件,如果是则创建目录
  * @throws IOException
  */
 private void mkDir() throws IOException{
  String contentType = request.getContentType();

  if(contentType != null && contentType.indexOf("multipart/form-data") != -1){
   upload  = new Upload();
   //获得真实路径
   String path = request.getSession().getServletContext().getRealPath("/img");

   File file = new File(path);
   if(!file.exists()){
    file.mkdir();
   }
   //调用上传方法
   upload.upload(path);
  }
 }

 public void init(FilterConfig arg0) throws ServletException {}
 
 /**
  * Copyright(c),2000-2009
  
  * 
  * @Date 2009-6-24
  * @Description 自定义请求对象
  * @version 1.00
  * @see
  */
 private class MyRequest extends HttpServletRequestWrapper{

  public MyRequest() {
   super(request);
  }

  /**
   * 获得请求参数
   * @param arg0 请求参数
   */
  public String getParameter(String arg0) {
   //请求内容类型字符串
   String contentType = request.getContentType();

   //上传组件
   if(contentType != null && contentType.indexOf("multipart/form-data") != -1){
    String info = upload.getParameter(arg0);

    return info;
   }
   else{//普通提交
    String value = request.getParameter(arg0);

    if(value == null){
     return null;
    }
    //转码
    try {
     byte[] by = value.getBytes("ISO8859-1");
     value = new String(by,"gbk");
    } catch (Exception e) {
     e.printStackTrace();
    }
    return value;
   }
  }

  /**
   * 获得一组数据
   * @param arg0 请求参数
   */
  public String[] getParameterValues(String arg0) {
//   请求内容类型字符串
   String contentType = request.getContentType();

   //上传组件
   if(contentType != null && contentType.indexOf("multipart/form-data") != -1){
    String[] strArr = upload.getParameterValues(arg0);
    return strArr;
   }
   else{//普通提交
    String[] strs = request.getParameterValues(arg0);

    if(strs == null){
     return null;
    }

    //转码
    try {
     for(int i=0;i<strs.length;i++){
      byte[] by = strs[i].getBytes("ISO8859-1");
      strs[i] = new String(by,"gbk");
     }
    } catch (UnsupportedEncodingException e) {
     e.printStackTrace();
    }
    return strs;
   }
  }
 }

 /**
  * Copyright(c),2000-2009
  * 
  * @author
  * @Date 2009-6-25
  * @Description 上传组件
  * @version 1.00
  * @see
  */
 private class Upload {
  /**初始化*/
  private final static int NONE=1;
  /**接下来读到头信息*/
  private final static int HEADER=2;

  /**请求参数封装的Map集合*/
  private Hashtable<String,Object> fieldMap = new Hashtable<String,Object>();

  /**当前状态*/
  private  int state = NONE;

  /**分界符*/
  private String boundary = null;
  /**分界符 结束*/
  private String lastBoundary = null;

  /**上传组件所用的字节流*/
  private ServletInputStream input;

  /**
   * 构造方法
   */
  public Upload(){
   //得到上传组件的内容类型
   String contentType = request.getContentType();
   //得到分界符
   this.boundary = this.getBoundary(contentType);
   //得到分界结束符
   this.lastBoundary = boundary+"--";
  }

  /**
   * 获得请求参数
   * @param key 参数名
   * @return 参数值
   */
  public String getParameter(String key){
   //根据键获得值
   Object obj = fieldMap.get(key);

   //如果值为空,则返回空
   if(obj == null){
    return null;
   }

   //如果对应的值是字符串数组,则返回第一个值
   if(obj.getClass() == String[].class){
    String[] stringArray = (String[])obj;
    return stringArray[0];
   }
   return obj.toString();
  }

  /**
   * 获得一组数据
   * @param key 参数名
   * @return 参数数组
   */
  public String[] getParameterValues(String key){
//   根据键获得值
   Object obj = fieldMap.get(key);
//   如果值为空,则返回空
   if(obj == null){
    return null;
   }

   //如果obj是字符串数组,则直接返回
   if(obj.getClass() == String[].class){
    String[] stringArray = (String[])obj;
    return stringArray;
   }

   //如果不是字符串数组,则创建数组。并将值做为第一上元素
   String[] tempArray = {obj.toString()};
   return tempArray;
  }

  /**
   * 上传文件方法
   * @param dirString 文件所在的目录
   * @throws IOException IO异常
   */
  public void upload(String dirString) throws IOException{
    //获得输入流
       input = request.getInputStream();

    //临时字节数组
    byte[] by = new byte[1024];
    int temp=0;//读取字节数

    //将流进行行读取,以字节方式写入文件
    while((temp = input.readLine(by, 0, by.length)) != -1){
     //将字节数组写入文件
     String str = new String(by,0,temp).trim();

     //如果读到最后一行,则跳出循环
     if(str.equals(this.lastBoundary)){
      break;
     }

     switch(this.state){
     case  NONE://初始状态
      if(str.startsWith(this.boundary)){
       this.state = HEADER;
      }
      break;
     case HEADER://头
      //判断是否是上传的文件数据
      if(str.indexOf("filename=") >0){
       this.setUploadFile(str,by,dirString);
      }
      else{//普通数据
       this.setNormal(str,by);
      }
      this.state = NONE;
      break;
    }
   }
  }
  
  /**
   * 处理文件上传
   * @param str 行读取的字符串
   * @param by 包含数据的字节数组
   * @param dirString 目录名
   * @throws IOException
   */
  private void setUploadFile(String str, byte[] by, String dirString) throws IOException {
   //按引号分割,第二个元素就是参数名,第四个元素就是文件名
   String[] args = str.split("\"");

   if(args.length<4){
    return;
   }
   //以日期毫秒为文件名
   String fileName = dirString+"/"+new Date().getTime()+args[3].substring(args[3].indexOf("."));

   //参数为键,文件名为值
   this.fieldMap.put(args[1], fileName);

   //临时变量
   int temp = 0;
   //读取空行
   temp = input.readLine(by, 0, by.length);
   temp = input.readLine(by, 0, by.length);

   //构建文件写入流
   FileOutputStream  out = new FileOutputStream(fileName);

   //循环写入
   while((temp = input.readLine(by, 0, by.length)) != -1){

    str = new String(by,0,temp).trim();

    //如果是分界符,则跳出循环
    if(this.lastBoundary.equals(str) || this.boundary.equals(str)){
     break;
    }
    out.write(by,0,temp);
   }
   //关闭流
   out.close();
  }
  
  /**
   * 普通参数
   * @param str 行读取字符串
   * @param by 字节数组
   * @throws IOException
   */
  private void setNormal(String str,byte[] by) throws IOException {
   //获得属性名
   String fieldName = this.getFieldName(str);

   //临时变量
   int temp = 0;
   //读取空行
   temp = input.readLine(by, 0, by.length);
   //读取数据
   temp = input.readLine(by, 0, by.length);

   //获得值
   String value = new String(by,0,temp).trim();

   //判断是否存在键
   if(this.fieldMap.containsKey(fieldName)){//存在
    //通过键取到值
    Object obj = fieldMap.get(fieldName);

    //存放值的集合
    List list = new ArrayList();

    //如果是字符串
    if(obj.getClass() == String.class){
     list.add(obj);
    }
    else if(obj.getClass() == String[].class){//如果是字符串数组
     String[] strArray = (String[])obj;
     for(String tempString : strArray){
      list.add(tempString);
     }
    }

    //加入新值
    list.add(value);

    String[] strArray = this.toStringArray(list);
    this.fieldMap.put(fieldName, strArray);
   }
   else{
    //加入Map集合
    this.fieldMap.put(fieldName, value);
   }
  }
  /**
   * 获得属性值
   * @param str 行读取字符串
   * @return 属性值
   */
  private String getFieldName(String str) {
   int index = str.indexOf("name");
   return str.substring(index+6,str.trim().length()-1);
  }

  /**
   * 将集合对象转化为字符串数组
   * @param list 集合对象
   * @return 字符串数组
   */
  private String[] toStringArray(List list) {
   Object[] objs = list.toArray();
   String[] stringArray = new String[objs.length];
   for(int i=0;i<objs.length;i++){
    stringArray[i] = objs[i].toString();
   }
   return stringArray;
  }

  /**
   * 分界字符串
   * @param contentType
   * @return
   */
  private String getBoundary(String contentType) {
   int index = contentType.indexOf("boundary=");
   return "--"+contentType.substring(index+"boundary=".length());
  }
 }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值