系统运维系列 之实现servlet上传下载文件(java应用)

本文探讨了在Spring MVC中如何实现文件上传与下载,包括代码实例和常见问题如request为null的排查方法,重点提到了structs2过滤器配置的影响。同时,提供了Postman模拟文件操作的方法。

1 前言
本篇博客列举了几种常用的文件上传与下载的代码实现方式和postman的模拟方式,列举了当遇到request为null的排查方法,其中在代码逻辑上没有问题的情况下,一般文件相关的request为空,需要排查structs2过滤器的配置。

2 文件上传
添加依赖:以下方法不仅仅需要这两个jar包,如有需要可自行添加依赖,本部分只提供几种文件上传的方式。

<dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
       <version>2.4</version>
</dependency>
<dependency>
       <groupId>commons-fileupload</groupId>
       <artifactId>commons-fileupload</artifactId>
       <version>1.3.1</version>
</dependency>

实现方法1:
使用IOUtils.copy

public void uploadFile() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		request.setCharacterEncoding("UTF-8");
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		String result = "";
        DiskFileItemFactory factory=new DiskFileItemFactory();//1.创建DiskFileItemFactory工厂类
        ServletFileUpload upload=new ServletFileUpload(factory);//2.创建解析类,用于解析resquest
        try {
            List<FileItem> list = upload.parseRequest(request);//3.解析内容,获取一个list,数据都存储在list中
            System.out.println(list.size());
            for(FileItem item:list) {
                if(item.isFormField()) {//判断是否是普通的表单内容
                    System.out.println(item.getFieldName());//获取的是表单中name属性的值
                    System.out.println(item.getString());//获取的是对应的表单的值
                }else {//为假,说明是上传项
                    //获取流,进行处理
                    InputStream ism = item.getInputStream();
                    Date date = new Date();//时间戳
                    SimpleDateFormat df1 = new SimpleDateFormat("yyyyMMddHHmmss");
                    String rootPath = request.getServletContext().getRealPath("/");
                    String path = "static/test/";
                    String fileName = "test"+df1.format(date) + ".txt";
                    System.out.println(path);
                    String filename = item.getName();//这里getName可以获取文件名
                    System.out.println(filename);
                    File file=new File(rootPath+path+fileName);
                    file.createNewFile();//这里不做文件存在性和名字重复判断
                    OutputStream fos = new FileOutputStream(file);
                    //这里直接借助commons.io来做io对接,不然需要做流的读取和写入
                    IOUtils.copy(ism,fos);//把输入流的数据拷贝到输出流
                    IOUtils.closeQuietly(ism);
                    IOUtils.closeQuietly(fos);
                }
            }
        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  
    }

实现方法2:
使用FileUtils.copyFile

public <V> void uploadFile() throws IOException {
		HttpServletRequest request = ServletActionContext.getRequest();
		request.setCharacterEncoding("UTF-8");
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		String result = "";
		String realPath = request.getSession().getServletContext().getRealPath("/");
		FileUtils.copyFile(upload, new File(realPath + "static/test/", uploadFileName));
		Map<String, V> resp = new HashMap<String, V>();
		resp.put("status", (V) new Integer(200));
		resp.put("message", (V) "OK");
		JSONObject jsonObject = JSONObject.fromObject(resp);
		result = jsonObject.toString();
		out.print(result);
	}

实现方法3:
使用file.transferTo

public String uploadFile (HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpServletRequest request = ServletActionContext.getRequest();
		request.setCharacterEncoding("UTF-8");
		//CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		String result = "";
		StandardMultipartHttpServletRequest multipartRequest =  new StandardMultipartHttpServletRequest(request,false);
        MultipartFile file = multipartRequest.getFile("fileName");
        if (file.getOriginalFilename().equals("")) {
        	Map<String, V> resp = new HashMap<String, V>();
    		resp.put("status", (V) new Integer(500));
    		resp.put("message", (V) "请选择一个文件");
    		JSONObject jsonObject = JSONObject.fromObject(resp);
    		result = jsonObject.toString();
    		out.print(result);
        }
        if (!suffix.equals("csv")) {
        	Map<String, V> resp = new HashMap<String, V>();
    		resp.put("status", (V) new Integer(500));
    		resp.put("message", (V) "文件类型不符");
    		JSONObject jsonObject = JSONObject.fromObject(resp);
    		result = jsonObject.toString();
    		out.print(result);
        }
        double fileSize = (file.getSize() / 1024) / 1024;
        if (fileSize > 10) {
        	Map<String, V> resp = new HashMap<String, V>();
    		resp.put("status", (V) new Integer(500));
    		resp.put("message", (V) "请上传小于10MB的文件");
    		JSONObject jsonObject = JSONObject.fromObject(resp);
    		result = jsonObject.toString();
    		out.print(result);
        }
        System.out.println("文件大小:" + (file.getSize() / 1024) / 1024 + "MB");
        Date date = new Date();//时间戳
        SimpleDateFormat df1 = new SimpleDateFormat("yyyyMMHHmmss");
        //SimpleDateFormat df2 = new SimpleDateFormat("yyyyMM");
        //String rootPath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        String rootPath = multipartRequest.getSession().getServletContext().getRealPath("/");
        String path = "static/mmllist/";
        String fileName = "test"+df1.format(date) + suffix;
        //创建要保存文件的路径
        File dirFile = new File(rootPath + path, fileName);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
        file.transferTo(dirFile);
   }

