java - 使用 getServletConfig().getServletContext().getAttribute() (Java) 时获取 NPE

标签 java servlets

我使用 Servlet 的时间并不长。我遇到了这个问题,我无法终止自己。我正在使用 Servlet 创建一个小型 Web 项目,并且我尝试将我的服务和 DAO 对象添加到 ServletContext。

HTTP Status 500 - Error instantiating servlet class com.taxi.service.controller.LoginController

type Exception report

message Error instantiating servlet class com.taxi.service.controller.LoginController

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Error instantiating servlet class com.taxi.service.controller.LoginController
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)
root cause

java.lang.NullPointerException
    javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123)
    com.taxi.service.controller.LoginController.<init>(LoginController.java:16)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    java.lang.Class.newInstance(Class.java:379)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

我的 web.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>Jean taxi-service</display-name>

    <listener>
        <listener-class>com.taxi.service.utils.ApplicationContext</listener-class>
    </listener>

    <servlet>
        <servlet-name>InitController</servlet-name>
        <servlet-class>com.taxi.service.controller.InitController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>LoginController</servlet-name>
        <servlet-class>com.taxi.service.controller.LoginController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>RegistrationController</servlet-name>
        <servlet-class>com.taxi.service.controller.RegistrationController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>PrivateAreaController</servlet-name>
        <servlet-class>com.taxi.service.controller.PrivateAreaController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>OrderController</servlet-name>
        <servlet-class>com.taxi.service.controller.OrderController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>ReviewController</servlet-name>
        <servlet-class>com.taxi.service.controller.OrderController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>AdminController</servlet-name>
        <servlet-class>com.taxi.service.controller.AdminController</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>InitController</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>LoginController</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>RegistrationController</servlet-name>
        <url-pattern>/registration</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>OrderController</servlet-name>
        <url-pattern>/orderCreation</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>ReviewController</servlet-name>
        <url-pattern>/review</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>PrivateAreaController</servlet-name>
        <url-pattern>/privateArea</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>AdminController</servlet-name>
        <url-pattern>/adminPanel</url-pattern>
    </servlet-mapping>

    <!-- <error-page>
        <location>/WEB-INF/pages/error.jsp</location>
    </error-page>
    -->

    <session-config>
        <session-timeout>45</session-timeout>
    </session-config>

    <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/order_board</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>

    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>

</web-app>

ServletContext 监听器类:

public class ApplicationContext implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        servletContextEvent.getServletContext().setAttribute("clientDao", new ClientDaoImpl(DataBaseUtil.getConnectionPoolInstance()));
        servletContextEvent.getServletContext().setAttribute("orderDao", new ClientDaoImpl(DataBaseUtil.getConnectionPoolInstance()));
        servletContextEvent.getServletContext().setAttribute("clientService", new ClientServiceImpl());
        servletContextEvent.getServletContext().setAttribute("orderService", new OrderServiceImpl());
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

登录 Controller 类:

public class LoginController extends HttpServlet {

    private ClientService clientService = (ClientServiceImpl) getServletConfig().getServletContext().getAttribute("clientService");

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response){
       ...
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response{
        /**
         *...something doing with clientService
         */
    }
}

当我试图从 ServletContext 获取我的服务对象时,在这些行中我得到了 NPE:

private ClientService clientService = (ClientServiceImpl) getServletConfig().getServletContext().getAttribute("clientService");

我应该怎么做,才能使这个 npe 异常消失并且我的 clientService 工作。 多谢。 附:我会阅读所有的建议和答案,希望你能帮助我解决这个问题。

最佳答案

在覆盖的 init(ServletConfig) 方法中初始化您的字段。 ServletConfig 在实例初始化时不可用。

@Override
public void init(ServletConfig config) throws ServletException {
    super.init(config);
    this.clientService = config.getServletContext().getAttribute("clientService");
}

来自javadoc of Servlet#init(ServletConfig)

Called by the servlet container to indicate to a servlet that the servlet is being placed into service.

The servlet container calls the init method exactly once after instantiating the servlet. The init method must complete successfully before the servlet can receive any requests.

javadoc of the GenericServlet implementation of init(ServletConfig)进一步说明

This implementation stores the ServletConfig object it receives from the servlet container for later use. When overriding this form of the method, call super.init(config).

关于java - 使用 getServletConfig().getServletContext().getAttribute() (Java) 时获取 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42059690/

相关文章:

java - 从命令提示符编译并运行 Servlet

java - doGet 方法完成后,Servlet 是否返回响应?

java - mvn 依赖 :tree does not list dependencies of a dependency

java - 捕获错误以抛出异常

java - 如何在 JPA 和 Hibernate 4.3 中使用 SchemaExportTool

java - 使用 Maven 部署带有嵌入式 jetty 的 jar

java - 将单个图像选择从图库转换为多个

java - 如何在 Velocity 上配置 UTF-8?

java - 带有克隆项目 : build problems 的 Tomcat + Eclipse

java - 如何处理图像生成 Servlet 的异常?