views:

200

answers:

4

How do I specify the path to a file in a web application? I have a folder named 'templates' under WEB-INF, I've been told that under GlassFish v3 the path should look like this:

./WebContent/WEB-INF/templates

but this way I'm getting a file not found exception. What do I have to change in order to make it work?

+1  A: 

When you create a dynamic web app project in Eclipse, the content that will go into the root of the war file gets packaged from the WebContent folder.

It sounds like you want to access a file from the directory WEB-INF/templates at runtime for your web app.

I assume that you are using the absolute path to access a file from there presently. You have already figured out that this probably will not work for your app, once it is deployed.

You will need to access the content of the file using ServletContext.getResourceAsStream(String).

The following snippet finds a file named WEB-INF/templatez/myfile.txt from a servlet that is part if the web app that contains the myfile.txt file. Other web apps and users will will not be able to access the file via http GET requests.

package a;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name="FileFinder", urlPatterns={"/FileFinder"})
public class FileFinder extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            //* TODO output your page here
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet FileFinder</title>");  
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet FileFinder at " + request.getContextPath () + "</h1>");
            InputStream is = null;
            try {
                is = request.getServletContext().getResourceAsStream("/WEB-INF/templatez/myfile.txt");
                out.println((null == is ? "did not " : "did ") + "find the file myfile.txt");
            } finally {
                if (null != is) is.close();
            }

            out.println("</body>");
            out.println("</html>");
            //*/
        } finally { 
            out.close();
        }
    } 

    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }

}
vkraemer
Well, this is not exactly what I need, I don't need to use the file itself, I just need to pass the path to FreeMarker but thanks a lot anyway, I really appreciate your time and help. Besides, I found a shorter path within the same folder structure to what seems like locally deployed app. Hopefully it will keep working after the real deployment.
Slavko
A: 

Ok, I figured this out. Can't believe the solution was this simple. I just moved the templates folder to WebContent folder, same place JSP and HTML pages are at and changed the path in the DD to /templates. Now I'm pretty sure it'll work under any web container on any server.

Slavko
A: 

Would servlet 3.0's resource JAR feature be useful: http://blogs.sun.com/alexismp/entry/web_inf_lib_jar_meta ?

Alexis MP
No, it would not. That's a new way of getting a resource and I don't need a resource, I just need a path to a file that I can pass to FreeMarker.
Slavko
A: 

If I understand you correctly, you cannot rely on the current working directory to locate a resource you have deployed. If your resource is physically placed relative to a classpath resource (like inside a jar), you can ask about where that resource is, and then navigate from there.

From http://stackoverflow.com/questions/558502/how-a-servlet-can-get-the-absolute-path-to-a-file-outside-of-the-servlet/559059#559059 which in turn is from http://www.exampledepot.com/egs/java.lang/ClassOrigin.html:

Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();  // file:/c:/almanac14/examples/
Thorbjørn Ravn Andersen