2 文件下载:

public void downloadFile(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1.获取下载目标
        String filename = request.getParameter("target");
        System.out.println(filename);
        // 2.找到下载目标
        String path = getServletContext().getRealPath("download/" + filename);
        File file = new File(path);
        if (file.exists()) {
            // 3.如果文件存在,那么设置响应的内容为下载,告诉浏览器将信息识别成下载
            // 判断一下浏览器
            String agent = request.getHeader("User-Agent");
            if (agent.contains("Firefox")) {// 火狐
                BASE64Encoder base64Encoder = new BASE64Encoder();
                filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
            } else {// ie和谷歌
                filename = URLEncoder.encode(filename, "utf-8");
            }
            response.setHeader("Content-Disposition", "attachment; filename=" + filename);
            // 4.获取文件流
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            // 5.返回给浏览器
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = fis.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            os.flush();// flush一下
            os.close();
            fis.close();
        } else {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("找不到文件");
        }
    }

3 问题处理:
fileupload插件调用upload.parseRequest(request)解析得到空值问题:
(1)原因在于Spring的配置文件中已经配置了MultipartResolver,导致文件上传请求已经被预处理过了,所以此处解析文件列表为空,对应的做法是删除该段配置;
(2)认为是structs的过滤器导致请求已被预处理,需要修改对应过滤器的配置。

4 使用postman模拟上传与下载文件:
文件上传参考资料:
https://blog.youkuaiyun.com/maowendi/article/details/80537304
文件下载参考资料:
https://www.cnblogs.com/jilodream/p/12567447.html

5 参考资料:
https://www.cnblogs.com/progor/p/9347823.html JavaWeb:servlet实现下载与上传功能
https://www.cnblogs.com/tongsi/p/12703200.html JAVA+HttpServletRequest文件上传
https://blog.youkuaiyun.com/u013248535/article/details/55823364 fileupload插件调用upload.parseRequest(request)解析得到空值问题

Files contained in javax.servlet.jar: META-INF/MANIFEST.MF javax/servlet/http/LocalStrings.properties javax.servlet.http.HttpSessionBindingListener.class javax.servlet.http.HttpSessionBindingEvent.class javax.servlet.http.HttpSessionEvent.class javax.servlet.http.HttpSession.class javax.servlet.http.HttpSessionContext.class javax.servlet.http.Cookie.class javax.servlet.http.HttpSessionAttributeListener.class javax.servlet.http.HttpServlet.class javax.servlet.http.HttpServletRequest.class javax.servlet.http.HttpServletResponse.class javax.servlet.http.NoBodyResponse.class javax.servlet.http.NoBodyOutputStream.class javax.servlet.http.HttpServletRequestWrapper.class javax.servlet.http.HttpSessionActivationListener.class javax.servlet.http.HttpSessionListener.class javax.servlet.http.HttpUtils.class javax.servlet.http.HttpServletResponseWrapper.class javax/servlet/resources/web-app_2_2.dtd javax/servlet/resources/j2ee_1_4.xsd javax/servlet/resources/j2ee_web_services_client_1_1.xsd javax/servlet/resources/j2ee_web_services_1_1.xsd javax/servlet/resources/XMLSchema.dtd javax/servlet/resources/jsp_2_0.xsd javax/servlet/resources/javaee_web_services_client_1_2.xsd javax/servlet/resources/datatypes.dtd javax/servlet/resources/web-app_2_3.dtd javax/servlet/resources/jsp_2_1.xsd javax/servlet/resources/web-app_2_4.xsd javax/servlet/resources/javaee_5.xsd javax/servlet/resources/web-app_2_5.xsd javax/servlet/resources/xml.xsd javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd javax/servlet/jsp/resources/jspxml.dtd javax/servlet/jsp/resources/jsp_2_0.xsd javax/servlet/jsp/resources/jsp_2_1.xsd javax/servlet/jsp/resources/jspxml.xsd javax/servlet/LocalStrings.properties javax.servlet.ServletContextAttributeListener.class javax.servlet.ServletContextAttributeEvent.class javax.servlet.ServletContextEvent.class javax.servlet.ServletContext.class javax.servlet.RequestDispatcher.class javax.servlet.Servlet.class javax.servlet.ServletException.class javax.servlet.ServletRequest.class javax.servlet.ServletResponse.class javax.servlet.ServletConfig.class javax.servlet.ServletInputStream.class javax.servlet.ServletOutputStream.class javax.servlet.FilterChain.class javax.servlet.ServletRequestEvent.class javax.servlet.Filter.class javax.servlet.FilterConfig.class javax.servlet.ServletRequestAttributeListener.class javax.servlet.ServletRequestAttributeEvent.class javax.servlet.GenericServlet.class javax.servlet.SingleThreadModel.class javax.servlet.ServletRequestWrapper.class javax.servlet.ServletResponseWrapper.class javax.servlet.ServletRequestListener.class javax.servlet.UnavailableException.class javax.servlet.ServletContextListener.class META-INF/maven/org.mortbay.jetty/servlet-api-2.5/pom.xml META-INF/maven/org.mortbay.jetty/servlet-api-2.5/pom.properties
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值