文件上传
- form method=post
- form encType=multipart/form-data值 :表示提交的数据以多段的形式进行拼接,然后以二进制流的形式发送给服务器
- form input type = file添加上传文件
<body>
<%--
action表示 服务器的url,结合xml配置文件,如果不通过表单提交,就直接在浏览器输入http://localhost:8080/upLoadServlet,
报405此URL不支持Http方法GET
请求行中接收的方法由源服务器知道,但目标资源不支持
--%>
<form action="http://localhost:8080/upLoadServlet" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"> <br>
头像:<input type="file" name="photo"> <br>
提交 <input type="submit" value="上传">
</form>
</body>
- 编写服务器代码接受处理上传的数据
(1)解析数据 用到两个jar包 commons-fileupload.jar /commobs-io.jar
(2) ServletFileUpload 用于解析上传的数据,方法:
①. 判断当前上传的数据格式是否是多段格式isMultipartContext()
②. 解析上传的数据parseRequest()
③. 判断当前这个表单项是普通的表单项(true)还是文件类型(false)isFormField()
④. getFieldname getString getName
⑤. FileItem.write(file):将上传的文件写到file磁盘目录
//(1)只有是多段的数据,才代表文件上传的
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (ServletFileUpload.isMultipartContent(req)) { // 如果是多段的
FileItemFactory fileItemFactory = new DiskFileItemFactory(); // 创建工厂实现类
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); // 创建用于解析上传数据的工具类ServlstFileUpload
try {
List<FileItem> list = servletFileUpload.parseRequest(req);// 解析上传的数据,得到内一个表单项
for(FileItem fileItem : list){
if (fileItem.isFormField()) {
// true普通表单项
System.out.println("表单项的name:"+fileItem.getFieldName());
System.out.println("表单项的value:"+fileItem.getString("utf-8"));
}else {
// 上传的文件
System.out.println("表单项的name:"+fileItem.getFieldName());
System.out.println("上传的文件名:"+fileItem.getName());
fileItem.write(new File("e:\\"+fileItem.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
读取上传给服务器的数据(了解)
req.setCharacterEncoding("utf-8");
System.out.println("文件上传过来了,现在我开始处理文件了");
//0.因为 form encType=multipart/form-data值 :表示提交的数据以多段的形式进行拼接,然后以二进制流的形式发送给服务器
System.out.println(req.getParameter("username"));
// 1.以二进制流的形式读取客户端上传给服务器的图片 数据
ServletInputStream inputStream = req.getInputStream();
byte[] buffer = new byte[1024];
int read = inputStream.read(buffer);
System.out.println(new String(buffer,0,read));
文件下载
- 服务器获取要下载的文件名
- 通过ServletContext对象读取要下载的文件输入流
- 通过servletContext获取要下载的文件类型
- 在回传前,通过响应头告诉客户端返回的数据类型
- 告诉客户端收到的数据是用于下载(通过响应头),并针对不同浏览器采用不同的编码
- 把要下载的内容以流的形式回传给客户端
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.服务器获取要下载的文件名
String downloadFileName = "iu_big.jpg";
ServletContext servletContext = getServletContext();
// 2.通过ServletContext对象读取要下载的文件输入流
InputStream resourceAsStream = servletContext.getResourceAsStream("/FileUpLoadDownLoad/downloadFile/"+downloadFileName);
// 3.通过servletContext获取要下载的文件类型
String mimeType = servletContext.getMimeType("/FileUpLoadDownLoad/downloadFile/"+downloadFileName);
// 4.在回传前,通过响应头告诉客户端返回的数据类型
resp.setContentType(mimeType);
// 5.告诉客户端收到的数据是用于下载(通过响应头),并针对不同浏览器采用不同的编码
// resp.setHeader("Content-Disposition","attachment;filename="+downloadFileName); // 表示附件,下载使用
if (req.getHeader("User-Agent").contains("Firefox")) {
resp.setHeader("Content-Disposition","attachment;filename==?UTF-8?B?"+ new BASE64Encoder().encode("火狐编码.jpg".getBytes("UTF-8")) +"?=");//火狐浏览器BASE64编码
}else {
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("URL编码.jpg","UTF-8"));//URL编码支持谷歌ie,把汉字转换成16进制格式
}
// 6.把要下载的内容以流的形式回传给客户端
ServletOutputStream outputStream = resp.getOutputStream(); // 获取响应的输出流
IOUtils.copy(resourceAsStream, outputStream); // 读取流中全部的数据,复制给输出流,输出给客户端
}
这里若出现响应状态码500空指针NullPointException异常只需重新导入io包并重启服务器即可解决。