Java使用JSON播放复杂的数据绑定

时间:2014-09-20 14:00:40

标签: java angularjs playframework playframework-2.0

我在使用@OneToMany绑定和Java Play中的bindFromRequest方法时遇到问题。目前我有一个具有许多FinancialAsset模型的客户端模型

@Entity
public class Client extends Model {

...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "client")
public List<FinancialAsset> assetList;
...
}

以下是我的FinancialAsset模型的要点

@Entity
public class FinancialAsset extends Model {

@Id
public long id;

@ManyToOne(optional = false)
@JoinColumn(name="client", referencedColumnName = "id")
public Client client;

public enum AssetType {
    K401, ANNUITY, CASH, CD, GOLD, IRA, PARTNERSHIP, RENTAL_PROP, RETIREMENT_ACCT
}

public float totalValue;
public AssetType realAssetType;

public String financialInstitute;

public String description;

public void setRealAssetType (String assetTypeString) {
    this.realAssetType = AssetType.valueOf(assetTypeString);
}

public static List<AssetType> getAllAssetTypes() {
    List<AssetType> all = new ArrayList<AssetType>(Arrays.asList(AssetType.values()));
    return all;
}

public static Finder<Long,FinancialAsset> find = new Finder(Long.class, FinancialAsset.class);

public static List<FinancialAsset> allForClient(Client client) {
    return find.where().eq("clientId", client.id).findList();
}
}

当我的前端客户端(Angular.js)使用以下数据调用我的方法来更新客户端时:

{
    id: 1234,
    assetList: Array[1]
        assetType: "ANNUITY",
        totalValue: 50000,
        description: "blah",
        financialInstitue: "blahstitute",
    otherClientproperties: "..."
}

当我执行get()获取客户端时,它尝试bindFromRequest但是出错:

@BodyParser.Of(play.mvc.BodyParser.Json.class)
public static Result editClientJSON() {
    Logger.debug("Reached editClientJSON");
    Form<Client> clientForm = Form.form(Client.class);
    //Error is here on the get
    Client client = clientForm.bindFromRequest().get();

    client.update();
    Logger.debug("Client updated: " + client.name);
    response().setHeader(LOCATION, routes.ClientCtrl.getClientJSON(client.id).url());

    return ok();
}

错误输出:

play.api.Application$$anon$1: Execution exception[[IllegalStateException: No value]]
at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.1]
at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10.jar:2.1.1]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:144) [play_2.10.jar:2.1.1]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:140) [play_2.10.jar:2.1.1]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1]
java.lang.IllegalStateException: No value
at play.libs.F$None.get(F.java:540) ~[play_2.10.jar:2.1.1]
at play.data.Form.get(Form.java:525) ~[play-java_2.10.jar:2.1.1]
at controllers.ClientCtrl.editClientJSON(ClientCtrl.java:60) ~[na:na]
at Routes$$anonfun$routes$1$$anonfun$applyOrElse$14$$anonfun$apply$14.apply(routes_routing.scala:225) ~[na:na]
at Routes$$anonfun$routes$1$$anonfun$applyOrElse$14$$anonfun$apply$14.apply(routes_routing.scala:225) ~[na:na]
at play.core.Router$HandlerInvoker$$anon$6$$anon$2.invocation(Router.scala:164) ~[play_2.10.jar:2.1.1]

我的想法是它无法将assetList绑定到FinancialAsset模型。我不知道如何调试它或弄清楚它在寻找什么。

提前致谢!

2 个答案:

答案 0 :(得分:0)

这似乎是一个验证问题。您应该在从表单获取底层对象之前检查表单错误,因为绑定可能会失败并且可能没有要获取的底层对象。请尝试以下代码来检测并显示任何表单错误:

@BodyParser.Of(play.mvc.BodyParser.Json.class)
public static Result editClientJSON() {
    Logger.debug("Reached editClientJSON");
    Form<Client> clientForm = Form.form(Client.class).bindFromRequest();

    if(clientForm.hasErrors()) {//check out for form errors
        for (String errorKey : clientForm.errors().keySet()) {
            for (ValidationError error : clientForm.errors().get(errorKey)) {
                Logger.error(error.key() + " = " + error.message());                 
            }
        }
        return badRequest();
    }

    //There is no error on the form so it is now safe to get the Client
    Client client = clientForm.get();
    client.update();
    Logger.debug("Client updated: " + client.name);
    response().setHeader(LOCATION, routes.ClientCtrl.getClientJSON(client.id).url());

    return ok();
}

答案 1 :(得分:0)

此行为似乎是我正在使用的Play版本的错误,Play 2.1.1。我升级到2.3,问题得到了解决。非常令人沮丧。