Servelt工具类,基于Tomcat8以上版本,提供常见工具方法,包括:cookie查找和删除、文件下载设置、文件上传的表单解析、上传数据和session中数据的比较、多级目录的创建

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

/**
 * 提供和Servlet有关的一系列工具方法(jdk8)
 * @author 彭锋
 * @2018年6月6日 下午2:41:30
 */
public final class MyServletUtils {
    /**
     * 解析文件上传的表单,并返回解析结果
     * @param req
     * @return
     */
    public static final Map<String,List<FileItem>> parseMultipartParam(HttpServletRequest req){
        //判断是否是文件上传的form
        boolean b = ServletFileUpload.isMultipartContent(req);
        if(b) {
            try {
                //是文件上传的表单提交
                DiskFileItemFactory factory = new DiskFileItemFactory();
                //设置文件上传使用的缓存
                factory.setSizeThreshold(1024*1024);
                //创建ServletFileUpload对象
                ServletFileUpload upload = new ServletFileUpload(factory);
                //解析请求,获取封装了上传的表单数据的Map集合并返回
                return upload.parseParameterMap(req);
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * 根据name获取文件上传的表单提交过来的一个值
     * @param map
     * @param name
     * @return
     */
    public static final String getMultipartParam(Map<String,List<FileItem>> map,String name) {
        String[] values = getMultipartParams(map,name);
        if(values != null && values.length > 0) {
            return values[0];
        }
        return null;
    }
    /**
     * 根据name获取文件上传的表单提交过来的多个值
     * @param map
     * @param name
     * @return
     */
    public static final String[] getMultipartParams(Map<String,List<FileItem>> map,String name) {
        String[] values = null;
        List<FileItem> list = map.get(name);
        if(list != null && !list.isEmpty()) {
            values = new String[list.size()];
            try {
                for (int i = 0; i < values.length; i++) {
                    FileItem item = list.get(i);
                    values[i] = item.getString("utf-8");
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return values;
    }
    /**
     * 根据指定的name,获取文件上传表单中提交过来的一个FileItem对象
     * @param map
     * @param name
     * @return
     */
    public static final FileItem getMultipartFile(Map<String,List<FileItem>> map,String name) {
        FileItem[] values = getMultipartFiles(map,name);
        if(values != null && values.length > 0) {
            return values[0];
        }
        return null;
    }
    /**
     * 根据指定的name,获取文件上传表单中提交过来的FileItem数组
     * @param map
     * @param name
     * @return
     */
    public static final FileItem[] getMultipartFiles(Map<String,List<FileItem>> map,String name) {
        FileItem[] values = null;
        List<FileItem> list = map.get(name);
        if(list != null && !list.isEmpty()) {
            values = list.toArray(new FileItem[list.size()]);
        }
        return values;
    }
    /**
     * 根据文件名的哈希值,使用按位与和移位运算的方式,生成n级目录
     * @param parentPath 要生成的文件夹的父目录
     * @param fileName 文件名
     * @param n 要生成的文件目录的层数,最小1,最高8
     * @return
     */
    public static final String createDirs(String parentPath,String fileName,int n) {
        if(fileName != null && fileName.trim().length() > 0) {
            String dirPath = "/";
            //根据文件名,获取哈希码
            int code = fileName.hashCode();
            //判断n的值,最低不能小于1,最多不能大于8
            if(n <= 0) {
                n = 1;
            }else if(n > 8) {
                n = 8;
            }
            //根据要生成的文件夹的级数,生成对应的文件夹的路径
            for(int i = 0; i < n; i++) {
                code = code >>> 4*i;
                dirPath = dirPath+ (code & 15) +"/";
            }
            File parentDir = new File(parentPath);
            if(!parentDir.exists()) {
                throw new RuntimeException("指定的父目录不存在!");
            }
            File dir = new File(new File(parentPath),dirPath);
            if(!dir.exists()) {
                dir.mkdirs();
            }
            return dirPath;
        }
        throw new NullPointerException("文件名不能为空!");
    }
    /**
     * 删除Cookie
     * @param resp 响应对象
     * @param cookie 要删除的Cookie
     */
    public static final void deleteCookie(HttpServletResponse resp,Cookie cookie) {
        if(cookie != null) {
            cookie.setValue("");
            cookie.setMaxAge(0);
            resp.addCookie(cookie);
        }
    }
    /**
     * 根据指定的名字,从请求中查找cookie
     * @param req
     * @param name
     * @return
     */
    public static final Cookie getCookie(HttpServletRequest req,String name) {
        Cookie[] cookies = req.getCookies();
        if(cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals(name)) {
                    return cookie;
                }
            }
        }
        return null;
    }
    
    /**
     * 判断从页面提交的数据和session中相同名称的数据是否相等(可用于判断验证码等)
     * @param req 请求对象
     * @param keyName 请求和session中保存的相同的键名
     * @return
     */
    public static final boolean isEqual(HttpServletRequest req,String keyName) {
        String data = req.getParameter(keyName);
        if(data == null) {
            return false;
        }else {
            return data.equals(req.getSession().getAttribute(keyName));
        }
    }
    /**
     * 针对文件下载的请求,对响应进行处理,并返回响应给浏览器的字节输出流
     * @param req 请求对象
     * @param resp 响应对象
     * @param fileName 返回给浏览器显示用的下载的文件名
     * @return
     * @throws IOException
     */
    public static final OutputStream downloadProcessing(HttpServletRequest req, HttpServletResponse resp,String fileName) throws IOException {
        //设置返回给浏览器的数据的类型
        resp.setContentType(req.getServletContext().getMimeType(fileName));
        /*
         * 处理返回给浏览器的文件名,避免出现中文乱码
         *        需要对下载的文件名进行编码:保证浏览器端可以正常的显示数据
         *        这里需要对setHeader中的value值进行编码,这里不同的浏览器采用的编码形式不一样。
         *        IE、Chrome 等他们可以使用Java中提供的EncodeURL类进行编码。
         *        而Firefox它内部采用的Base64编码,我们需要判断用户当前使用的是什么浏览器,然后确定对应的编码算法
         *        在用户发出请求的时候,在请求头中携带了当前浏览器的信息 user-agent
         */
        String agent = req.getHeader("user-agent");
        //判断用户使用的浏览器
        if( agent!=null && agent.contains("Firefox") ){
            /*
             * 判断成立,说明用户使用的是火狐浏览器 ,需要对文件名进行base64编码,然后进行如下处理
             */
            //获取base64编码对象
            Encoder encoder = Base64.getEncoder();
            //对文件名进行base64编码
            String base64 = encoder.encodeToString(fileName.getBytes("utf-8"));
            //对编码过后的文件名进行如下处理
            fileName = "=?utf-8?B?"+ base64 +"?=";
        }else{
            //使用的IE ,Chrome 等浏览器
            fileName = URLEncoder.encode(fileName, "utf-8");
        }
        /*
         * 通过设置响应头,告诉浏览器以附件下载的方式处理收到的数据
         * setHeader 设置响应的头信息:
         *         key :Content-Disposition 
         *         value: attachment 告诉浏览器当前的 数据需要以附件下载的方式打开    
         *         filename=浏览器显示的下载的文件名
         * */
        resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        return resp.getOutputStream();
    }
}

 

posted on 2018-06-06 16:40  大别山人  阅读(142)  评论(0编辑  收藏  举报