`
学会做人
  • 浏览: 120997 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

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

阅读更多

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());
  }
 }

}

分享到:
评论

相关推荐

    过滤器实现图片过滤功能

    在本案例中,我们讨论的主题是如何利用过滤器来实现图片过滤功能,这在很多场景下都是非常实用的,比如防止恶意图片上传、实施内容审查或者优化图片资源等。 首先,我们要了解Java Filter的基本概念。Filter是...

    管道过滤器程序,主要用java实现

    8. **使用现代框架**:现代Java Web框架如Spring MVC和Filter API一起使用,可以更方便地管理和配置过滤器,同时提供更多的功能和灵活性。 在提供的压缩包文件`src`中,可能包含了实现上述知识点的源代码。这些代码...

    java过滤器

    ### Java过滤器实现原理与应用...通过以上内容可以看出,Java过滤器是一个非常强大且灵活的工具,可以帮助开发者在不修改业务逻辑的情况下实现各种功能。无论是对于提高系统的安全性还是改善用户体验,都有重要的意义。

    Struts2实现上传功能源码

    1. **配置Struts2核心过滤器**:在web.xml中配置`struts2-convention-plugin`或`struts2-core`过滤器,确保Struts2能够处理请求。 2. **创建上传表单**:HTML表单中需要包含一个`&lt;input type="file"&gt;`标签,用于...

    fiter过滤器的实现

    以`PeripheryLoginCheckFilter.java`为例,我们可以推测这是一个实现了登录检查功能的过滤器。它可能会在用户尝试访问特定资源之前,检查请求中是否存在有效的会话(Session)或认证令牌,如果没有,就重定向到登录...

    解决字符编码的过滤器

    #### 四、使用Servlet过滤器解决字符编码问题 为了确保Struts2应用能够正确处理各种字符编码,可以通过配置Servlet过滤器来统一设置字符编码规则。这种方式具有以下优势: 1. **统一性**:通过在Web应用启动时即...

    tuiimageeditor使用HTML5Canvas实现的全功能照片图像编辑器配有很棒的过滤器

    **tui.image-editor** 是一个基于 HTML5 Canvas 技术的开源项目,它提供了一个...总之,tui.image-editor 是一个强大且灵活的图像编辑解决方案,对于需要在 Web 端提供图片编辑功能的应用来说,是一个值得考虑的选择。

    flash 实现的多文件上传

    Flash在过去的网页开发中被广泛应用于多媒体交互和富互联网应用(RIA),其中包括文件上传功能,因为它可以提供比HTML更灵活的用户界面和更好的文件处理能力。 在Web应用程序中,传统的HTML表单仅支持单个文件上传...

    jqgrid实现图片上传功能(java版)

    总结,实现jqGrid图片上传功能(Java版)需要前端与后端的紧密协作。前端需要处理文件选择、预览和数据提交,而Java后端则负责接收、存储文件并返回响应。通过三层架构,我们可以更好地组织代码,提高可维护性和可...

    使用Struts2实现文件上传和下载的所有方案

    使用Struts2实现手动过滤文件上传的类型和大小 为了确保安全,通常需要限制上传文件的类型和大小。可以通过自定义拦截器或者在Action中实现检查。例如,可以检查文件扩展名,限制文件大小,甚至读取文件内容进行更...

    基于SSM使用ueditor编辑框文本、图片上传功能实现

    本教程将详细讲解如何在SSM项目中集成ueditor编辑框,实现文本和图片的上传功能。 1. **ueditor编辑器** ueditor是由百度开发的一款开源的富文本在线编辑器,提供了丰富的API和配置选项,支持多种文本格式,以及...

    SSM整合 配置文件 文件上传 过滤器 拦截器 连接数据库

    4. **web.xml**:Web应用的部署描述符,配置了DispatcherServlet、过滤器(Filter)以及监听器(Listener)等。 **文件上传**:在SpringMVC中,可以通过MultipartFile类型处理文件上传。需要配置MultipartResolver...

    magento价格过滤器

    "Magento价格过滤器"是Magento系统中的一个重要功能,它允许用户根据商品的价格范围进行筛选,提高购物体验,尤其对于拥有大量商品的在线商店来说,这一功能至关重要。 在描述中提到的“可拖动的区间,自动填写”,...

    通用型Web文件上传JavaBean的实现

    通用型Web文件上传JavaBean的设计和实现,不仅简化了Web开发中文件上传的复杂度,还提高了应用的灵活性和性能。通过理解HTTP协议的工作原理,以及合理设计JavaBean,开发者可以构建高效、安全的Web文件上传系统,...

    百度UEditor 1.3.6 net版 图片上传功能

    通过以上分析,我们可以看到UEditor 1.3.6的图片上传功能不仅提供了便捷的用户体验,而且在安全性、灵活性和易用性方面都做了充分考虑。无论是前端的配置还是后端的接口设计,都需要开发者有扎实的技能基础,以确保...

    SpringBoot+Vue.js实现前后端分离的文件上传功能

    在Vue项目中,需要编写实现上传功能的组件,它会包含一个文件选择器和一个上传按钮。在上传按钮的点击事件中,可以使用JavaScript的XMLHttpRequest对象或更现代的Fetch API发起对后端上传接口的请求,并将选中的文件...

    strust2文件上传功能

    ### Struts2 文件上传功能详解 ...开发者可以根据实际需求灵活配置和使用这些功能,从而实现高效且安全的文件处理操作。此外,还应注意文件的安全性和性能优化等问题,确保应用程序能够在各种环境下稳定运行。

    struts2+jquery.uploadify实现上传下载

    为了支持文件上传,我们需要在Struts配置文件中启用`default-stack`中的`params`拦截器,并添加`上传过滤器`(`filter-class`为`org.apache.struts2.dispatcher.multipart.DefaultFileUploadFilter`),确保文件数据...

    springMVC实现多文件上传需要的jar

    在Spring MVC框架中,实现多文件上传是一...理解这些知识点,你就可以构建一个稳定且灵活的多文件上传功能。注意在实际开发中,还需要考虑安全性,如限制文件大小、过滤非法文件类型等,以防止DoS攻击和其他安全风险。

Global site tag (gtag.js) - Google Analytics