我正在创建 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, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, 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 为空,我不知道为什么。
@Stateless
添加 SigninCommand
注释@Named
注释附加到 UserEJB
类但我还是得到了 NPE。
请帮忙。
答案 0 :(得分:2)
问题是,除了在 CDI-beans 中使用 new 之外,tomcat 被用作容器而没有像 Weld-Standalone 那样添加任何东西。 因此,无论是像@Ejb、@Standalone...这样的 Ejb-Annotations,还是像 @Inject 这样的 CDI-Annotations,在 war-file 的部署过程中都没有任何影响。 合理的解决方案是从纯 servlet 容器切换到像 wildfly、kumuluzee 那样的微配置容器......
答案 1 :(得分:1)
这通常是由于调用层次结构中的某个地方 new 发生了一些实例化。确保您的 SigninCommand
类的任何实例都没有被 new
实例化。由于我们没有您的主要 servlet 代码,我很抱歉这只是一个猜测,因为我无法发表评论要求包含您的 servlet 代码。干杯。