Search code examples
javaservletsnullpointerexceptioninputstreamservletcontextlistener

Can't get ResourceAsStream from path using ServletContext


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


Solution

  • 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"