今天我们来学习Servlet文件上传下载

Servlet文件上传主要是使用了ServletInputStream读取流的方法,其读取方法与普通的文件流相同。

一.文件上传相关原理

第一步,构建一个upload.jsp文件

  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
  2. <%
  3. String path = request.getContextPath();
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  5. %>
  6.  
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  8. <html>
  9. <head>
  10. <base href="<%=basePath%>">
  11.  
  12. <title>My JSP 'index.jsp' starting page</title>
  13. <meta http-equiv="pragma" content="no-cache">
  14. <meta http-equiv="cache-control" content="no-cache">
  15. <meta http-equiv="expires" content="0">
  16. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  17. <meta http-equiv="description" content="This is my page">
  18. <!--
  19. <link rel="stylesheet" type="text/css" href="styles.css">
  20. -->
  21. </head>
  22. <body>
  23. <form enctype="application/x-www-form-urlencoded" action="${pageContext.request.contextPath }/servlet/UploadServlet1" method="post">
  24. <input type="text" name="name" value="name" /><br/>
  25. <div id="div1">
  26. <div>
  27. <input type="file" name="photo" />
  28. </div>
  29. </div>
  30. <input type="submit" name="上传" /><br/>
  31. </form>
  32. </body>
  33. </html>

第二步,构建一个servlet UploadServlet1.java

  1. package com.zk.upload;
  2.  
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5.  
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletInputStream;
  8. import javax.servlet.http.HttpServlet;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11.  
  12. public class UploadServlet1 extends HttpServlet {
  13. public void doGet(HttpServletRequest request, HttpServletResponse response)
  14. throws ServletException, IOException {
  15. String name=request.getParameter("name");
  16. String photo=request.getParameter("photo");
  17.  
  18. ServletInputStream inputstream=request.getInputStream();
  19. int len=0;
  20. byte[] b=new byte[1024];
  21. while((len=inputstream.read(b))!=-1){
  22. System.out.println(new String(b,0,len));
  23. }
  24. inputstream.close();
  25. }
  26. public void doPost(HttpServletRequest request, HttpServletResponse response)
  27. throws ServletException, IOException {
  28. ServletInputStream inputstream=request.getInputStream();
  29. int len=0;
  30. byte[] b=new byte[1024];
  31. while((len=inputstream.read(b))!=-1){
  32. System.out.println(new String(b,0,len));
  33. }
  34. inputstream.close();
  35. }
  36.  
  37. /**
  38. * Initialization of the servlet. <br>
  39. *
  40. * @throws ServletException if an error occurs
  41. */
  42. public void init() throws ServletException {
  43. // Put your code here
  44. }
  45.  
  46. }

最后执行UploadServlet1.java之后,输出上传文件的信息。

这里涉及到文件上传的相关原理,在我本地浏览器中调试显示信息如下:

这是一些有关文件上传的相关信息。

二.文件上传

接下来,我们开始进行文件上传的工作。

第一部,创建jsp

