一键采集上传常见的细节问题(()文件上传的内容上传内容及内容解析 )

优采云 发布时间: 2022-02-28 14:25

  一键采集上传常见的细节问题(()文件上传的内容上传内容及内容解析

)

  一:文件上传:javascript

  要求:

  1:jsp的页面:

  一:表格形式:

  b:帖子提交:

  c: form 指定一个属性:enctype="multipart/form-data"

  d:文件组件:

  2:小服务程序:

  request.getParamter("name");//不生效:

  ServletInputStream in = request.getInputStream();

  把得到的数据封装进去,理论上可以解析数据。

  3:请求在请求正文中:css

  发布请求正文:

  请求第一行:

  请求头信息:html

  请求正文:

  ------------------

  普通组件:只有一个标头:Content-Dispositon:name="xxx"java

  请求正文:mrzhang:填写内容。

  ------------------

  文件上传字段:两个标题:

  内容处置:表单数据;;文件名="C:\Users\Mrzhang\Desktop\copy2.txt"

  内容类型:文本/纯 MIMEweb

  文件上传内容:

  xxxx阿帕奇

  - - - - - - - 大批

  二:解析请求中的请求体:

  1:jar:Apache组织提供的公共组件:

  公共文件上传

  commons-io

  文件上传相关的两个组件,这两个组件是强依赖的。

  2:原理:

  请求体中各个组件的内容被封装成一个对象:

  FileItem 对象:使用对象的方法和属性来获取数据。

  3:获取文件项:

  a:获取工厂:

  b:获取解析器:

  c:使用解析器解析请求,获取fileItme对象:

  对象代码:

  // 获取工厂:

  DiskFileItemFactory 工厂 = new DiskFileItemFactory();

  // 获取解析器:

  ServletFileUpload 上传 = 新的 ServletFileUpload(Factory);

  // 解析请求并获取所有 FileItem 对象:

  List list=upload.parseRequest(request); 浏览器

  4:FileItem类详解:

  isFormField() 判断组件是普通组件还是文件上传组件:true,普通组件:false:文件上传组件:

  getFieldName() 返回普通字段属性的值。name= username 获取用户名的值:

  获取字符串();获取普通字段的上传内容。

  文件上传组件:

  获取名称();获取文件名:

  获取尺寸();将以字节为单位上传文件大小。长

  获取输入流();获取文件上传对应的流:

  写(文件文件);将文件内容写入指定位置:

  雄猫

  三:文件上传的具体代码;

  (1)引入jar包:

  (2)准备页面:

  (3)准备 Servlet:

  四:详情:

  1:上传的普通字段内容:乱码:getString("utf-8");

  2:上传的文件不能被外界直接访问,应隐藏:目的、安全;

  应该是上传到web-inf,内容不能被外界直接访问。安全

  获取 web-inf/files 的位置:tomcat 上的真实位置:

  ServletContext.getRealPath("/WEB-INF/files");

  3:文件的文件路径问题:

  不同浏览器上传的路径不一致。一些浏览器上传相对路径,而另一些浏览器上传绝对路径。大多数浏览器上传的相对路径。

  一个.txt

  c:\user\mrzhang\f​​iles\a.txt

  提取文件名:

  字符串文件名 = f2.getName();

  //截距:

  int index = filename.lastIndexOf("\\");

  如果(索引!=-1){

  文件名 = 文件名.subString(index+1);

  }

  4:上传文件名乱码:

  request.setCharacterEncoding("utf-8");

  解析器提供了一个方法:

  servletFileUpload.setHeaderEncoding("utf-8");// 提供的解析器。高优先级:request.setCharacterEncoding("utf-8")的封装;

  5:文件名相同的问题:

  解决方案1:uuid+“文件名”。后缀名;

  解决方案2:new Date().getTime()+"filename";

  6:上传的文件不能在同一个目录下: 上传的目录被打散了:

  a:时间分手:获取当前时间,创建目录:

  b: 文件名首字母分散:abc.txt : charAt("0")

  c:散列分解:

  实施步骤:

  (1) 获取文件名:

  (2)获取哈希值:hashCode(); int

  (3)转换为十六进制: Integer.toHexString(); //String: 9A8B7C

  (4) 获取字符串的前两位:第一个字母为一级目录,第二个字母为二级目录。16*16

  package com.yidongxueyuan.web.servlet;

import java.io.File;

import java.io.IOException;

import java.util.List;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.FileUploadException;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

/*

* 处理文件上传的servlet:

*

* 1:细节:

* 乱码解决了文件名称上传的乱码,

* 普通字段: getString("utf-8");

*

* 2:对相对路径进行了处理: subString();

*

* 3: 文件名称同名的问题,处理:

*

* 4: 哈希打散:

* filename.hashCode();

* filename.toHexString();

* filename.charAt(0);

*

* File dir= new File(root, charAt(0)+"\"+charAt(1));

*

* File destFile = new File(dir, savefilename);

*

* write();

*

*

*

*

*/

public class FileUploadServlet extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//解决上传文件名称的乱码问题:

request.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");//告知客户端浏览器响应的内容: text/html charset=utf-8

/*

* 三步走:

* 1:得到工厂:

* 2: 得到解析器:

* 3:解析request:

*/

//得到得到解析器工厂;

DiskFileItemFactory factory = new DiskFileItemFactory(1024*20,new File("C:/Users/Mrzhang/javaEE/javaEE-07/temp"));

// DiskFileItemFactory factory = new DiskFileItemFactory();

