I'm using renderJSON(Object)
to return some objects as JSON values, and it's working fine except for one field. Is there an easy way to add in that one field without having to manually create the whole json template?
-
Since I got very confused by this Q&A and it is not clearly stated: __This question is specific to Play 1.x__ – bluenote10 Sep 07 '14 at 20:58
3 Answers
Play uses GSON to build the JSON string. If your one field is a specific object type, then you can easily do this by providing a customised serialisation for that type. See the documentation here
http://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ
However, if it is an Integer class for example, that you want to work in one way for one, and another way for another, then you may have a little more difficulty.
Example
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(SpecificClass.class, new MySerializer());
private class MySerializer implements JsonSerializer<DateTime> {
public JsonElement serialize(SpecificClass src, Type typeOfSrc, JsonSerializationContext context) {
String res = "special format of specificClass"
return new JsonPrimitive(res);
}
}

- 54,176
- 10
- 96
- 129
-
1The Version 2.2 now use jackson : http://www.playframework.com/documentation/2.2.x/JavaJsonRequests – Thibaut Jan 03 '14 at 09:29
-
The question pre-dated Play 2, and the renderJSON method is specific to play 1.x, therefore the GSON answer is still valid. – Codemwnci Jan 03 '14 at 15:13
Simply do a
JsonElement elem = new Gson().toJsonTree(yourObject);
JsonObject obj = elem.getAsJsonObject();
obj.remove("xxx");
obj.addProperty("xxx", "what you want");
// other stuff ...
renderJSON(obj.toString());
etc.

- 27,415
- 11
- 90
- 112

- 1,820
- 12
- 18
After evaluating the play framework we hit a stumbling block and decision choice on serializing JSON for an external API. Allot of articles out there suggest using the Lift framework within play which just seem like extra overhead.After trying some of the frameworks / modules with in the play framework a college and myself decided to write a light weight code block that could cater for our needs.
case class User (
user_id: Int,
user_name: Option[String],
password: Option[String],
salt: Option[String]
) extends Serializable {
def toXml =
<user>
<user_id>{user_id}</user_id>
<user_name>{user_name.getOrElse("")}</user_name>
</user>
override def toJson =
"{" + JSON.key("user_id") + JSON.value(user_id) + ", " + JSON.key("user_name") + JSON.value(user_name) + "}"
}
class Serializable {
def toJson = ""
}
object JSON {
def key(x:String) = value(x) + ": "
def value(x:Any):String = {
x match {
case s:String => "\"" + s + "\""
case y:Some[String] => value(y.getOrElse(""))
case i:Int => value(i.toString)
case s:Serializable => s.toJson
case xs:List[Any] => "[" + xs.map(x => value(x)).reduceLeft(_ + ", " + _) + "]"
}
}
}
def searchUserByName(user_name: String) = {
(for (
u <- Users if u.user_name.like(("%"+user_name+"%").bind)
) yield u.*)
.list
.map(User.tupled(_))
}
def toXml(users:List[User]) = {
<users>
{ users.map(u => u.toXml) }
</users>
}
def toJson(users:List[User]) = {
"[" + users.map(u => u.toJson).reduceLeft(_ + ", " + _) + "]"
}
And from the controller.
// -- http://localhost:9000/api/users/getUser/xml
// -- http://localhost:9000/api/users/getUser/json
def getUser(requestType:String) = {
db withSession{
val user = Users.byUserName("King.Kong")
if(requestType == "xml") {
Xml(user.toXml)
} else {
user.toJson
}
}
}
//--- http://localhost:9000/api/users/searchuser/xml
//--- http://localhost:9000/api/users/searchuser/json
def searchUser(requestType:String) = {
db withSession{
val users = Users.searchUserByName("Doctor.Spoc")
if(requestType == "xml") {
Xml(Users.toXml(users))
} else {
val jsonList = Users.toJson(users)
Json(jsonList)
}
}

- 178
- 2
- 4