这里的form表单需要更改一下enctype属性,这个属性是规定在发送到服务器之前应该如何对表单数据进行编码。

  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
  2. <%
  3. String path = request.getContextPath();
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  5. %>
  6.  
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  8. <html>
  9. <head>
  10. <base href="<%=basePath%>">
  11.  
  12. <title>My JSP 'index.jsp' starting page</title>
  13. <meta http-equiv="pragma" content="no-cache">
  14. <meta http-equiv="cache-control" content="no-cache">
  15. <meta http-equiv="expires" content="0">
  16. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  17. <meta http-equiv="description" content="This is my page">
  18. </head>
  19. <body>
  20. <form enctype="multipart/form-data" action="${pageContext.request.contextPath }/servlet/UploadServlet2" method="post">
  21. <input type="text" name="name" value="name" /><br/>
  22. <div id="div1">
  23. <div>
  24. <input type="file" name="photo" />
  25. </div>
  26. </div>
  27. <input type="submit" name="上传" /><br/>
  28. </form>
  29. </body>
  30. </html>

  UploadServlet2.java

  1. package com.zk.upload;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.PrintWriter;
  8. import java.io.UnsupportedEncodingException;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. import java.util.List;
  12. import java.util.UUID;
  13.  
  14. import javax.servlet.ServletException;
  15. import javax.servlet.http.HttpServlet;
  16. import javax.servlet.http.HttpServletRequest;
  17. import javax.servlet.http.HttpServletResponse;
  18.  
  19. import org.apache.commons.fileupload.FileItem;
  20. import org.apache.commons.fileupload.FileUploadBase;
  21. import org.apache.commons.fileupload.FileUploadException;
  22. import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  23. import org.apache.commons.fileupload.servlet.ServletFileUpload;
  24. import org.apache.commons.io.FilenameUtils;
  25.  
  26. public class UploadServlet2 extends HttpServlet {
  27.  
  28. /**
  29. * Constructor of the object.
  30. */
  31. public UploadServlet2() {
  32. super();
  33. }
  34.  
  35. /**
  36. * Destruction of the servlet. <br>
  37. */
  38. public void destroy() {
  39. super.destroy(); // Just puts "destroy" string in log
  40. // Put your code here
  41. }
  42.  
  43. /**
  44. * The doGet method of the servlet. <br>
  45. *
  46. * This method is called when a form has its tag value method equals to get.
  47. *
  48. * @param request the request send by the client to the server
  49. * @param response the response send by the server to the client
  50. * @throws ServletException if an error occurred
  51. * @throws IOException if an error occurred
  52. */
  53. public void doGet(HttpServletRequest request, HttpServletResponse response)
  54. throws ServletException, IOException {
  55. //优先级不高
  56. request.setCharacterEncoding("UTF-8");
  57.  
  58. //要执行文件上传的操作
  59. //判断表单是否支持文件上传
  60. boolean isMultipartContent=ServletFileUpload.isMultipartContent(request);
  61. if(!isMultipartContent){
  62. throw new RuntimeException("your form is not multipart/form-data");
  63. }
  64. //创建一个DiskFileItemFactory工厂类
  65. DiskFileItemFactory factory=new DiskFileItemFactory();
  66. //创建一个ServletFileUpload核心对象
  67. ServletFileUpload sfu=new ServletFileUpload(factory);
  68. //解决上传表单乱码的问题
  69. sfu.setHeaderEncoding("UTF-8");
  70. try {
  71. //限制上传文件的大小
  72. //sfu.setFileSizeMax(1024);
  73. //sfu.setSizeMax(6*1024*1024);
  74. //解析requst对象,得到一个表单项的集合
  75. List<FileItem> fileitems=sfu.parseRequest(request);
  76. //遍历表单项数据
  77. for(FileItem fileItem:fileitems){
  78. if(fileItem.isFormField()){
  79. //普通表单项
  80. processFormField(fileItem);
  81. }
  82. else{
  83. //上传表单项
  84. processUploadField(fileItem);
  85. }
  86. }
  87. } catch(FileUploadBase.FileSizeLimitExceededException e){
  88. throw new RuntimeException("文件过大");
  89. }catch (FileUploadException e) {
  90. // TODO Auto-generated catch block
  91. e.printStackTrace();
  92. }
  93. }
  94. private void processUploadField(FileItem fileItem) {
  95. // TODO Auto-generated method stub
  96. //得到上传的名字
  97. String filename=fileItem.getName();
  98. //得到文件流
  99. try {
  100. InputStream is=fileItem.getInputStream();
  101. String dictory=this.getServletContext().getRealPath("/upload");
  102. System.out.println(dictory);
  103. //创建一个存盘的路径
  104. File storeDirecctory=new File(dictory);//既代表文件又代表目录
  105. if(!storeDirecctory.exists()){
  106. storeDirecctory.mkdirs();//创建一个指定目录
  107. }
  108. //处理文件名
  109. filename=filename.substring(filename.lastIndexOf(File.separator)+1);
  110. if(filename!=null){
  111. filename=FilenameUtils.getName(filename);
  112. }
  113. //解决文件同名的问题
  114. filename=UUID.randomUUID()+"_"+filename;
  115.  
  116. //目录打散
  117. //String childDirectory=makeChildDirectory(storeDictory);//2015-10-
  118. String childDirectory=makeChildDirectory2(storeDirecctory,filename);
  119. //System.out.println(childDirectory);
  120. //上传文件,自动删除临时文件
  121. fileItem.write(new File(storeDirecctory,childDirectory+File.separator+filename));
  122.  
  123. } catch (IOException e) {
  124. // TODO Auto-generated catch block
  125. e.printStackTrace();
  126. } catch (Exception e) {
  127. // TODO Auto-generated catch block
  128. e.printStackTrace();
  129. }
  130.  
  131. }
  132.  
  133. //上传表单项
  134. private void processUploadField1(FileItem fileItem) {
  135. // TODO Auto-generated method stub
  136.  
  137. //得到上传的名字
  138. String filename=fileItem.getName();
  139. //得到文件流
  140. try {
  141. //得到文件流
  142. InputStream is=fileItem.getInputStream();
  143.  
  144. String dictory=this.getServletContext().getRealPath("/upload");
  145. System.out.println(dictory);
  146. //创建一个存盘的路径
  147. File storeDictory=new File(dictory);//既代表文件又代表目录
  148. if(!storeDictory.exists()){
  149. storeDictory.mkdirs();//创建一个指定目录
  150. }
  151. //处理文件名
  152. filename=filename.substring(filename.lastIndexOf(File.separator)+1);
  153. if(filename!=null){
  154. filename=FilenameUtils.getName(filename);
  155. }
  156. //解决文件同名的问题
  157. filename=UUID.randomUUID()+"_"+filename;
  158.  
  159. //目录打散
  160. //String childDirectory=makeChildDirectory(storeDictory);//2015-10-
  161. String childDirectory2=makeChildDirectory2(storeDictory,filename);
  162. //System.out.println(childDirectory);
  163. //在storeDictory目录下创建完整的文件
  164. //File file=new File(storeDictory,filename);
  165. //File file=new File(storeDictory,childDirectory+File.separator+filename);
  166. File file2=new File(storeDictory,childDirectory2+File.separator+filename);
  167.  
  168. //通过文件输出流将上传的文件保存到磁盘
  169. //FileOutputStream fos=new FileOutputStream(file);
  170. FileOutputStream fos2=new FileOutputStream(file2);
  171.  
  172. int len=0;
  173. byte[] b=new byte[1024];
  174. while((len=is.read(b))!=-1){
  175. // fos.write(b,0,len);
  176. fos2.write(b,0,len);
  177. }
  178. //fos.close();
  179. fos2.close();
  180. is.close();
  181. System.out.println("success");
  182. //删除临时文件
  183. fileItem.delete();
  184. } catch (IOException e) {
  185. // TODO Auto-generated catch block
  186. e.printStackTrace();
  187. }
  188.  
  189. }
  190. //目录打散
  191. private String makeChildDirectory(File storeDictory) {
  192. // TODO Auto-generated method stub
  193. SimpleDateFormat sm=new SimpleDateFormat("yyyy-MM-dd");
  194. String date=sm.format(new Date());
  195. //创建目录
  196. File file=new File(storeDictory,date);
  197. if(!file.exists()){
  198. file.mkdirs();
  199. }
  200. return date;
  201. }
  202. //目录打散
  203. private String makeChildDirectory2(File storeDictory,String filename){
  204. int hashcode=filename.hashCode();
  205. System.out.println(hashcode);
  206. String code=Integer.toHexString(hashcode);
  207. String childDirectory=code.charAt(0)+File.separator+code.charAt(1);
  208. //创建指定目录
  209. File file=new File(storeDictory,childDirectory);
  210. if(!file.exists()){
  211. file.mkdirs();
  212. }
  213. return childDirectory;
  214. }
  215. //普通表单项
  216. private void processFormField(FileItem fileItem) {
  217. // TODO Auto-generated method stub
  218. String fieldname=fileItem.getFieldName();
  219.  
  220. try {
  221. String valuename=fileItem.getString("UTF-8");
  222. // fieldname=new String(valuename.getBytes("iso-8859-1"),"utf-8");
  223. System.out.println(fieldname+":"+valuename);
  224. } catch (UnsupportedEncodingException e) {
  225. // TODO Auto-generated catch block
  226. e.printStackTrace();
  227. }
  228.  
  229. }
  230.  
  231. /**
  232. * The doPost method of the servlet. <br>
  233. *
  234. * This method is called when a form has its tag value method equals to post.
  235. *
  236. * @param request the request send by the client to the server
  237. * @param response the response send by the server to the client
  238. * @throws ServletException if an error occurred
  239. * @throws IOException if an error occurred
  240. */
  241. public void doPost(HttpServletRequest request, HttpServletResponse response)
  242. throws ServletException, IOException {
  243. request.setCharacterEncoding("UTF-8");
  244. //要执行文件上传的操作
  245. //判断表单是否支持文件上传
  246. boolean isMultipartContent=ServletFileUpload.isMultipartContent(request);
  247. if(!isMultipartContent){
  248. throw new RuntimeException("your form is not multipart/form-data");
  249. }
  250. //创建一个DiskFileItemFactory工厂类
  251. DiskFileItemFactory factory=new DiskFileItemFactory();
  252. //产生临时文件
  253. factory.setRepository(new File("f:\\temp"));
  254. //创建一个ServletFileUpload核心对象
  255. ServletFileUpload sfu=new ServletFileUpload(factory);
  256. sfu.setHeaderEncoding("UTF-8");
  257. try {
  258. //限制上传文件的大小
  259. //sfu.setFileSizeMax(1024*1024*1024);
  260. //sfu.setSizeMax(6*1024*1024);
  261. //解析requst对象,得到一个表单项的集合
  262. List<FileItem> fileitems=sfu.parseRequest(request);
  263. //遍历表单项数据
  264. for(FileItem fileItem:fileitems){
  265. if(fileItem.isFormField()){
  266. //普通表单项
  267. processFormField(fileItem);
  268. }
  269. else{
  270. //上传表单项
  271. processUploadField(fileItem);
  272. }
  273. }
  274. } catch(FileUploadBase.FileSizeLimitExceededException e){
  275. //throw new RuntimeException("文件过大");
  276. System.out.println("文件过大");
  277. }catch (FileUploadException e) {
  278. // TODO Auto-generated catch block
  279. e.printStackTrace();
  280. }
  281. }
  282.  
  283. /**
  284. * Initialization of the servlet. <br>
  285. *
  286. * @throws ServletException if an error occurs
  287. */
  288. public void init() throws ServletException {
  289. // Put your code here
  290. }
  291.  
  292. }

 这里面加了文件大小限制、文件重命名、目录打散等方法。

