我正在尝试基于Zentask示例创建一个简单的登录 - zentask - playframework,但是当我单击调用Application.authenticate操作的登录按钮时,它会给出运行时异常。我用 - 错误
标记了这一行[RuntimeException: java.lang.reflect.InvocationTargetException]
Application.java
public class Application extends Controller {
.........
public static class Login
{
public String email;
public String password;
public String validate()
{
if (User.authenticate(email, password) == null) {
return "Invalid user or password";
}
return null;
}
}
public static Result authenticate()
{
Form<Login> loginForm = form(Login.class).bindFromRequest(); //--- error
if(loginForm.hasErrors()) {
return badRequest(login.render(loginForm));
} else {
session("email", loginForm.get().email);
return redirect(
routes.Application.index()
);
}
}
}
我知道它与Login Class中的validate函数有关,因为当我在validate函数中删除对User.authenticate的调用时,它可以正常工作。但我无法弄明白。
用户类为 -
@Entity
public class User extends Model
{
@Id
@Constraints.Required
@Formats.NonEmpty
public String userId;
@OneToOne(cascade=CascadeType.PERSIST)
AccountDetails accDetails;
public static Model.Finder<String,User> find = new Model.Finder<String,User>(String.class, User.class);
// Authenticate the user details
public static User authenticate(String email, String password)
{
String tempId = AccountDetails.authenticate(email, password).userId;
return find.ref(tempId);
}
.. . . . . . .
}
和AccountDetails类 -
@Entity
public class AccountDetails extends Model
{
@Id
String userId;
@Constraints.Required
String emailId;
@Constraints.Required
String password;
public static Model.Finder<String,AccountDetails> find =
new Model.Finder<String,AccountDetails>(String.class, AccountDetails.class);
public static AccountDetails authenticate(String email, String password)
{
return find.where()
.eq("email", email)
.eq("password", password)
.findUnique();
}
}
答案 0 :(得分:4)
我必须承担很多,但如果这是你的stacktrace的样子:
play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.reflect.InvocationTargetException]]
at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10.jar:2.2.3]
at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10.jar:2.2.3]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10.jar:2.2.3]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10.jar:2.2.3]
at scala.Option.map(Option.scala:145) [scala-library.jar:na]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:264) [play_2.10.jar:2.2.3]
...
Caused by: java.lang.NullPointerException: null
at models.User.authenticate(User.java:26) ~[na:na]
at controllers.Application$Login.validate(Application.java:50) ~[na:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05]
然后问题的原因实际上是由您的User类中的NPE暗示的。 如果您输入伪造凭证,您的查找程序将找不到任何内容并在AccountDetails.authenticate()中返回null。
所以在下面的方法中你不检查null并尝试获取userId,这会导致NPE:
public static User authenticate(String email, String password) {
String tempId = AccountDetails.authenticate(email, password).userId;
return find.ref(tempId);
}
如果您只是正确检查null,您将获得所需的功能:
public static User authenticate(String email, String password) {
User user = null;
AccountDetails accountDetails = AccountDetails.authenticate(email, password);
if (accountDetails != null) {
user = find.ref(accountDetails.userId);
}
return user;
}