【问题标题】:NullPointerException in bean injected in Servlet在 Servlet 中注入的 bean 中的 NullPointerException
【发布时间】:2014-08-05 18:13:23
【问题描述】:

我有两个 servlet:ServletUtils 和 ServletAditional。
ServletAditional 使用 ServletUtils 中称为 isAllowed 的方法来检查用户是否可以访问网页。问题是每次 ServletAditional 尝试使用该方法时都会以 bean UserCalculation 导致的 NullPointer 异常结束,该异常为 null。
在快速查看调试模式下的 servlet 后,我​​发现 ServletUtils 中的 init 方法从未被调用过。我尝试在登录时设置 bean,甚至在登录初始化中强制初始化,但 bean 仍然为空。
我的问题是,有没有一种方法可以初始化 ServletUtils 并设置 bean 而无需重新编写每个 servlet?

ServletUtils:

public class ServletUtils extends HttpServlet{
private static final long serialVersionUID = 1L;
private HttpServletRequest request; 
private HttpServletResponse response;
private UserCalculation userCalculation;
protected User user;

public void setUserCalculation(UserCalculation userCalculation) {
    this.userCalculation = userCalculation;
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
    //does nothing, not necessary
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //does nothing, not necessary
}

@Override
public void init(ServletConfig config) {
    ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
    this.userCalculation = (UserCalculation) ctx.getBean("UserCalculation");
}

public boolean isAllowed(int idRole) throws ServletException, IOException{
    User user=(User) getSessionAttribute("user");
    return userCalculation.checkRole(user, idRole);
}
}

Servlet附加:

public class ServletAdicional extends ServletUtils {
private static final long serialVersionUID = 1L;
private int role=1;
private AditionalService service;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    setRequestResponse(request, response);

    if (!isLogedIn()){
        redirectLogin();
    }
    else if (isAllowed(role)){
        setDefaultAttributes();
        redirectTo("CalculateAditionals");
    }
    else{
        redirectToErrorPage();
    }
}
@Override
public void init(ServletConfig config) {
    ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
    this.service = (AditionalService) ctx.getBean("AditionalService");
}
}

错误信息说:

Servlet.service() for servlet [aditionalReport] in context with path [/ElectronicaProject] threw exception
java.lang.NullPointerException
    at electronicaProject.servlets.ServletUtils.isAllowed(ServletUtils.java:82)
    at electronicaProject.servlets.ServletAditional.doGet(ServletAditional.java:31)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

【问题讨论】:

    标签: java spring servlets dependency-injection nullpointerexception


    【解决方案1】:

    这很简单。由于您在两个类中都覆盖了init() 方法,因此永远不会调用ServletUtilsinit() 方法并且永远不会初始化userCalculation

    了解更多


    试试

    public class ServletAdicional extends ServletUtils {
        @Override
        public void init(ServletConfig config) {
            super.init(config);
            ...
        }
    }
    

    让我们看一个简单的程序来理解它。

    interface Init {
        public void init();
    }
    
    class ServletUtils implements Init {
        @Override
        public void init() {
            System.out.println("inside ServletUtils's init method");
        }
    }
    
    class ServletAdicional extends ServletUtils {
        @Override
        public void init() {
            System.out.println("inside ServletAdicional's init method");
        }
    }
    
    public static void main(String[] args) throws Exception {
        
        Init init = new ServletAdicional();
        init.init();
    }
    

    输出:

    inside ServletAdicional's init method
    

    几点:

    • ServletUtils 类中也可以调用super.init(config);
    • 尽量避免 Servlet 中的实例成员,例如 user,如果它不是单例,因为它被视为对 Servlet 的多个请求的共享对象。
    • 如果您不想提供任何实现,它们不会覆盖这些方法。
    • 如果需要,不要将 HttpServletRequestHttpServletResponse 作为 Servlet 的实例成员,然后只需将其作为方法参数传递即可。

    【讨论】:

    • 首先不要手写 servlet。
    • @Braj 谢谢,我不敢相信我没有看到。必须睡一觉。不幸的是,这就是整个项目的重点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 2016-04-06
    • 2017-09-12
    • 2015-04-16
    • 2021-08-04
    • 2016-11-09
    • 1970-01-01
    相关资源
    最近更新 更多