[Java] 纯文本查看 复制代码
实现文件上传的三点前提:
* 表单页面的method属性设置为post方式
* enctype属性设置为multipart/form-data类型
* input标签为file类型
<form enctype=”multipart/form-data” method=”post”/>
为什么用post提交请求?因为post没有大小限制。并且数据都在请求体中。
需要的jar包 commons-fileupload commons-io
下图为工作流程图:
4.核心类介绍:
* DiskFileItemFactory类:用于将请求消息实体中的每一个文件封装成单独的FileItem对象。
* ServletFileUpload 类:通过使用parseRequest(HttpServletRequest request)方法可以将HTML中每个表
单提交的数据封装成一个FileItem对象,然后以List集合返回。
* FileItem接口:用于封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem对象。
5.代码练习
//分离目录
String hexString =Integer.toHexString(fileName.hashCode());
String path = hexString.charAt(0) + "/" + hexString.charAt(1);
String filePath=this.getServletContext().getRealPath(webPath+path+fileName);
文件上传
//1.创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
File f = new File("I:\\target");
if(!f.exists()){
f.mkdirs();
}
//2.设置文件的缓存路径
factory.setRepository(f);
//3.创建fileUpload组件
ServletFileUpload fileupload = new ServletFileUpload(factory);
fileupload.setHeaderEncoding("utf-8");
//获取系统字符编码
//4.解析reqeust
List<FileItem> fileItems = fileupload.parseRequest(request);
PrintWriter pw = response.getWriter();
//5.遍历集合
for(FileItem fileItem:fileItems){
//6.判断是否为普通字段
if(fileItem.isFormField()){
//获得字段名和字段值
String name = fileItem.getFieldName();
String value = fileItem.getString("utf-8");
pw.print("上传者"+value+"<br>");
}else{
//上传的文件路径 根据浏览器的不同会有区别
String fileName = fileItem.getName();
pw.println("文件来源"+fileName+"<br>");
//截取出文件名
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
pw.print("成功上传文件:"+fileName+"<br>");
//文件名唯一
fileName = UUID.randomUUID().toString().replace("-", "")+"_"+fileName;
//在服务器创建同名文件
String webPath = "/upload/";
//分离目录
String hexString =Integer.toHexString(fileName.hashCode());
String path = hexString.charAt(0) + "/" + hexString.charAt(1);
String filePath = this.getServletContext().getRealPath(webPath+path+fileName);
System.out.println(filePath);
//创建文件
File file = new File(filePath);
file.getParentFile().mkdirs();
file.createNewFile();
//获得上传文件流
InputStream in = fileItem.getInputStream();
//获得写入文件流
OutputStream out = new FileOutputStream(file);
//流的对拷
IOUtils.copy(in,out);
//释放资源
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
fileItem.delete();
文件下载
String fileName=new String(request.getParameter("fileName").getBytes("iso-8859-1"),"utf-8");
System.out.println(fileName);
String type=this.getServletContext().getMimeType(fileName);
response.setHeader("ContentType", type);
String realPath = this.getServletContext().getRealPath("/download/"+fileName);
// 根据浏览器的类型处理中文文件的乱码问题:
String agent = request.getHeader("User-Agent");
System.out.println(agent);
if(agent.contains("Firefox")){
fileName = base64EncodeFileName(fileName);
}else{
fileName = URLEncoder.encode(fileName,"UTF-8");
}
response.setHeader("Content-Disposition", "attachment;filename="+fileName);
InputStream in = new FileInputStream(realPath);
OutputStream os = response.getOutputStream();
byte[] b = new byte[1024];
int len;
while((len=in.read(b))!=-1){
os.write(b,0,len);
}
in.close();
os.close();
}
public static String base64EncodeFileName(String fileName) {
BASE64Encoder base64Encoder = new BASE64Encoder();
try {
return "=?UTF-8?B?"
+ new String(base64Encoder.encode(fileName
.getBytes("UTF-8"))) + "?=";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}