无法调用方法,因为注入为空

问题描述

我正在创建 web 应用程序,我正在使用 java ee 7,使用 maven tomcat 插件创建 war 部署它。我有 servlet、ejb、一些逻辑、jpa 集成等。我使用命令模式来处理请求。我的主 servlet 获取参数并将用户根据命令从隐藏输入作为参数重定向下一页

我有实现登录逻辑的登录表单和类。这些课程是下一个

编辑 (我编辑了我的代码添加了 bean 的注入。我还根据每个命令的限定符创建了)

我的代码

SigninCommand.java

@SigninCommandQualifier
public class SigninCommand implements Command {

    @Inject
    private UserEJB userEJB;

    public String execute(HttpServletRequest request,HttpServletResponse response) throws IOException {
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        User signinUser = new User(email,password);
        User foundUser = userEJB.findUser(signinUser);
        if (foundUser != null) {
            request.setAttribute("passedAuth",true);
            return PagesManager.getProperty("page.nameGeneration");
        } else {
            request.setAttribute("passedAuth",false);
            return PagesManager.getProperty("page.signin");
        }
    }
}

UserEJB.java

@Stateless
public class UserEJB implements UserEJBRemote{
    @Inject
    private EntityManager em;
    public List<User> findUsers() {
        TypedQuery<User> query = em.createNamedQuery(FIND_ALL,User.class);
        return query.getResultList();
    }

    public User findUser(@NotNull User user) {
        return em.find(User.class,user);
    }

    public
    @NotNull
    User createuser(@NotNull User user) {
        em.persist(user);
        return user;
    }

    public
    @NotNull
    User updateUser(@NotNull User user) {
        return em.merge(user);
    }

    public void deleteUser(@NotNull User user) {
        em.remove(em.merge(user));
    }
}

beans.xml

<beans 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/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

ProjectServlet.java

public class ProjectServlet extends HttpServlet {

    @Inject
    @EmptyCommandQualifier
    private Command command;

    @Inject
    private ActionFactory actionFactory;

    @Override
    protected void doGet(HttpServletRequest request,HttpServletResponse response) throws servletexception,IOException {
        processRequest(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request,response);
    }

    private void processRequest(HttpServletRequest request,IOException{
        String action = request.getParameter("command");
        try {
            command = actionFactory.defineCommand(action);
        } catch (IllegalArgumentException e) {
            request.setAttribute("msg",action + " " + MessageManager.getProperty("message.wrongaction"));
        }
        String page;
        try {
            page = command.execute(request,response);
        } catch (IOException e) {
            page = PagesManager.getProperty("page.error");
        }
        if (page != null) {
            if (page.equals("not redirecting")) {
                return;
            }
            Requestdispatcher dispatcher = getServletContext().getRequestdispatcher(page);
            dispatcher.forward(request,response);
        } else {
            page = PagesManager.getProperty("page.index");
            request.getSession().setAttribute("nullPage",MessageManager.getProperty("message.nullpage"));
            response.sendRedirect(request.getcontextpath() + page);
        }
    }
}

Command.java

public interface Command {
    String execute(HttpServletRequest request,HttpServletResponse response) throws IOException;
}

CommandEnum.java

public enum CommandEnum {

    EMPTY_COMMAND {
        {
            this.command = emptyCommand;
        }
    },NAME_GENERATION {
        {
            this.command = nameGenerationCommand;
        }
    },NAME_GENERATION_SETTINGS {
        {
            this.command = nameGenerationSettingsCommand;
        }
    },SIGNIN {
        {
            this.command = signinCommand;
        }
    };

    Command command;

    @Inject
    EmptyCommand emptyCommand;
    @Inject
    NameGenerationCommand nameGenerationCommand;
    @Inject
    NameGenerationSettingsCommand nameGenerationSettingsCommand;
    @Inject
    SigninCommand signinCommand;

    public Command getCommand() {
        return command;
    }
}

ActionFactory.java

public class ActionFactory {

    @Inject
    @EmptyCommandQualifier
    private Command command;

    @Inject
    private CommandEnum commandEnum;

    public Command defineCommand(String action) throws IllegalArgumentException {
        if (action == null || action.isEmpty()) {
            return command;
        }
        commandEnum = CommandEnum.valueOf(action.toupperCase());
        command = commandEnum.getCommand();
        return command;
    }

    @Produces
    public static CommandEnum getEmptyCommandEnum()
    {
        return CommandEnum.EMPTY_COMMAND;
    }
}

问题

当我点击登录页面上的登录按钮时,我捕捉到下一个异常:

java.lang.NullPointerException: Cannot invoke "factory.ActionFactory.defineCommand(String)" because "this.actionFacto
ry" is null
        at servlet.ProjectServlet.processRequest(ProjectServlet.java:39)
        at servlet.ProjectServlet.doPost(ProjectServlet.java:33)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
        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.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        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:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:832)
        at org.apache.coyote.http11.AbstractHttp11Proces
sor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractCo
nnectionHandler.process(AbstractProtocol.java:603)
        at org.apache.tomcat.util.net.JIoEndpoint$Socket
Processor.run(JIoEndpoint.java:310)
        at java.base/java.util.concurrent.ThreadPoolExec
utor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExec
utor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:83
2)

actionFactory 为空,我不知道为什么。

我尝试了什么

  1. @Stateless 添加 SigninCommand 注释
  2. 将 bean.xml 文件添加到 WEB-INF 文件夹(在它被放置在 meta-inf 之前)
  3. 清除 IDEA 缓存
  4. @Named 注释附加到 UserEJB

但我还是得到了 NPE。

请帮忙。

解决方法

问题是,除了在 CDI-beans 中使用 new 之外,tomcat 被用作容器而没有像 Weld-Standalone 那样添加任何东西。 因此,无论是像@Ejb、@Standalone...这样的 Ejb-Annotations,还是像 @Inject 这样的 CDI-Annotations,在 war-file 的部署过程中都没有任何影响。 合理的解决方案是从纯 servlet 容器切换到像 wildfly、kumuluzee 那样的微配置容器......

,

这通常是由于调用层次结构中的某个地方 new 发生了一些实例化。确保您的 SigninCommand 类的任何实例都没有被 new 实例化。由于我们没有您的主要 servlet 代码,我很抱歉这只是一个猜测,因为我无法发表评论要求包含您的 servlet 代码。干杯。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...