一 概述
1.什么是文件上传?
将本地文件保存到服务器上的过程,叫做文件上传。
2.什么是文件下载?
广义上,任何从服务器端获取数据的过程都属于文件下载,默认情况下由浏览器打开展示。狭义的文件下载,指的是将从服务器端获取的数据以附件的形式保存到本地。因此下载文件时,需要重新设定浏览器处理响应内容的方式:
response.setHeader("Content-disposition","attachment;filename=xxxxxx");
由于响应报头只支持ISO-8859-1的编码方式,如果文件名含有中文,将出现乱码,因此文件名必须转化为ISO-8859-1编码形式:
String filenameStr="图片.jpg"//定义中文文件名 byte[] buf=filenameStr.getBytes("UTF-8");//将文件名转化为UTF-8编码系统下的字节码(工作空间采用UTF-8编码) String filename =new String(buf,"ISO-8859-1");//采用ISO-8859-1对字节码重新进行编码
二 上传
1.文件上传对请求的要求
请求方式:POST。
数据类型:
enctype="multipart/form-data"
表单编写:
<form action="${pageContext.request.contextPath }/fc01.do"method="post" enctype="multipart/form-data">
<input type="file" name="img">
<input type="submit" value="上传文件">
</form>
2.文件上传的关键
上传文件在服务器上的目录一般已固定,只需要获取了输入流,就可以完成上传任务。上传文件在客户端的路径由用户指定,不能采用:
FileInputStream is=new FileInputStream(String sourcePath)
确定,因此创建输入流是文件上传的关键。
3.不同的框架提供了不同的获取输入流的方式。
4.Servlet上传
Servlet提供了Part对象获取输入流。
import java.io.File; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; @WebServlet("/uploadServlet") @MultipartConfig() public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); request.setCharacterEncoding("UTF-8"); Part part = request.getPart("fileName"); //利用自定义工具从Content-disposition请求头中获取文件名 String fileName = UploadUtils.getFileName(part); String path = request.getServletContext().getRealPath("/Files"); part.write(path + File.separator + fileName); } }
5.SpringMVC上传
SpringMVC提供了MultipartFile对象实现文件上传。
配置文件:
<mvc:annotation-driven /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--单次允许上传的最大值 --> <property name="MaxUploadSize" value="1048576" /> <!--设置文件上传时的编码方式,解决文件名为中文时的乱码问题 --> <property name="defaultEncoding" value="UTF-8" /> </bean>
java代码:
import java.io.File; import java.io.IOException; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; @Controller @RequestMapping public class FileUploadController { @RequestMapping("/fc01.do") public String doUpload01(HttpSession session, MultipartFile img, Model model) throws IllegalStateException, IOException { if (img.getSize() > 0) { String filename = img.getOriginalFilename(); System.out.println("filename=" + filename); if (filename.endsWith("jpg")) { String path = "d:/uploadFiles"; File file = new File(path, filename); img.transferTo(file); } else { model.addAttribute("fileTip", "不支持格式"); return "/fileUpload/index.jsp"; } } else { model.addAttribute("fileTip", "请选择文件"); return "/fileUpload/index.jsp"; } return "/fileUpload/success.jsp"; } }
6.Struts2上传
基本原理:fileUpload拦截器先将文件上传到临时文件中,然后注入到Action中。
核心代码:
import java.io.File; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class SingleuploadAction extends ActionSupport { private static final long serialVersionUID = 7322039059983814357L; private File img; private String imgFileName; public File getImg() {return img; } public void setImg(File img) {
this.img = img; } public String getImgFileName() {
return imgFileName; } public void setImgFileName(String imgFileName) {
this.imgFileName = imgFileName; } public String doFileupload() throws Exception {
if (img != null) { String fileName = img.getName(); String path = ServletActionContext.getServletContext().getRealPath("/imgs"); File destFile = new File(path, imgFileName); FileUtils.copyFile(img, destFile); return SUCCESS; } return INPUT; } }
三 下载
1.下载的关键
下载是从服务器固定目录获取文件,输入流可知,输出路径由用户定义,因此关键是创建输出流。
2.Struts2下载
Struts2采用跳转方式stream创建输出流。
配置文件:
<package name="down" extends="struts-default"> <action name="download" class="com.struts2.download.DownloadAction"> <result type="stream"> <!--指明输入流,以便系统获取 --> <param name="inputName">inputStream</param> <param name="contentDisposition">attachment;filename=${fileName}</param> </result> </action> </package>
java代码:
import java.io.InputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class DownloadAction extends ActionSupport { private static final long serialVersionUID = 1L; private InputStream inputStream; private String fileName; public InputStream getInputStream() {
return inputStream; } public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream; } public String getFileName() {
return fileName; } public void setFileName(String fileName) {
this.fileName = fileName; } public String execute() { fileName = "1.jpg"; inputStream = ServletActionContext.getServletContext().getResourceAsStream("/Files/1.jpg");
return SUCCESS; } }
3.Servlet下载
Servlet提供了ServletOuputStream作为文件下载的输出流。
核心代码:
import java.io.IOException; import java.io.InputStream; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/DownloadServlet") public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * 请求报头与响应报头只支持ISO-8859-1的编码方式,任何出现的报头中的字符都必须能够被ISO-8859-1编码, * 不能的必须先转化为ISO-8859-1编码,比如中文。 */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType("text/html;charset=UTF-8");// 设置响应体中内容的编码方式 /* * 将含有中文的文件名转化为ISO-8859-1编码形式 */ String filenameStr = "图片A"; byte[] bytes = filenameStr.getBytes("UTF-8"); String filename = new String(bytes, "ISO-8859-1");// 设置浏览器以附件形式处理响应 response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".jpg"); InputStream is = getServletContext().getResourceAsStream("/Files/upload.txt");// 以输入流形式获取上传文件 ServletOutputStream os = response.getOutputStream();// 获取向客户端输出的输出流 /* * 输入流与输出流结合,先获取文件内容,再将内容输出 */ int len = -1; byte[] buf = new byte[1024]; while ((len = is.read(buf)) != -1) { os.write(buf); } os.close(); is.close(); } }