【问题标题】:Tomcat: Null Pointer Exception when trying to access web serviceTomcat:尝试访问 Web 服务时出现空指针异常
【发布时间】:2012-11-26 02:41:51
【问题描述】:

我有一个包含 Web 服务的动态 Web 项目。我已将其导出为 WAR 文件并将其放置在 tomcat 的 webapps 目录中。 Tomcat 显示 Web 应用程序正在运行。当我尝试调用我的服务的一项操作时,我收到以下异常:

java.lang.NullPointerException
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1629)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:461)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    java.lang.Thread.run(Thread.java:680)

知道这意味着什么吗?

这是我定义网络服务的类:

打包网络服务;

import java.sql.*;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.core.MediaType;

@Path("/operations")
public class NotifyWebService {

    @Path("/insertNewPatron")
    @GET

    public String insertNewPatron(@QueryParam("cardNumber")String cardNumber,
                                    @QueryParam("pin") String pin,
                                    @QueryParam("nickname") String nickname,
                                    @QueryParam("deviceID")String deviceID) throws Exception {


        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxxxxx;";




            Connection c = DriverManager.getConnection(connectionUrl);

            String insertPatronStatement = "INSERT INTO dbo.Patron VALUES ('"+cardNumber+"','"+pin+"','"+nickname+"')";
            String insertDeviceOwner = "INSERT INTO dbo.DeviceOwner VALUES ('"+deviceID+"','"+cardNumber+"')";
            Statement state = null;

            state = c.createStatement();
            state.executeUpdate(insertPatronStatement);
            state.executeUpdate(insertDeviceOwner);


            c.close();


            return "true";
    }


    @Path("/initializeDevice")
    @GET

    public String initializeDevice( @QueryParam("deviceID")String deviceID) throws Exception{

        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxxxx;";


        Connection c = DriverManager.getConnection(connectionUrl);

        String insertDeviceStatement = "INSERT INTO dbo.Devices VALUES ('"+deviceID+"',1,3,1,3)";
        Statement state = c.createStatement();
        state.executeUpdate(insertDeviceStatement);


        return "true";
    }


    @Path("/updateDevicePreferences")
    @GET

    public String updateDevicePreferences(@QueryParam("deviceID") String deviceID, 
                                            @QueryParam("dueDateNotice")String dueDateNotice,
                                            @QueryParam("dueDateNoticeAdvance") String dueDateNoticeAdvance,
                                            @QueryParam("holdsNotice") String holdsNotice, 
                                            @QueryParam("eventNoticeAdvance")String eventNoticeAdvance) throws Exception{
        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxxxx;";


        Connection c = DriverManager.getConnection(connectionUrl);

        String updateDeviceStatement = "UPDATE dbo.Devices SET dueDateNotice="+dueDateNotice+", dueDateNoticeAdvance="+dueDateNoticeAdvance
                                    +", holdsNotice="+holdsNotice+", eventNoticeAdvance="+eventNoticeAdvance+" WHERE deviceID='"+deviceID+"'";
        Statement state = c.createStatement();
        state.executeUpdate(updateDeviceStatement);

        return "true";
    }


    @Path("/removeUser")
    @GET

    public String removeUser(@QueryParam("cardNumber")String cardNumber) throws Exception{
        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxxxx;";


        Connection c = DriverManager.getConnection(connectionUrl);

        String removeStatement = "DELETE FROM dbo.Patron WHERE cardNumber='"+cardNumber+"'";

        Statement state = c.createStatement();
        state.executeUpdate(removeStatement);




        return "true";
    }

    @Path("/addEvent")
    @GET

    public String addEvent(@QueryParam("deviceID")String deviceID, @QueryParam("eventID")String eventID) throws Exception{

        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxxx;";


        Connection c = DriverManager.getConnection(connectionUrl);

        String eventStatement = "INSERT INTO dbo.Events VALUES ('"+deviceID+"','"+eventID+"')";
        Statement state = c.createStatement();
        state.executeUpdate(eventStatement);


        return "true";
    }

    @Path("/removeEvent")
    @GET

    public String removeEvent(@QueryParam("deviceID")String deviceID, @QueryParam("eventID")String eventID) throws Exception{

        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxxx;";


        Connection c = DriverManager.getConnection(connectionUrl);

        String eventStatement = "DELETE FROM dbo.Events WHERE deviceID='"+deviceID+"' AND eventID='"+eventID+"'";
        Statement state = c.createStatement();
        state.executeUpdate(eventStatement);


        return "true";
    }

    @Path("/removeAllEvents")
    @GET

    public String removeAllEvents(@QueryParam("deviceID")String deviceID) throws Exception{

        String connectionUrl = "jdbc:sqlserver://mssql.acpl.lib.in.us:1433;" +
                   "databaseName=MobileNotify;user=Mobile_Notification_User;password=xxxx;";


        Connection c = DriverManager.getConnection(connectionUrl);

        String eventStatement = "DELETE FROM dbo.Events WHERE deviceID='"+deviceID+"'";
        Statement state = c.createStatement();
        state.executeUpdate(eventStatement);


        return "true";
    }
}

这是我的 web.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>APNS_WebService</display-name>
   <servlet>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

如果需要更多信息,请告诉我!

【问题讨论】:

    标签: java web-services tomcat web-applications jax-rs


    【解决方案1】:

    我认为您的 NPE 的原因是您的 &lt;servlet-class&gt; 块中缺少 &lt;servlet-class&gt; 元素。但是,决定 servlet-class 应该是什么会引发更大的问题...

    看起来您还没有选择 JAX-RS 框架。请参阅JAX-RS Frameworks,了解各种替代方案。

    我目前正在使用泽西岛。 Jersey 的典型 web.xml 可能包含:

      <servlet>
        <servlet-name>WebService</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
           <param-name>com.sun.jersey.config.property.packages</param-name>
           <param-value>webservice</param-value>
        </init-param>
        <init-param>
          <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
          <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>WebService</servlet-name>
        <url-pattern>/api/rest/*</url-pattern>
      </servlet-mapping>
    

    对于许多 JAX-RS 框架,框架的选择将决定您应该输入什么作为 &lt;servlet-class&gt;

    还请注意,由于您的根资源位于包 webservice 中,因此我将 com.sun.jersey.config.property.packages 参数设置为 webservice,因此 Jersey 将扫描您的包中的任何 JAX-RS 注释类。

    【讨论】:

    • 谢谢,成功了!我以为我有一个类似于以前的 web.xml,但我想我错了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多