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