【问题标题】:GWT ServleContext and retrieving a fileGWT ServleContext 和检索文件
【发布时间】:2013-10-09 21:35:05
【问题描述】:

我正在开发一个 GWT 应用程序,并且正在尝试从“war/config/config.properties”中检索文件。在 GWT 服务器端,我创建了一个名为 Config.java 的类,它创建了一个新的 Properties 对象并从 config.properties 填充它,我使用 RemoteServiceServlet 扩展了 Config,以便能够使用 getServletContext()。我正在使用以下行来加载属性

prop.load(ServletContext.class.getResourceAsStream("config/config.properties"));

我的 config.properties 文件看起来像这样

database=db
host=192.168.1.1
password=pass
user=user

我的配置类看起来像这样

public class Config extends RemoteServiceServlet {

Properties prop = new Properties();

public Config(){
    //load a properties file
    try {           
        ServletContext sc = getServletContext();            
        prop.load(sc.getResource("/config/config.properties").openStream());

        //System.out.println("Get Real Path" + getServletContext().getRealPath("config") + "/config.properties");
        //FileInputStream input = (FileInputStream) getServletContext().getResourceAsStream("/config/config.properties");
        //prop.load(new FileInputStream(getServletContext().getRealPath("/config/config.properties")));
        //prop.load(input);
        System.out.println("properties file loaded successfully");

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        System.out.println("Could not find properties file");
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NullPointerException e) {
        System.out.println("null pointer exception in loading properties file");
        e.printStackTrace();
    }
}

public String getProperty(String name){
    return prop.getProperty(name);
}

}

然而对于我的一生,我无法弄清楚为什么我在加载属性时会收到空指针异常,只是拒绝工作。堆栈跟踪在这里,任何想法是我做错了什么?

java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Unknown Source)
    at java.util.Properties.load0(Unknown Source)
    at java.util.Properties.load(Unknown Source)
    at com.cbs.ioma.server.Config.<init>(Config.java:19)
    at com.cbs.ioma.server.DatabaseServiceImpl.<init>(DatabaseServiceImpl.java:61)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at java.lang.Class.newInstance0(Unknown Source)
    at java.lang.Class.newInstance(Unknown Source)
    at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:463)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:324)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)``

编辑:我更改了代码以反映下面的评论,此处发布了新错误

> java.lang.NullPointerException    at
> javax.servlet.GenericServlet.getServletContext(GenericServlet.java:160)
>   at com.cbs.ioma.server.Config.<init>(Config.java:19)

编辑:我改变了我的班级,你能看一下并告诉我应该如何调用 servlet 吗?如果它被 Servlet 中的另一个方法调用,我不明白我应该如何覆盖该方法。如何实现?

public class Config extends RemoteServiceServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    Properties prop = new Properties();

    public Config(){

    }

    public String getProperty(String name){
        return prop.getProperty(name);

    }

    @Override
    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
        try {           
            prop.load(config.getServletContext().getResource("/config/config.properties").openStream());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

【问题讨论】:

    标签: java gwt


    【解决方案1】:

    我误读了你的问题。如果文件在war/config/config.properties,你应该使用

    ServletContext sc = ...// get servlet context; 
    sc.getResource("/config/config.properties");
    

    javadoc中所述:

    返回映射到指定路径的资源的 URL。这 路径必须以“/”开头并被解释为相对于 当前上下文根。

    编辑

    Servlet 容器启动时,它会使用无参数构造函数实例化您的ServletConfig)类。然后它调用它的Servlet#init(ServletConfig) 方法,您最终可以访问ServletContext。这是您应该初始化 Properties 对象的地方。所以重写该方法并将您当前的构造函数代码移动到它。


    供您参考

    不要这样做

    ServletContext.class.getResourceAsStream("config/config.properties")
    

    如果config/config.properties 位于类路径的根目录,则使用

    ServletContext.class.getResourceAsStream("/config/config.properties")
    

    上面的 case 将采用 ServletContext 所在包的名称,并尝试使用它解析您指定的路径。比如ServletContextjavax.servlet中,所以

    /javax/servlet/config/config.properties
    

    您的资源显然不在其中。 javadoc of Class#getResource(String) 中描述了您应该指定的路径的规则。

    【讨论】:

    • 您复制粘贴的内容好像是一样的?
    • 等待我看到变化,/。我也试过了,还是没有骰子。
    • 另外,如果它找不到文件,它不会先给我一个找不到文件的异常吗?
    • @john 我误解了你的问题。请参阅我的编辑。它不会给出FileNotFoundException,因为它不是在寻找File,而是在寻找作为URL 的资源。
    • 嗯,这仍然行不通,因为 sc.getResource() 提供了一个 URL,而 prop.load() 正在寻找 InputStream,有没有办法使用 getResourceAsStream 代替?
    【解决方案2】:

    我建议您使用更高级别的库来为您处理。

    例如使用ResourceBundle

    ResourceBundle bundle = ResourceBundle.getBundle(fully.qualified.path.using.dots.to.properties);
    bundle.getString("your_property_key");
    

    【讨论】:

    • 嘿 manubot,我尝试使用常量,但除非您使用第三个辅助类,否则您不能在服务器端使用它。
    • @john 你是对的,对不起。常量在服务器上不可用,我将编辑答案。但是 ResourceBundle 应该为你完成这项工作(它为我)
    • 你能举一个完全限定路径的例子吗? 'getservletcontext' 仍然不适合我。
    • @john 使用资源包时不需要调用 getservletcontext。我认为问题在于,当 .properties 是类路径的一部分时,您将它们视为文件服务器上的文件,并且您应该将它们视为另一个类(对于 ResourceBundle 的 porpuses)。您需要在类路径中包含属性并使用限定名称,例如“com.myapp.server.ressources.myproperties.properties”
    猜你喜欢
    • 1970-01-01
    • 2012-01-29
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多