//得到解析器:

ServletFileUpload upload = new ServletFileUpload(factory);

//解析以前设置上传单个文件的大小:

// upload.setFileSizeMax(1024*10);//这是最大是10K:

// upload.setSizeMax(1024*1024*10); //设置了整个request 的大小, 若是上传的request 大于设定的最大值, 也会触发异常

//解析request: 获List

try {

List fileItem = upload.parseRequest(request);

//解析fileItem当中的内容: web-inf下的: 目录安全: 不能被外界随机的访问:

FileItem f2 = fileItem.get(1);//文件上传的组件:

/*

* 得到文件的名称:

* f2.getName();

* f2.getInputStream(); 文件当中的内容:

* new FileOutputStream("path");

* 实现流对接:

*/

/*

* 得到要保存的路径:

* WEB-INF/files/

* 目的: 安全: 不能被外界直接经过浏览器访问:

* 得到ServletContext对象: 得到真实路径:

*/

String root = this.getServletContext().getRealPath("/WEB-INF/files/");

//得到上传文件的名称:

String filename = f2.getName();

/*

* 细节的处理:

* 1: 绝对路径的问题: 兼顾小部分浏览器:

*/

int index = filename.lastIndexOf("\\");

if(index != -1){//说明路径当中存在\\ :

filename = filename.substring(index+1);

}

/*

* 处理文件同名的问题: uuid

*/

String savename = CommonsUtils.uuid()+"_"+filename;

/*

* 哈希码 生产多个目录: 将上传的文件存放在多个目录当中:

*/

// 1:得到文件名称的哈希值:

int code = filename.hashCode();// int

// 2:得到code 的十六进制的值:

String hex = Integer.toHexString(code);// 9c0a1d

// 得到前两位: 充当第一层目录 和第二层目录:

char firstDir = hex.charAt(0);

char secDir = hex.charAt(1);

/*

* 得到保存的文件路径:

*/

File dirFile = new File(root, firstDir+"/"+secDir);//存放的目录:

//dirFile 若是不存在,建立:

if(!dirFile.exists()){//说明不存在

//建立“:

dirFile.mkdirs();//建立多层的目录:

}

//建立保存的文件:

File destFile = new File(dirFile, savename);

//保存:

try {

f2.write(destFile);

} catch (Exception e) {

e.printStackTrace();

}

} catch (FileUploadException e) {

// 触发异常: 说明文件过大:

request.setAttribute("msg", "您传的文件过大");

request.getRequestDispatcher("/index.jsp").forward(request, response);

e.printStackTrace();

}

}

}

  文件下载

  文件下载:

  原来:服务器响应返回的数据:text/html 浏览器可以自动解析:

  原理:现在要求服务端传递的数据是字节数组:服务端只需要响应一个字节流。

  下载具有两个标头的流需要满足的条件:

  Stream:服务器端响应返回的字节流。new FileOutputStream("字符串路径");

  设置两个标题:

  * Content-Type:这是文件类型的 MIME 类型:text/css text/javascript : tomcat : web.xml

  * Content-Disposition : 默认值:inline 在浏览器中打开。

  文件下载:附件;文件名=xxxx;

  下载详情:

  1:下载的文件名乱码:

  一般解决方案:

  新字符串(name.getBytes("gbk"),"iso-8859-1");

  缺点:这种方法可以解决大部分浏览器,但是个别特殊字符无法解决:

  不同的浏览器对文件名进行不同的编码:

  修复狐:Base64:

  其他浏览器:url

  2:通用方式:提供一个工具类,稍后搜索:

  文件下载servlet代码如下:

  package com.yidongxueyuan.web.servlet;

import java.io.FileInputStream;

import java.io.IOException;

import java.net.URLEncoder;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

import sun.misc.BASE64Encoder;

/*

* 负责下载的Servlet:

*/

public class DownLoadFileServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

/* request.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");*/

/*

* 1: 文件的下载具有一个流: 两个头:

*/

String filename = "C:/Users/Mrzhang/Desktop/API/a练习图片/girl.jpg";

//头信息:

// Content-Type: MIME 文件的MIME类型:

String conentType= this.getServletContext().getMimeType(filename);//可以得到.jpg文件的MIME类型: image/jpeg

String name = "凤姐.jpg";

// String savename = new String(name.getBytes("gbk"),"iso-8859-1"); 解决 大部分状况:

String savename = FilenameEncodingUtils.filenameEncoding(name, request);

String contentDisposition = "attachment;filename="+savename;

//设置响应头信息:

response.setHeader("Content-Type",conentType );

response.setHeader("Content-Disposition", contentDisposition);

//准备的一个流:

//将图片读取到fis当中:

FileInputStream fis = new FileInputStream(filename);

//响应输出流:

ServletOutputStream out = response.getOutputStream();

//流对接: IOUtils

IOUtils.copy(fis, out);

fis.close();

out.close();

}

}

class FilenameEncodingUtils {

// 用来对下载的文件名称进行编码的!

public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {

String agent = request.getHeader("User-Agent"); //获取浏览器

if (agent.contains("Firefox")) {

BASE64Encoder base64Encoder = new BASE64Encoder();

filename = "=?utf-8?B?"

+ base64Encoder.encode(filename.getBytes("utf-8"))

+ "?=";

} else if(agent.contains("MSIE")) {

filename = URLEncoder.encode(filename, "utf-8");

} else {

filename = URLEncoder.encode(filename, "utf-8");

}

return filename;

}

}

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线