JavaEE中文件的下载和文件的上传(--------前后台交互----------)

时间:2022-03-15 16:17:15

文件上传技术与下载技术


介绍service方法中的两个重要参数。

ServletRequest – 用接收用户的请求。它的作用是:
可获取请求头信息。
可设置请请求的字符编码。
可获得用户传递的参数。Post或get。
可获取远程(即访问者)的IP地址。
可获取输入流,如用户上传文件、相片等。
它的一个子接口:javax.servlet.http.HttpServletRequest
ServletResponse – 用于向用户返回数据。
设置响应类型- contentType
设置编码-setCharacterEncoding
获取输出流。

它的一个子接口:javax.servlet.http.HttpServletResponse


文件下载技术:

文件下载技术相当于文件上传技术相对而言比较简单。我们以下载图片为例:
图片都是先浏览再下载

1.前端代码:

	<span style="font-size:14px;"><a href="img">查找文件夹下面的所有图片</a><br/></span>
前台只需要一句话就可以搞定了。直接通过web.xml查找后台的程序

2:后台显示代码:

public class ShowImg extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
doPost(request, response);//为了防止异常,将doGet和doPost连接在一起
	
public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
调出Servletcontext,当然也可以直接调用---当一一列出图片的时候需要文件的绝对路径</span>
ServletContext context =getServletContext();String path=context.getRealPath("/imgs");//找到该文件夹的绝对路径File file =new File(path);
 
  
找到文件夹之后,列出所有图片供用户浏览
		String files[] =file.list();
		for(String fn:files){
//一个个的全部显示出来</span>

String img="<img src='imgs/"+fn+"'/>";

// out.print("<a href=imgs/'"+fn+"'>下载图片</a>");String str="<a href='down?name=imgs/"+fn+"'>下载图片</a>";//提供下载的超链接,传参---传文件名给用户链接内容下面写out.print(str);out.print(img+"<br/>");}}
 
  

3.文件的具体下载

首先必须设置相应的协议。下载协议就需要设置相应的下载头
response.setContentType("application/force-download")</span>;//设置相应头
下载的时候需要显示当前图片的文件名,需要从前台获取,并且从下载获得之后写到前台去
OutputStream out=response.getOutputStream();//获得输出流
			String name=request.getParameter("name");//从客服端传过来的参数名
			int num=name.lastIndexOf("/");
			String aa=name.substring(num+1);
			aa=URLEncoder.encode(aa, "UTF-8");//若是中文需要重新编码
			//System.out.println(aa);  
		<span style="color:#ff0000;">	</span><span style="background-color: rgb(255, 0, 0);">response.setHeader("Content-Disposition",attachment;filename='"+aa+"'");</span>//获取从那边传过来的文件名,以便于存储的时候为下载用户名
进行具体的下载
String filename=this.getServletContext().getRealPath(name);//获得绝对路径,传文件名过来,同时传了可以获得的绝对路径就可以进行读可写了
			InputStream in=new FileInputStream(filename);
			byte[] b=new byte[1024];
			int len=0;
			while((len=in.read(b))!=-1){
				out.write(b, 0, len);
			}
 
·· JavaEE中文件的下载和文件的上传(--------前后台交互----------)
点击之后的效果图:
JavaEE中文件的下载和文件的上传(--------前后台交互----------)
传文件名不一样
JavaEE中文件的下载和文件的上传(--------前后台交互----------)


文件的上传

文件上传要是自己去写会很麻烦,所以我们可以用别人的包。。下载链接点击打开链接

表单:
客户端发送HTTP必须使用multipart/form-data数据类型,表示复合数据类型。
即:<form enctype=“multipart/form-data”>
在表单中使用<input type=“file” name=“somename”/>html标签。
需要的包:
Commons-fileupload.jar,核心上传文件工具都在这个包中。
commons-io.jar – 上传文件所需要的包

JavaEE中文件的下载和文件的上传(--------前后台交互----------)

详解

DiskFileItemFactory-创建监时文件目录,指是缓存区大小
ServletFileUpload用于解析HttpServletRequest。返回一组文件对象。
FileItem – 表示用户上传的每一个文件对像。

主要流程:

File f  = new File("F:/ex/temp");//指定临时文件存放位置
DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//临时文件的大小和存放位置

ServletFileUpload sf =new ServletFileUpload(ff);

       List<FileItem> list=sf.parseRequest(request);//开始解析

for(FileItem it:list){//获得文件名。以及用到uuid解决重名的问题

FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));//写的指定的文件夹中

}

