JavaWeb文件上传与下载

一.文件上传

1. 引入两个jar包

jar包可以在maven库进行下载,地址:https://mvnrepository.com,一般点击下载量最多的jar进行下载就可以了。

  • apache:commons-fileupload.jar
  • commons-fileupload.jar这个jar包是依赖commons-io.jar的

2. 代码

前端代码:表单请求方式必须为post,属性为 enctype="multipart/form-data"才能上传文件。

<form action="后端上传接受地址" method="post" enctype="multipart/form-data">
	<input type="file" name="picture"/>
</form>

后端代码:

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");
    //上传
    try {
        //判断form表单是否是mutipart格式
        boolean isMultipart=ServletFileUpload.isMultipartContent(request);
        if(isMultipart) {
            //判断前台的form是否有mutipart属性
            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            //通过parseRequest解析form中的所有请求字段,并保存到items集合中,(即前台传递的sname,sno,spiture就保存到items里面了)
            List<FileItem> items = upload.parseRequest(request);
            //遍历items中的数据(sno,sname,spicture)
            Iterator<FileItem> iter=items.iterator();
            while(iter.hasNext()) {
                FileItem item = iter.next();
                //getFieldName获取普通表单字段
                String itemName = item.getFieldName();
                int sno = -1;
                String sname = null;
                //判断前台字段是普通form表单字段(sname,sno),还是文件字段
                if(item.isFormField()) {
                    if(itemName.equals("sno")) {
                        sno = Integer.parseInt(item.getString("UTF-8"));
                    }else if(itemName.equals("sname")) {
                        sname = item.getString("UTF-8");
                    }else {
                        System.out.println("其他普通表单字段……");
                    }
                }else {//文件字段
	                //getName()是获取文件名, //a.txt a.docx a.png
	                String fileName = item.getName();
	                //防止文件重名覆盖,添加一个文件前缀
                	String prefix = UUID.randomUUID().toString().replaceAll("-", "").replaceAll(".", "");
                	fileName = prefix + fileName;
               
                    //获取文件内容并上传
                    //定义文件路径:指定上传的文件位置(服务器路径)
                    //动态获取服务器路径
                    String path = request.getSession().getServletContext().getRealPath("static/upload");
                    File file = new File(path,fileName);
                    item.write(file); //将文件上传到指定位置
                    System.out.println(fileName+"上传成功!");
                    return;

                }
            }
        }

    }catch(FileUploadException e) {
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

注意问题:
String path = request.getSession().getServletContext().getRealPath("static/upload");通过这种方式指定文件的上传路径,文件只会上传到war包中,容易误删,但指定本机地址,如D:\bookimg,img访问不了。所以就还是第一种方式将文件存放到war包中,即服务器上就好了。项目重新运行会重新编译一次,按道理war包中之前上传的资源是会被清除的,但我测试后发现文件还是存在,但这是好事,这就不用担心文件被清空了。重启是我们手动的行为,如果是重要的文件怕被清空,可以先保存下来到项目中相同的文件路径下再启动即可。如path指定的路径为static/upload,在重启先可以将war包下的static/upload文件复制一份到源码中,即使重新编译也会携带上这些文件。这就比较稳妥了。

二、文件下载

不需要依赖任何jar

  1. 直接通过<img/>标签就可以请求到服务器中的图片资源了。
  2. 如果是文件则通过输出流的形式将文件输出给用户
    注意: 文件需要设置响应头,如果是任意类型则通过附件形式指定文件类型,两个响应头都要设置。如果content-Type指定了具体的响应类型,并且直接在浏览器中显示,则不需要设置content-Disposition
 //MIME类型,表示二进制文件,任意类型都可以
response.addHeader("content-Type","application/octet-stream"); 
//attachement表示以附件的方式下载文件
response.addHeader("content-Disposition","attachement;filename="+fileName);
文件类型Content-Type
二进制文件(任何类型的文件)application/octet-stream
Wordapplication/msword
Excelapplication/vnd.ms-excel
PPTapplication/vnd.ms-powerpoint
图片image/gif, image/bmp, image/jpeg
文本文件text/plain
html网页text/html

代码

public class DownLoadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
	    //获取需要下载的文件名
	    String fileName = request.getParameter("filename"); //from表单和a标签参数的获取都用getParameter
	    //下载文件:需要设置消息头
	    response.addHeader("content-Type","application/octet-stream");//MIME类型,这里为二进制文件(任意文件类型都可)
	    response.addHeader("content-Disposition","attachement;filename="+fileName); //attachement为附件,以附件方式获取要下载的文件,filename指定具体文件,包含了文件后缀:abc.txt
	    //Servlet通过文件的地址,将文件转为输入流,读到Servlet中
	    InputStream in = getServletContext().getResourceAsStream("upload/"+fileName);
	    //通过输出流将刚才已经转为输入流的文件输出给用户
	    ServletOutputStream out = response.getOutputStream();
	    byte[] bs = new byte[10];
	    int len = -1;
	    while((len=in.read(bs))!= -1){
	        out.write(bs,0,len);
	    }
	    out.close();
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值