最后,我们运行一下这个demo

我们在web-apps的目录下可以看到我们刚刚上传的文件

三.文件下载

现在我们进行文件下载

  1. package com.zk.upload;
  2.  
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. import java.net.URLEncoder;
  7.  
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletOutputStream;
  10. import javax.servlet.http.HttpServlet;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13.  
  14. public class DownloadServlet1 extends HttpServlet {
  15.  
  16. /**
  17. * Constructor of the object.
  18. */
  19. public DownloadServlet1() {
  20. super();
  21. }
  22.  
  23. /**
  24. * Destruction of the servlet. <br>
  25. */
  26. public void destroy() {
  27. super.destroy(); // Just puts "destroy" string in log
  28. // Put your code here
  29. }
  30.  
  31. /**
  32. * The doGet method of the servlet. <br>
  33. *
  34. * This method is called when a form has its tag value method equals to get.
  35. *
  36. * @param request the request send by the client to the server
  37. * @param response the response send by the server to the client
  38. * @throws ServletException if an error occurred
  39. * @throws IOException if an error occurred
  40. */
  41. public void doGet(HttpServletRequest request, HttpServletResponse response)
  42. throws ServletException, IOException {
  43. //设置一个要下载的文件
  44. String filename="a.csv";
  45. filename=new String(filename.getBytes("UTF-8"),"iso-8859-1");
  46. //告知浏览器要下载文件
  47. response.setHeader("content-disposition", "attachment;filename="+filename);
  48. response.setContentType(this.getServletContext().getMimeType(filename));//根据文件明自动获取文件类型
  49. response.setCharacterEncoding("UTF-8");//告知文件用什么服务器编码
  50.  
  51. PrintWriter pw=response.getWriter();
  52. pw.write("Hello,world");
  53.  
  54. }
  55.  
  56. /**
  57. * The doPost method of the servlet. <br>
  58. *
  59. * This method is called when a form has its tag value method equals to post.
  60. *
  61. * @param request the request send by the client to the server
  62. * @param response the response send by the server to the client
  63. * @throws ServletException if an error occurred
  64. * @throws IOException if an error occurred
  65. */
  66. public void doPost(HttpServletRequest request, HttpServletResponse response)
  67. throws ServletException, IOException {
  68. doGet(request,response);
  69. }
  70.  
  71. /**
  72. * Initialization of the servlet. <br>
  73. *
  74. * @throws ServletException if an error occurs
  75. */
  76. public void init() throws ServletException {
  77. // Put your code here
  78. }
  79.  
  80. }

  首先指定一个需要下载的文件的文件名,然后告知浏览器需要下载文件,根据文件明自动获取文件类型,并告知文件用什么服务器编码。执行servlet后,会下载一个名为

a.csv的文件。

下载后,可以看到文件中存有Hello,world字符。

Servlet文件上传下载的更多相关文章

  1. java中的文件上传下载

    java中文件上传下载原理 学习内容 文件上传下载原理 底层代码实现文件上传下载 SmartUpload组件 Struts2实现文件上传下载 富文本编辑器文件上传下载 扩展及延伸 学习本门课程需要掌握 ...

  2. jsp+servlet实现文件上传下载

    相关素材下载 01.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  3. SpringMVC文件上传下载

    在Spring MVC的基础框架搭建起来后,我们测试了spring mvc中的返回值类型,如果你还没有搭建好springmvc的架构请参考博文->http://www.cnblogs.com/q ...

  4. salesforce 零基础学习(四十二)简单文件上传下载

    项目中,常常需要用到文件的上传和下载,上传和下载功能实际上是对Document对象进行insert和查询操作.本篇演示简单的文件上传和下载,理论上文件上传后应该将ID作为操作表的字段存储,这里只演示文 ...

  5. commons-fileupload实现文件上传下载

    commons-fileupload是Apache提供的一个实现文件上传下载的简单,有效途径,需要commons-io包的支持,本文是一个简单的示例 上传页面,注意设置响应头 <body> ...

  6. JavaWeb实现文件上传下载功能实例解析

    转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...

  7. JAVA Web 之 struts2文件上传下载演示(一)(转)

    JAVA Web 之 struts2文件上传下载演示(一) 一.文件上传演示 1.需要的jar包 大多数的jar包都是struts里面的,大家把jar包直接复制到WebContent/WEB-INF/ ...

  8. java web 文件上传下载

    文件上传下载案例: 首先是此案例工程的目录结构:

  9. 2013第38周日Java文件上传下载收集思考

    2013第38周日Java文件上传&下载收集思考 感觉文件上传及下载操作很常用,之前简单搜集过一些东西,没有及时学习总结,现在基本没啥印象了,今天就再次学习下,记录下自己目前知识背景下对该类问 ...

