Play框架:[运行时异常:java.lang.reflect.InvocationTargetException]

8

我正在尝试创建一个简单的基于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类中的验证函数有关,因为当我在验证函数中删除对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();
    }

}

没有导入声明,没有异常堆栈跟踪,只有片段代码。除非你已经处理过这样的问题,否则回答这样的问题是非常困难的。 - user2813148
1个回答

4

我必须进行一些假设,但如果您的堆栈跟踪看起来像这样:

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中得到提示。

如果您输入虚假凭据,则您的finder将找不到任何内容并在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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接