-1

I have a Servlet that handles the download of an attached File. I get the attached file's path from the request and try to get the resource as stream from it using the ServletContext, but I always get the InputStream as null, the following is my doGet method:

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String path = request.getParameter("path");

    // Fetch File name from path and Then depending on the File extension choose
    // which ContentType using Switch structure
    Path p = Paths.get(path);
    String fileName = p.getFileName().toString();
    Optional<String> fileExtension = Optional.ofNullable(fileName).filter(f -> f.contains("."))
            .map(f -> f.substring(fileName.lastIndexOf(".") + 1));
    System.out.println("This is File Name: " + fileName);
    System.out.println("This is File Extension: " + fileExtension.orElseGet(null));

    /// Set ContentType of the HTTP header depending on the File
    /// Extensions
    switch (fileExtension.orElseGet(null).toLowerCase()) {
        case "txt":
            response.setContentType("text/plain");
            break;
        case "pdf":
            response.setContentType("application/pdf");
            break;
        case "doc":
            response.setContentType("application/msword");
            break;
        case "docx":
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            break;
        case "xlsx":
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            break;
        case "zip":
            response.setContentType("application/zip");
            break;
        case "jpeg":
            response.setContentType("image/jpeg");
            break;
        case "jpg":
            response.setContentType("image/jpeg");
            break;
        case "png":
            response.setContentType("image/png");
            break;
        case "rar":
            response.setContentType("application/x-rar-compressed");
            break;

        default:
            break;
    }

    response.setHeader("Content-disposition", "attachment; filename=" + fileName);
    //URL url = getClass().getResource(path);
    //InputStream strm=url.openStream();

     try(InputStream in = request.getServletContext().getResourceAsStream(path);
              OutputStream out = response.getOutputStream()) {

        byte[] buffer = new byte[ARBITARY_SIZE];

        int numBytesRead;
        while ((numBytesRead = in.read(buffer)) > 0) {
            out.write(buffer, 0, numBytesRead);
        }
    }
}

below is the Attachments Folder path:

enter image description here

Billel Tyo
  • 58
  • 7
  • 1
    This code makes no sense. The whole servlet is unnecessary. Just link to the URL `${pageContext.request.contextPath}/resources/Attachments/new1.txt` directly instead to the URL of the servlet. Unless this represents an uploaded file .. Then you need to take a step back because saving uploaded files into deploy folder isn't ever going to work reasonably in a production environment. – BalusC Dec 06 '20 at 16:48
  • Well, I have used that approach using: `` – Billel Tyo Dec 07 '20 at 15:49
  • @ BalusC, What do you suggest as a better approach for the production environment, and if any available resources thanks to provide with. – Billel Tyo Dec 08 '20 at 08:27
  • https://stackoverflow.com/q/18664579 – BalusC Dec 08 '20 at 09:44
  • @ BalusC,Really appreciate your Help, but still have an issue when I use: File fileSaveDir = new File(getServletContext().getInitParameter("file-upload")); I get NullPointerException, even though I added in web.xml, it works fine when I put the path hardcoded like this: File fileSaveDir = new File("c:/Attachments"); – Billel Tyo Dec 08 '20 at 12:33

1 Answers1

0

src/main/webapp is the Servlet root folder, i.e. files and folders in the webapp folder are copied into the .war file at the root.

The path parameter to servletContext.getResourceAsStream(path) must be relative to that, and must start with /.

So to read that file, you need path = "/resources/Attachments/new 1.txt"

Andreas
  • 138,167
  • 8
  • 112
  • 195