JavaWeb之文件上传和下载

基础不牢固,地动山摇!
最近做项目上传文件出现很多bug,回来看视频学习
文件上传:
使用的jar包,apache:commons-fileupload,他又依赖于commons-io.jar包,需要将两个jar包引入。
前台jsp:
后台Servlet:
<input type="file" name="picture"/>
注意:表单提交方式必须是post,因为文件是特别的大,地址栏会放不下,它只能存放大概4K的数据。在表单中必须增加一个属性enctype="multipart/form-data"
注意的问题:
上传目录 upload
1.如果修改代码则在tomcat启动时,会被删除
原因:当修改代码的时候,tomcat会重新编译一份class,并重新部署(重重新创建各种目录)
2.如果不改代码,则不会删除
原因:没有修改代码,class仍然是之前的class
因此为了防止上传目录丢失:a.虚拟路径 ,b.更换上传目录到非tomcat目录.
限制上传:
类型,大小。
具体代码如下:
(1)上传Servlet:

public class UploadServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html; charset=UTF-8");
		// 上传
		// request.getParameter("sname")
		try {
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			if (isMultipart) {// 判断前台的form是否有 mutipart属性
//				FileItemFactory factory = new DiskFileItemFactory();
				DiskFileItemFactory factory = new DiskFileItemFactory();
				
				ServletFileUpload upload = new ServletFileUpload(factory);
				
				//设置上传文件时用到的临时文件大小,factory(因为上传文件是先一点点上传到缓冲区,然后再放文件)
				factory.setSizeThreshold(50000);//设置临时的缓存文件是
				factory.setRepository(new File("D:\\study\\uploadtemp"));//设置临时文件的位置
				//控制上传文件的大小~KB upload
				upload.setSizeMax(100000);//单位是字节B
				Thread.sleep(3000); 
				
				
				// 通过parseRequest解析form中的所有请求字段,并保存到 items集合中(即前台传递的sno sname
				// spicture此时就保存在了items中)
				List<FileItem> items = upload.parseRequest(request);
				// 遍历items中的数据(item=sno sname spicture)
				Iterator<FileItem> iter = items.iterator();
				while (iter.hasNext()) {
					FileItem item = iter.next();
					String itemName = item.getFieldName();
					int sno = -1;
					String sname = null;
					// 判断前台字段 是普通form表单字段(sno sname),还是文件字段

					// request.getParameter() -- iter.getString()
					if (item.isFormField()) {
						if (itemName.equals("sno")) {// 根据name属性 判断item是sno sname 还是spicture?
							sno = Integer.parseInt(item.getString("UTF-8"));
						} else if (itemName.equals("sname")) {
							sname = item.getString("UTF-8");
						} else {
							System.out.println("其他字段xxx.....");
						}
					} else {// picture 
							// 文件 上传
							// 文件名 getFieldName是获取 普通表单字段的Name值
							// getName()是获取 文件名
						String fileName = item.getName();//a.txt   a.docx   a.png
						String ext = fileName.substring(fileName.indexOf(".")+1 );
						if(!(ext.equals("png") ||ext.equals("gif")||ext.equals("jpg"))){
							System.out.println("图片类型有误,格式只能是");
							return; //终止
						}
						
						// 获取文件内容 并上传
						// 定义文件路径:指定上传的位置(服务器路径)
						// 获取服务器路径D:\\study\\apache-tomcat-8.5.30\\wtpwebapps\\UpAndDown\\upload
//						String path =request.getSession().getServletContext().getRealPath("upload");
						String path = "D:\\study\\upload";
						File file = new File(path, fileName);
			
						
						item.write(file);// 上传
						System.out.println(fileName + "上传成功!");
						return;
					}
				}

			}

		}
		catch (FileUploadBase.SizeLimitExceededException e) {//SizeLimitExceededException是FileUploadException的一个子类
			System.out.println("上传文件大小超过限制");
		}
		catch (FileUploadException e) 
		{
			e.printStackTrace();
			
		}
		
		// 解析请求
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

JSP表单:

<body>
        <form action="UploadServlet" method="post" enctype="multipart/form-data">
                   学号:<input type="sno"/><br/>
                   姓名:<input type="sname"/><br/>
                  上传照片:<input type="file" name="picture"/><br/>
                  <input type="submit" value="注册"/>
        </form>
        <a href="DownLoadServlet?filename=酷酷.jpg">酷酷</a>
</body>

文件的下载:
下载不需要任何的jar包,
a.前端发一个请求(地址a form),请求Servlet ,
b.Servlet 通过文件的地址,将文件转为输入流,读到Servlet 中,
c.通过输入流 将已经转为输入流的文件,输出给用户
注意:下载文件需要设置两个 响应头

response.addHeader("content-Type", "application/octe-stream");//任意二进制文件类型
response.addHeader("content-Disposition", "attachement;fileName="+fileName);//fileName包含了文件后缀

下载时可能会出现文件名乱码:
IE、360谷歌等浏览器设置方式:

response.addHeader("content-Disposition", "attachment;fileName="+URLEncoder.encode(fileName,"UTF-8"));

火狐浏览器比较复杂,首先要给文件名加上前缀和后缀
前缀:=?UTF-8?B?
外层String构造方法
中间:Base64.encode
后缀:?=
如下:

response.addHeader("content-Disposition", "attachment;fileName=?UTF-8?B?"+new String( Base64.encodeBase64(fileName.getBytes("UTF-8")))+"?=" );

具体下载代码如下:

public class DownLoadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		
		//获取需要下载的文件名
		String fileName =request.getParameter("filename");
		
		//对于不同浏览器,进行不同的处理
		//获取客户端的User-Agent:信息
		String agent = request.getHeader("User-Agent");
		if(agent.toLowerCase().indexOf("firefox")!= -1){
			//火狐谷歌等
			response.addHeader("content-Disposition", "attachment;fileName=?UTF-8?B?"+new String( Base64.encodeBase64(fileName.getBytes("UTF-8")))+"?=" );
		}else{
			//IEx下载文件名乱码问题
			response.addHeader("content-Disposition", "attachment;fileName="+URLEncoder.encode(fileName,"UTF-8"));//fileName包含了文件后缀
			
		}

		//下载文件需要设置响应消息头
		response.addHeader("content-Type", "application/octe-stream");//任意二进制文件类型
		
		
		//Servlet 通过文件的地址,将文件转为输入流,读到Servlet 中,
		InputStream in = getServletContext().getResourceAsStream("/res/"+fileName);
		
		//通过输入流 将已经转为输入流的文件,输出给用户
		ServletOutputStream out = response.getOutputStream();
		byte[] bs = new byte[1024]; //不断向缓冲区里面放
		int len = -1;
		while((len=in.read(bs)) != -1){
			out.write(bs,0,len);
		}
		out.close();
		in.close();
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值