简体   繁体   中英

NullPointerException in bean injected in Servlet

I have two servlets: ServletUtils and ServletAditional.
ServletAditional uses a method from ServletUtils called isAllowed to check whether the user can access the webpage or not. The problem is that every time ServletAditional tries to use this method ends in a NullPointer exception caused by the bean UserCalculation, which is null.
After having a quick look a the servlet in debug mode, I found that the init method in ServletUtils is never called. I tried to set the bean at login and even forcing the init in the Login init, but the bean is still null.
My question is, is there a way to initialize ServletUtils and set the bean without having to re write every 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");
}
}

Error message says:

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)

It's very simple. As you have overridden init() method in both the classes hence init() method of ServletUtils is never called and userCalculation is never initialized.

Read more about


Try

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

Let's have a look at simple program to understand it.

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();
}

output:

inside ServletAdicional's init method

Some Points:

  • Call super.init(config); in ServletUtils class as well.
  • Try to avoid instance members in Servlet such as user if it's not a singleton because it's treated as shared object for multiple requests to the Servlet.
  • If you don't want to provide any implementation they don't override these methods.
  • Don't make HttpServletRequest and HttpServletResponse as instance members of the Servlet if needed then simply pass it as method arguments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM