Jannik
Jannik

Reputation: 90

Spring MVC Safe way to Upload, generate and download a file

I´m working on a WebApp with Spring MVC and Maven. I have the following process: First of all the User has to upload a file. Afterwards the uploaded file will be edited. Last but not least I want to create a download which contains the edited file.

The first step "Upload File" works well. I have a controller which contains the following POST method:

    @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();
    }

In the "serialize" Method my PDFClown File will be saved to a temp folder.

Afterwards the "uploadResult" page will be appear which contains the folloing code:

    <%@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>

When the User clicks on the link another Controller will be called which handles the download. I dont know how to design the controller so that it can works with the edited file which I saved in my temp folder. I think it should look like that :

    @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;
}

I have two questions now:

  1. How can the DownloadController attain the temp path to the file?
  2. Is this process of Uploading,Generating and Downloading a File safe? Or is there a better way to handle this process?

I´m new to Spring MVC and WebApp Development and I´m thankful for every suggestion :)

Upvotes: 1

Views: 2342

Answers (1)

StanislavL
StanislavL

Reputation: 57381

You can use the same approach you use in the upload

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

All you need is to point to the same file and then read it.

If you need a custom dir for the files saving you can either define a property - my.file.path=some path here or

use system temp dir

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);
  }
}

Got the code from the link

  1. Actually the approach is not safe. What to do if 2 different users upload files with the same name& What if one is uploaded and another user tries to download it? What is amount of files is millions? etc. etc.

It's better to use independent file storage but for test project it's fine

Upvotes: 1

Related Questions