在Servlet中注入的bean中的NullPointerException

时间:2014-06-15 23:03:28

标签: java spring servlets dependency-injection nullpointerexception

我有两个servlet:ServletUtils和ServletAditional ServletAditional使用ServletUtils中一个名为isAllowed的方法来检查用户是否可以访问该网页。问题是ServletAditional每次尝试使用此方法时都会以Bean UserCalculation引起的NullPointer异常结束,该异常为空。
在调试模式下快速查看servlet之后,我发现从不调用ServletUtils中的init方法。我尝试在登录时设置bean,甚至在Login init中强制执行init,但bean仍为null 我的问题是,有没有办法初始化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);
}
}

ServletAditional:

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)

1 个答案:

答案 0 :(得分:1)

这很简单。由于您在两个类中都覆盖了init()方法,因此永远不会调用init() ServletUtils方法,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

一些要点:

  • 同时拨打super.init(config);课程中的ServletUtils
  • 尝试避免Servlet中的实例成员,例如user,如果它不是单例,因为它被视为对Servlet的多个请求的共享对象。
  • 如果您不想提供任何实现,则不会覆盖这些方法。
  • 如果需要,不要将HttpServletRequestHttpServletResponse作为Servlet的实例成员,然后将其作为方法参数传递。