【问题标题】:Communication between Servlet & Applet fails when it was workingServlet 和 Applet 之间的通信在工作时失败
【发布时间】:2011-02-20 00:42:17
【问题描述】:

我有一个小程序(用户登录的地方),按下登录按钮时,我将登录详细信息发送到我的 servlet。在我的小程序中,负责将登录详细信息发送到 servelt 并接收 servlet 响应对象 FAILS 的函数。

我的问题是:我不知道为什么我的函数 sendObject(Object o) 失败并且我不知道如何解决它。你能帮我理解什么是错的以及为什么吗?

我使用的是 Apache 7.0。我认为从 servlet 接收响应(获取输入流)失败,但我不知道为什么 & 前几天登录工作正常,所以我知道我的 WEB-INF 文件夹设置得很好并且 web.xml 很好。

我的函数(我记录了函数失败的地方):

public ArrayList <Object> sendObject( Object o )
{
    try
    {
        URL servletUrl = new URL( this.getCodeBase(), "Updater" ); // "http://localhost:8080/" );
        URLConnection conn = servletUrl.openConnection();

        conn.setDoInput( true );
        conn.setDoOutput( true );
        conn.setUseCaches( false );
        conn.setRequestProperty( "Content-Type", "application/x-java-serialized-object" );

        OutputStream out = conn.getOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream( out );
        objOut.writeObject( o ); 
        objOut.flush(); 
        objOut.close();

        // receive result from servlet
        System.out.println( "Result from applet.getCodeBase()=" + this.getCodeBase() );
     // The following line is where I get the exception thrown
        InputStream instr = conn.getInputStream();              
        ObjectInputStream inputFromServlet = new ObjectInputStream(instr);
        ArrayList <Object> result = (ArrayList <Object>) inputFromServlet.readObject();
        inputFromServlet.close();
        instr.close();

        System.out.println( "Contents of output is " );
        for (int i=0; i<result.size(); i++)
        {
            System.out.println( "" + result.get(i) );
        }

        return result;
    }
    catch ( IOException e )
    {
        System.out.println( "In sendObject(): " + e );
    }
    catch ( Exception e )
    {
        System.out.println( "In sendObject(): " + e );
    }

    return null;
}    

Java 控制台输出:

applet.getCodeBase() 的结果 = http://localhost:8080/Updater/
在 sendObject() 中:java.io.IOException:服务器返回 HTTP 响应代码:500 用于 URL:http://localhost:8080/Updater/Updater

来自 Apache 日志:

20/02/2011 11:15:08 AM org.apache.catalina.core.ApplicationContext 日志
信息:ContextListener:contextInitialized()
2011 年 2 月 20 日上午 11:15:08 org.apache.catalina.core.ApplicationContext 日志
信息:SessionListener:contextInitialized()
20/02/2011 11:15:23 AM org.apache.catalina.core.ApplicationContext 日志
信息:将 servlet 更新程序标记为不可用
20/02/2011 11:15:23 AM org.apache.catalina.core.StandardWrapperValve 调用
严重:为 servlet 更新程序分配异常
java.lang.NullPointerException
在 javax.servlet.GenericServlet.getServletContext(GenericServlet.java:125)
在 UpdaterServlet.(UpdaterServlet.java:32) // 参考下面查看此文件的第 32 行
在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
在 sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(未知来源)
在 java.lang.reflect.Constructor.newInstance(Unknown Source)
在 java.lang.Class.newInstance0(未知来源)
在 java.lang.Class.newInstance(Unknown Source)
在 org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:119)
在 org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1048)
在 org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:799)
在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135)
在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源)
在 java.lang.Thread.run(Unknown Source)

localhost_access_log...:

