I really like the form in playframework, but I noticed something strange when I have a class that has a Map<>
field Map<>
import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.annotate.JsonSetter; import org.codehaus.jackson.map.annotate.JsonDeserialize; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) public class GameState { private String roomId = ""; private String woohoo = ""; @JsonDeserialize(as = LinkedHashMap.class, contentAs = Integer.class, keyAs = String.class) private Map<String, Integer> players = new HashMap<String, Integer>(); @JsonProperty("players") public Map<String, Integer> getPlayers() { return players; } @JsonSetter("players") public GameState setPlayers(Map<String, Integer> players) { this.players = players; return this; } public String getRoomId() { return roomId; } public GameState setRoomId(String roomId) { this.roomId = roomId; return this; } public String getWoohoo() { return woohoo; } public GameState setWoohoo(String woohoo) { this.woohoo = woohoo; return this; } }
In my controller, I have the following static form:
static Form<GameState> gameForm = new Form<GameState>(GameState.class);
and then I do the following:
@BodyParser.Of(BodyParser.Json.class) public static Result testAction() { Form<GameState> form = gameForm.bindFromRequest(); if (!form.hasErrors()) { GameState s = form.get(); if (!s.getPlayers().isEmpty()) { return ok(); } else { return badRequest("Need players!"); } } else { return badRequest("Wrong format!"); } }
This de-serializes any other field ( List<>
and Set<>
included when I had classes with such fields), but NOT Map<>
. It is strange that it works for:
GameState s = Json.fromJson(request().body().asJson(), GameState.class);
Here is the curl call that I use to validate the action
curl -X POST http://localhost:9000/game/end/1 --data '{"roomId": "someid", "woohoo": "something", "players" : { "oliver" : "0" } }' -H 'Content-Type: application/json'
I am using Play 2.1. It also doesn't matter if I have @ BodyParser.Of () or not in this action.
Question : Is there a way to make form.get()
correctly?