上传
基本实现思路
-
表单设计
enctype="multipart/form-data"
-
Servlet设计
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置编码 request.setCharacterEncoding(StandardCharsets.UTF_8.toString()); response.setContentType("text/html;charset=utf-8"); //获取解析器工厂,其中的两个参数分别为内存的缓存大小和缓存的临时存放路径 DiskFileItemFactory dif=new DiskFileItemFactory(1024*20,new File("C:/temp")); //获取解析器 ServletFileUpload sfi=new ServletFileUpload(dif); try { //通过解析器获取List,List中存放的是FileItem List<FileItem> items = sfi.parseRequest(request); for (FileItem item : items) { //该方法用来判断是否为普通表单 if (item.isFormField()){ System.out.println(item.getFieldName()+" "+item.getString(StandardCharsets.UTF_8.toString())); }else{ //因为个别浏览器的文件名会包含磁盘路径,因此需要先通过判断来截取实际文件名 String name=item.getName(); int index=name.lastIndexOf("\"); if (index!=-1){ name=name.substring(index+1); } //为了避免重名,所以为文件重新命名 String saveName= CommonsUtils.getUUID()+"_"+name; //获取文件名对象的hashcode int hashCode = name.hashCode(); //获取hashcode的16进制表示的字符串 String hexString = Integer.toHexString(hashCode); //获取web项目的实际路径信息 String root=this.getServletContext().getRealPath("/WEB-INF/files"); //设置保存路径:规则为截取字符串的第一个和第二个字符作为路径 File file=new File(root,hexString.charAt(0)+"/"+hexString.charAt(1)); //该方法可以判断路径是否存在,若路径存在啥也不干,若不存在则创建路径 file.mkdirs(); //文件的保存路径 File saveFile=new File(file,saveName); //保存文件 item.write(saveFile); } } } catch (Exception e) { e.printStackTrace(); } }
-
Servlet3.0对上传的支持
req.setCharacterEncoding("utf-8"); //可以直接获取参数 System.out.println(req.getParameter("username")); //获取Part对象,以便于对文件的操作 Part part = req.getPart("pic"); String header = part.getHeader("Content-Disposition"); int indexOf = header.lastIndexOf("filename="); int start=indexOf+10; int end=header.length()-1; String filename=header.substring(start,end); //写入文件 part.write("C:/Users/wu2we/Desktop/java/bookstore/out/artifacts/bookstore_war_exploded/book_img/"+filename);
下载
基本实现思路
总结起来就是两头一流:
两头:
- Content-Type :用来设置文件的类型,文件类型可以通过this.getServletContext().getMimeType(String s)方法获取到,参数是文件名。
- Content-Disposition:用来设置下载方式(弹出下载框),以及文件名,格式固定:attachment;filename=?
一流:即输出流
File file=new File("C:/Users/wu2we/Desktop/jdk-9_汉化版.CHM");
FileInputStream inputStream=new FileInputStream(file);
String mimeType = this.getServletContext().getMimeType("C:/Users/wu2we/Desktop/jdk-9_汉化版.CHM");
//解决编码问题
String newDisposition= DownUtils.filenameEncoding("jdk-9_汉化版.CHM",request);
String disposition="attachment;filename="+newDisposition;
response.setHeader("Content-Type",mimeType);
response.setHeader("Content-Disposition",disposition);
ServletOutputStream stream = response.getOutputStream();
IOUtils.copy(inputStream,stream);
inputStream.close();
文件名的编码问题
解决方案见上方