1,前台代码:

<h2>上传文件</h2>
		<form action="UpFile" method="post" <span style="color:#ff0000;">enctype="multipart/form-data">//必须要写,不然后台没办法去接收数据
		<!--  必须添加这个enctype="multipart/form-data"-->
		File1<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/>
		请输入名称:<input type="text" <span style="color:#ff6666;">name</span>="desc"/><br/>
		File2<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/>
		请输入名称:<input type="text"<span style="color:#ff0000;"> name</span>="desc"/><br/>
		<input type="submit" value="提交"/>
		</form>



2,后台代码:

2-1首先创建一个基于硬盘的工厂,用来存放临时文件
		//指定临时存放位置
		File f  = new File("F:/ex/temp");//指定临时文件存放位置
		DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//临时文件的大小和存放位置


2-2 创建一个用ServletFileUpload对象,并且设置文件大小,最大允许传多大的文件

//创建用于解析的对象
		ServletFileUpload sf =new ServletFileUpload(ff);
		sf.setFileSizeMax(1024*1024*10);//仅仅允许单个存放位置最大值是 10M
		sf.setSizeMax(1024*1024*20);//所有文件的最大值是20M
		String path =this.getServletContext().getRealPath("/imgs");
		System.out.println("存储路径:"+path);
2-3,开始解析对象
表单提交必须在前台填写《form aciton="" enctype="multipart/form-data"》;必须要添加这一句
List<FileItem> list=sf.parseRequest(request);//获得从前台传过来的所有信息前台必须填写enctype="multipart/form-data"</span>
			for(FileItem  it:list){
				it0=it;</span>
若是普通表单对象--可以直接判断出
				if(it.isFormField()){//是普通表单项,如 type=text里面name的值
					String name=it.getString("utf-8");
					System.out.println("基本表单项 name:"+name);//下面写的解释的名字
				}else{
// 这就是前台选择的文件名
					String name=it.getName();//具体的文件路径---绝对路径
//					String str=it.getString();//文件里面的内容
//					System.out.println("str"+str);
					String contenttype=it.getContentType();
					Long size=it.getSize();
	System.out.println(name+","+contenttype+","+size);</span>
				</span>在服务器端的资源文件名不能用中文,浏览器会自动编码-------必须要把用户上传的文件名转成没有中文的名字存储,
					//为了让用户在下载时能还原出原来的名字,就要把原文件名和映射名的对应关系存储起来,在用户下载时再转换回来</span>
//映射名String id=UUID.randomUUID().toString().replace("-", "");//全球唯一UUId来进行//文件名String lastname=name.substring(name.lastIndexOf("."));//文件格式//名字文件格式都找到了---组合String filename =id+lastname;//新的文件名//拷贝流。让它写到相应位置FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));//path为存储的绝对路径--之前定义的}
 这样能实现简单的上传,但是,这种上传是没有一点安全行了。完整的代码中附上了防一般的小问题还是没问题的 
JavaEE中文件的下载和文件的上传(--------前后台交互----------)
选择文件之后
JavaEE中文件的下载和文件的上传(--------前后台交互----------)
查看web服务器img里面的文件,文件已经上传到该页面《文件名为uuid生成的文件名》
JavaEE中文件的下载和文件的上传(--------前后台交互----------)

文件上传源代码:

<span style="font-size:14px;">package cn.hncu.UPfile;import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
public class MyupFile extends HttpServlet {
//doGET防止有人在用户栏输入地址。没有响应
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("utf-8");
Writer wr=resp.getWriter();
wr.write("暂不支持该上传方式");
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
//防护 以普通表单上传 法一:
//返回值 GET (null)   POST1(apllication/x-form-urlencoded,普通表单)   POST2(file:multipart/form-data,文件上传表单)
//String type =request.getContentType();
//if(!type.contains("mulitpart/form-data")){
//out.write("不支持普通表单的上传2");
//return ;
//}
// 法二
boolean boo=ServletFileUpload.isMultipartContent(request);
if(boo==false){
out.print("不支持普通表单的上传1");

}

//指定临时存放位置
File f  = new File("F:/ex/temp");//指定临时文件存放位置
DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//临时文件的大小和存放位置

//创建用于解析的对象
ServletFileUpload sf =new ServletFileUpload(ff);
sf.setFileSizeMax(1024*1024*10);//仅仅允许单个存放位置最大值是 10M
sf.setSizeMax(1024*1024*20);//所有文件的最大值是20M
String path =this.getServletContext().getRealPath("/imgs");
System.out.println("存储路径:"+path);
//开始进行解析
FileItem  it0=null;//用于在finally中进行删除临时文件
try {
List<FileItem> list=sf.parseRequest(request);//获得从前台传过来的所有信息,前台必须填写enctype="multipart/form-data"
for(FileItem  it:list){
it0=it;
if(it.isFormField()){//是普通表单项,如 type=text里面name的值
String name=it.getString("utf-8");
System.out.println("基本表单项 name:"+name);//下面写的解释的名字
}else{
String name=it.getName();//具体的文件路径
//<String n1=it.getFieldName();
//String str=it.getString();//文件里面的内容
//System.out.println("str"+str);
//System.out.println("n1:"+n1);
String contenttype=it.getContentType();
Long size=it.getSize();
//防止文件为空
if(size==0){
continue;//文件为空,直接返回;
}
//用户名。必须要填写
if(name==null||name.trim()==""){
continue;
}
//<span style="white-space: pre;">	</span>System.out.println(name+","+contenttype+","+size);
//在服务器端的资源文件名不能用中文,浏览器会自动编码-------必须要把用户上传的文件名转成没有中文的名字存储,
//为了让用户在下载时能还原出原来的名字,就要把原文件名和映射名的对应关系存储起来,在用户下载时再转换回来
//映射名
String id=UUID.randomUUID().toString().replace("-", "");
//文件名
String lastname=name.substring(name.lastIndexOf("."));
//名字文件格式都找到了---组合
String filename =id+lastname;
//拷贝流。让它写到相应位置
FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+file}} catch (FileUploadException e) {
throw new RuntimeException("文件上传解析错误。"+e);
}finally{
if(it0==null){
it0.delete();//删除临时文件
}}out.close();}}

文件下载源代码:

<span style="font-size:14px;">package cn.hncu.downImg;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DownImgDemo extends HttpServlet {

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

	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
			//设置相应头
			response.setContentType("application/force-download");
			//给前台传用户名
			/*传固定的用户名
			String aa="1.jpg";//若是中文,需要编码
			aa=URLEncoder.encode(aa, "UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename='"+aa+"'");////必须要加“attachment;”,否则会变成浏览
			*/
			
			OutputStream out=response.getOutputStream();//获得输出流
			String name=request.getParameter("name");//从客服端传过来的参数名
			int num=name.lastIndexOf("/");
			String aa=name.substring(num+1);
			aa=URLEncoder.encode(aa, "UTF-8");//若是中文需要重新编码
			//System.out.println(aa);  
			response.setHeader("Content-Disposition","attachment;filename='"+aa+"'");//获取从那边传过来的文件名,以便于存储的时候为下载用户名
			
			String filename=this.getServletContext().getRealPath(name);//获得绝对路径
			InputStream in=new FileInputStream(filename);
			byte[] b=new byte[1024];
			int len=0;
			while((len=in.read(b))!=-1){
				out.write(b, 0, len);}}}</span><span style="font-size: 18px;">
</span>