问题描述
我正在创建 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 为空,我不知道为什么。
我尝试了什么
- 向
@Stateless
添加SigninCommand
注释 - 将 bean.xml 文件添加到 WEB-INF 文件夹(在它被放置在 meta-inf 之前)
- 清除 IDEA 缓存
- 将
@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 代码。干杯。