【问题标题】:Spring MVC Safe way to Upload, generate and download a fileSpring MVC 上传、生成和下载文件的安全方式
【发布时间】:2017-09-14 05:51:54
【问题描述】:

我正在使用 Spring MVC 和 Maven 开发 WebApp。我有以下过程:首先,用户必须上传一个文件。之后上传的文件将被编辑。最后但并非最不重要的一点是,我想创建一个包含已编辑文件的下载。

第一步“上传文件”效果很好。我有一个控制器,其中包含以下 POST 方法:

    @RequestMapping(value = "/CircleUp", method = RequestMethod.POST)
    public String circleUpPost(HttpServletRequest request, Model model, //
            @ModelAttribute("circleUpForm") CircleUpForm circleUpForm) {

        return this.doUpload(request, model, circleUpForm);
    }

    private String doUpload(HttpServletRequest request, Model model, //
            CircleUpForm circleUpForm) {

        File file = circleUpForm.getFile();

        if (file != null) {
            try {
//Some edit stuff
                serialize(file, SerializationModeEnum.Standard);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        model.addAttribute("uploadedFiles", file);
        return "uploadResult";
    }

    protected static String serialize(File file, SerializationModeEnum serializationMode) {

        java.io.File test = null;

        try {
            test = java.io.File.createTempFile("Test", ".pdf");
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            file.save(test, serializationMode);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // test.deleteOnExit();

        return test.getPath();
    }

在“序列化”方法中,我的 PDFClown 文件将被保存到临时文件夹中。

随后会出现“uploadResult”页面,其中包含以下代码:

    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>
<head>
<meta charset="UTF-8">
<title>Download</title>
</head>
<body>
    <h3>Download Files:</h3>

    <a href="${pageContext.request.contextPath}/Download">CircleUp</a>

</body>
</html>

当用户单击链接时,将调用另一个控制器来处理下载。我不知道如何设计控制器,以便它可以与我保存在我的临时文件夹中的编辑文件一起使用。我认为它应该是这样的:

    @RequestMapping(value = "/Download")
public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {


    final String temperotyFilePath = ???

    String fileName = "Test.pdf";
    response.setContentType("application/pdf");
    response.setHeader("Content-disposition", "attachment; filename=" + fileName);

    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos = convertPDFToByteArrayOutputStream(temperotyFilePath + "\\" + fileName);
        OutputStream os = response.getOutputStream();
        baos.writeTo(os);
        os.flush();
    } catch (Exception e1) {
        e1.printStackTrace();
    }

}

private ByteArrayOutputStream convertPDFToByteArrayOutputStream(String fileName) {

    InputStream inputStream = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {

        inputStream = new FileInputStream(fileName);
        byte [] buffer = new byte [1024];
        baos = new ByteArrayOutputStream();

        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return baos;
}

我现在有两个问题:

  1. DownloadController 如何获取文件的临时路径?
  2. 这个上传、生成和下载文件的过程安全吗?或者有没有更好的方法来处理这个过程?

我是 Spring MVC 和 WebApp 开发的新手,我很感谢你的每一个建议 :)

【问题讨论】:

    标签: java spring maven spring-mvc web-applications


    【解决方案1】:

    您可以使用与上传相同的方法

    test = java.io.File.createTempFile("Test", ".pdf");
    

    您只需要指向同一个文件然后读取它。

    如果您需要自定义目录来保存文件,您可以定义一个属性 - my.file.path=some path here

    使用系统临时目录

    public class Main {
      public static void main(String[] args) {
        String property = "java.io.tmpdir";
    
        String tempDir = System.getProperty(property);
        System.out.println("OS current temporary directory is " + tempDir);
      }
    }
    

    the link获取代码

    1. 实际上这种方法并不安全。如果 2 个不同的用户上传具有相同名称的文件怎么办&如果一个被上传并且另一个用户尝试下载它怎么办?文件的数量是几百万?等等等等。

    最好使用独立的文件存储,但对于测试项目就可以了

    【讨论】:

    • 谢谢!但是我怎样才能在另一个控制器中指向同一个文件呢?
    • 您应该以某种方式将文件名传回客户端,然后在下载请求中使用相同的文件名。
    • 感谢工作:) 我首先将文件名从第一个控制器提供给 uploadResult.jsp,然后将 .jsp 的名称提供给第二个控制器:) 现在我必须考虑您对第 2 点的建议。!谢谢:)
    猜你喜欢
    • 2012-06-18
    • 2016-08-18
    • 2011-02-03
    • 1970-01-01
    • 2021-04-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多