Explanation of Class.getResourceAsStream and how it is set in Tomcat for a simple Java web - app?

主宰稳场 提交于 2019-12-08 04:50:16

问题


I have a very simple java web-application which is deployed to Tomcat.

In this application I have some code which goes like this:

package com.mywebapp.hello;

import javax.servlet.http.*;
import java.io.*;

public class PdfTwoServlet extends HttpServlet {

    public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {

        httpServletResponse.setContentType("application/pdf");
        InputStream is = PdfTwoServlet.class.getResourceAsStream("/two.pdf");

When I compile my code and deploy it to tomcat, the directory structure goes like this:

This is under say C:\Tomcat\webapps\myApplication :

So

PdfTwoServlet.class.getResourceAsStream("/two.pdf");

works fine and finds the file two.pdf which is under classes folder, but I have no idea how this works.

Accessing properties file in a JSF application programmatically here BalusC says:

The Class#getResourceAsStream() can take a path which is relative to the location of the Class which you're using there as starting point. If you use /foo/filename.properties, then it will actually load foo/filename.properties from the classpath root.

I have 2 questions:

1) Why is the classpath root is WEB-INF\classes folder? Where is it determined? ( As far as I understand, it should be because code is working fine as I said. )

According to this: http://docs.oracle.com/javase/tutorial/essential/environment/paths.html , I do not have a classpath set in my local machine. So maybe when I start tomcat, it sets the classpath? But there are few web-apps deployed, are there few classpaths?

2) Is there a better way to make this work instead of: PdfTwoServlet.class.getResourceAsStream ? Something like getClassPath().getResourceAsStrem ?

Edit: Maybe someone more experienced and with better English can edit the title of this question. I am not sure if it is good enough.


回答1:


For 1) The classpath root in a servlet application is by specification the WEB-INF\classes folder of the jar, plus the root of all the jars in WEB-INF/lib of that WAR. Anything in those locations will be seen as the root of the classpath.

For the question on how classpaths in tomcat work, when tomcat deploys it set's the classpath in the following way: each WAR corresponds to a separate class loader which has access to WEB-INF/classes and all the jars in WEB-INF/lib.

By default if the resource searched is not found here, it will be searched for in the tomcat/lib directory. If it's not found there, it will ask the parent class loader, and so on, the explanation can be found here

If there are several web-apps deployed, each WAR will have it's own class loader pointing to it's own WEB-INF/classes and WEB-INF/lib jars.

For 2) there is not method like getClasspath(), ServletContext.getResourceAsStream() is the advised way in servlet applications for getting resources from inside the WAR. The WAR might be zipped or exploded, and this works for both, see this answer.



来源:https://stackoverflow.com/questions/19505646/explanation-of-class-getresourceasstream-and-how-it-is-set-in-tomcat-for-a-simpl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!