127.0.0.1 - - [2011 年 2 月 20 日:11:15:12 +1100] "GET /Updater/index.html HTTP/1.1" 304 -
127.0.0.1 - - [20/Feb/2011:11:15:15 +1100] “GET /Updater/UpdaterApplet.class HTTP/1.1”304 -
127.0.0.1 - - [20/Feb/2011:11:15:15 +1100] “GET /Updater/ContentTree.class HTTP/1.1”304 -
127.0.0.1 - - [20/Feb/2011:11:15:15 +1100] “GET /Updater/ContentMap.class HTTP/1.1”304 -
127.0.0.1 - - [20/Feb/2011:11:15:15 +1100] “GET /Updater/UpdaterApplet$1.class HTTP/1.1”304 -
127.0.0.1 - - [20/Feb/2011:11:15:15 +1100] “GET /Updater/SQLInterface.class HTTP/1.1”304 -
127.0.0.1 - - [20/Feb/2011:11:15:23 +1100] “GET /Updater/ObjSerializationInterface.class HTTP/1.1”304 -
127.0.0.1 - - [20/Feb/2011:11:15:23 +1100] "POST /Updater/Updater HTTP/1.1" 500 3117

这是 UpdaterServlet.java 文件(如果您在上面看到此文件的第 32 行有错误):

public class UpdaterServlet extends HttpServlet
{
// Class Variables:
private static final long serialVersionUID = 1L;
private ArrayList <File> localDatabases;
private ArrayList <ArrayList <Object>> input;
private ArrayList <ArrayList <Object>> output;

// Class Methods:

public UpdaterServlet()
{
    getServletContext().log( "File open/created" ); // LINE 32
    localDatabases = new ArrayList <File>();

【问题讨论】:

    标签: java apache servlets applet


    【解决方案1】:

    看起来getServletContext() 返回null;您是否还覆盖了UpdaterServlet 中的init(ServletConfig) 方法?如果是这样,请务必致电super.init(config)

    【讨论】:

    • 感谢您的回复。实际上不,我不会覆盖 init()(也不会覆盖销毁、启动或停止),我应该调用这些超级方法吗?
    • 不,您没有必须覆盖这些方法,但如果您要覆盖init(ServletConfig),您可能还想在super 上调用它。不这样做通常是获得 null ServletContext 的原因。另一方面,Paulo 也是正确的 - 您的基本 URL 已经包含 Updater 上下文,因此在创建 servlet URL 时将 Updater 连接到它是向它添加额外 Updater 的原因。我并不完全相信这是问题所在,因为您在第 32 行确实有一个底层 NPE,您已经指出这是 ServletContext 上的日志方法调用。
    【解决方案2】:

    这个 NPE 意味着 ServletConfig 不存在(从那里返回 ServletContext)。这在 servlet 的 constructor 中确实不可用。 servlet 容器 servlet 构造之后设置它。您需要改为在 init() 方法中完成所需的工作。

    @Override
    public void init() {
        getServletContext().log( "File open/created" ); // LINE 32
        localDatabases = new ArrayList <File>();
        // ...
    }
    

    与具体问题无关,堆栈跟踪还暗示您的 servlet 在默认包中。这仅适用于非常特定的情况(某些 Apache Tomcat 版本与某些 JDK 版本相结合)。我强烈建议将 servlet 类放在一个包中并相应地更改 web.xml,这样您就不再依赖它了。

    【讨论】:

      【解决方案3】:

      那么,您的网络服务器知道在/Updater/Updater 上做什么吗?好像没有。看看错误日志,应该有更多的信息。

      【讨论】:

      • 感谢您的回答。我在上面发布了错误日志。不过还有其他错误日志,您希望我发布什么日志?
      • @Paulo 为什么返回localhost:8080/Updater/Updater 而不是localhost:8080/Updater?没有路径/文件夹localhost:8080/Updater/Updater 所以我不知道我是否需要创建这个或在路径中放入什么
      • 您的代码库是 http://localhost:8080/Updater/(因为小程序在 index.html 中),并且您的小程序正在向其中添加 Updater,这会将您带到 http://localhost:8080/Updater/Updater URL。 (我对 servlet 配置一无所知,所以我无法为您提供帮助。)
      • 他对上下文路径和 servlet 路径使用相同的名称。这确实令人困惑,但堆栈跟踪足以证明 servlet 调用。所以网址没问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-15
      相关资源
      最近更新 更多