随机推荐

  1. PAT (Basic Level) Practice (中文)1043 输出PATest (20 分)

    给定一个长度不超过 1 的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符已经输 ...

  2. Cloudera Manager和CDH版本的对应关系

    来源:https://www.cloudera.com/documentation/enterprise/release-notes/topics/rn_consolidated_pcm.html#c ...

  3. ArcMap 导入自定义样式Symbols

    管网的图例里有一些自定义的样式,这些在ArcMap中找不到,找到的也不合适,所以只能自己动手制作. 1. 菜单 Customize --> Style Manager 2 . 创建新的Style ...

  4. linux C++ 读取mysql结果保存

    c++读取mysql数据库结果保存 #include <fstream> #include <iomanip> #include <iostream> #inclu ...

  5. Ubuntu18.04安装mysql(AWS云)

    1.执行如下三条命令 sudo apt-get install mysql-server sudo apt install mysql-client sudo apt install libmysql ...

  6. Oracle 中关于 Group By 子句与多行函数嵌套搭配使用的注意事项

    目录 你需要知道的 啥叫单行函数 啥叫多行函数 如何理解这个概念 Group by 子句使用规则 看一道 071 考题 你需要知道的 提到 Group by 子句,你需要先理解一个东西:函数的分类.提 ...

  7. Dubbo的SPI机制与JDK机制的不同及原理分析

    从今天开始,将会逐步介绍关于DUbbo的有关知识.首先先简单介绍一下DUbbo的整体概述. 概述 Dubbo是SOA(面向服务架构)服务治理方案的核心框架.用于分布式调用,其重点在于分布式的治理. 简 ...

  8. php文件上传 form表单形式

    1.php界面 <?php header( 'Content-Type:text/html;charset=utf-8 ');include_once("conn/conn.php&q ...

  9. [CF1034A] Two Rabbits - 数学

    判断能否整除即可 #include <bits/stdc++.h> using namespace std; int x,y,a,b; int main() { int t; ios::s ...

  10. Spring域属性自动注入byName和byType

    byName 方式 <!--byName约束:bean当中的域属性名必须跟所注入bean的id相同--> <bean id="student" class=&qu ...