Playframework:

我正在尝试基于Zentask示例 – zentask – playframework创建一个简单的登录,但是当我单击调用Application.authenticate操作的登录按钮时,它会给出运行时exception。 我用 – 错误标记了这一行

[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 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 find = new Model.Finder(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 find = new Model.Finder(String.class, AccountDetails.class); public static AccountDetails authenticate(String email, String password) { return find.where() .eq("email", email) .eq("password", password) .findUnique(); } } 

我必须承担很多,但如果这是你的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,您将获得所需的function:

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