开发者

Play framework FORM binding to Set instead of List

开发者 https://www.devze.com 2023-04-10 10:29 出处:网络
Is there any way to properly bind to a Set on a form? I\'m doing POJO binding and my controller takes in a User object

Is there any way to properly bind to a Set on a form?

I'm doing POJO binding and my controller takes in a User object

public static void create(User user)

user.java

public class User implements Serializable {



    public Long id;

    @Required
    @Email
    public String email;

    public Set<Group> groups;

}

Group.java

    public class Group implements Serializable {

        public Long id;

        public String name;

    }

I can't seem to get my field to bind to groups

i've tried user.groups[].id, user.groups[0].id, user.groups.id. I can get it to work with 开发者_Python百科a list just fine but when it posts I get a list of N elements with a bunch of null items (one null for each checkbox that was not checked) and I could just create a new list without the nulls but that seems wrong.

Edit: User and Group are not meant to be persistent entities, Play is merely acting as a stateless and persistent-less presentation layer for a restful API


The new Binder implementation of Play 1.2.4 allows this.

In Play versions earlier to 1.2.4 (released December 02, 2011) you could not bind a set by sending parameters like

user.groups[1].id = 1
user.groups[1].name = "name1"
user.groups[3].id = 3
user.groups[3].name = "name3"
user.groups[4].id = 4
user.groups[4].name = "name4"

The problem with binding to a List is that you will get a List of length 5 where the value at 0 and 2 is null.

If you still need to use Play version minor than 1.2.4, a workaround for this problem could be using

Map<String, Group> groups

instead of Set or List. Then you won't get null elements in between and you will get Collection by calling groups.values().


First, since User and Group seems to be Entity, you should extend the play.db.jpa.Model class and also define it as an @Entity. For example:

@Entity
public class User extends Model {

    ...

}

Thanks to the extension of Model, you do not need to define the technical ID (i.e. you can remove the public Long id), and you will have a generic DAO for this class (see the Javadoc)

Now, you have to define the groups of User like that:

@ManyToMany
public Set<Group> groups;


I have similiar issue with Play. Play's binding is auto-magic, but sometimes you need to have to workarounds.

You can simply create a setter

public void setGroups(List<Group> groups)

And internally set the provided groups to your set. It is a bit dirty but will work.

I also recommend you to create a Unit test case to simulate the binding. Create a Map to simulate POST request and bind the map to your object to the Binder. It is much easier than repeating the process from web-interface, and it forms a regression test and alert you if Play's update break some of the binding behaviors (it happens to me).

0

精彩评论

暂无评论...
验证码 换一张
取 消