What can be a sample JSON payload for my object structure? - java

I'm new to JSON hence the answer to my question would be a huge help!
I have an enum like below:
enum Error
{
private final String message;
INVALID("failed"),
VALID("succeeded");
Error(String message){
this.message = message;
}
}
And my class is like:
class Response {
String id;
Error error;
}
How do I create a sample JSON payload for this?

If you instantiate and serialize you class using Gson, you will get a JSON string that is the exactly payload you are looking for.
For example, if you execute this:
Response r = new Response();
r.id="AA";
r.error = Error.INVALID;
Gson defaultGson = new Gson();
System.out.println(defaultGson.toJson(r));
you will get
{"id":"AA","error":"INVALID"}
Of course, you could use alternative way to serialize/deserialize your enum like asked here

Related

Convert multiple Java Beans to JSON

I have multiple Java bean classes that are associated to each other (JSON Array + JSON Object) since they have a nested structure.
There are about 10 classes. Is there a way to collectively convert these classes or at-least one by one?
I had created these classes out of a JSON data which I don't have access to right now.
So, now, what I'm looking forward is to create a dummy JSON out of those classes.
Using GSON, I tried converting one of these Bean classes however, I got an empty result. Here is one of the beans called Attachment.java.
Attachment.java
package mypackagename;
import java.io.Serializable;
public class Attachment implements Serializable{
private Payload payload;
private String type;
public Payload getPayload() {
return payload;
}
public void setPayload(Payload payload) {
this.payload = payload;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Implementation
Gson gson = new Gson();
Attachment attachment = new Attachment();
String json = gson.toJson(attachment);
Sure you got an empty result. Because your JSON object is empty. You should add data to your object and test it again as below:
Attachment attachment = new Attachment(new Payload("Test Payload"), "Test attachment");
String json = new Gson().toJson(attachment);
Log.e("Test", "Json: " + json); // result: Json: {"payload":{"test":"Test Payload"},"type":"Test attachment"}
To avoid empty object, you have to set a default value to your payload and type becaus Gson will ignore any null value.
This section of the Gson User Guide: https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
The fourth bullet point explains how null fields are handled.

Java - Google GSON syntax error

So I'm trying to parse a request that comes in JSON format, but the Google GSON library throws a syntax error.
The request looks like this: {"action":"ProjectCreation", data:{"projectName": "test project"}}.
Which doesn't look like it has a syntax error to me...
Here is the error that GSON gives me:
Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 20 path $.
EDIT:
I fixed the syntax error in the JSON request, it now looks like this {"action":"ProjectCreation", "data":{"projectName": "test project"}}.
GSON is still throwing the same error....
EDIT:
The code responsible for parsing the request looks like this:
private Type type = new TypeToken<Map<String, Object>>(){}.getType();
private String action;
private String responseAction;
private Map<String, String> data;
private Type dataType = new TypeToken<Map<String, String>>(){}.getType();
private Gson gson = new Gson();
private String requestId;
private Client client = new Client("127.0.0.1", 5699);
/**
* Constructor for this class, sets initial parameters
* #param request
* #param _requestId
*/
public ActionThread(String request, String _requestId) {
System.out.println(request);
//Parse the request into a map
Map<String, Object> _request = gson.fromJson(request, type);
//Give action the correct naming convention
action = _request.get("action") + "Request";
responseAction = _request.get("action") + "Response";
//Parse the data into a map
String _data = _request.get("data").toString();
data = gson.fromJson(_data, dataType);
//Set the request id
requestId = _requestId;
}
_request.get("data").toString() is not the JSON representation of your data object. It's the string representation of the inner map you just parsed that is equal to {projectName=test project}.
One easy and quick way to solve this would be to convert your data object into its JSON representation and then parse it again:
Map<String, String> data = gson.fromJson(gson.toJson(_request.get("data")), dataType);
It might be worth to consider having dedicated classes as well, for instance:
class Action {
#SerializedName("action")
String name;
Data data;
}
class Data {
String projectName;
}
and then
Action action = gson.fromJson(request, Action.class);
If you want to have the nested data object as a field directly in the Action class you could also write a custom deserializer.

How to use Gson to parse multiple types of payloads

I am using GSON parser to parse Http Response with JSON format as:
{ "type" : "A1", "payload": <Format as per type A1> }
{ "type" : "A2", "payload": <Format as per type A2> }
.
.
.
I don't have control over JSON output as I am writting only http client
I have defined base class as:
class Base {
String type;
Object payload;
}
Gson g = new Gson();
Base baseObj = gson.fromJson(response, Base.class);
// Need to cast and access baseObj.payload to specific class
But now I want to cast "Object payload" to specific class and access its member variables
well for nested objects in a JSON response you don't control of, you have to write a deserializer. See for GSON specific implementation: https://stackoverflow.com/a/23071080/6471273.
In theory, I don't really recommend this, because it's hackish, but you could also make it work depending if its throw-away code by doing something simple like below.
class Baselike {
String type;
String payloadStr;
}
class Payload
{
public int foo; // whatever the format is
public String bar;
}
Gson g = new Gson();
Baselike baseObj = gson.fromJson(response, Baselike.class);
Payload payloadObj = gson.fromJson(baseObj.payloadStr, Payload.class);
You can use jackson to deserialize your json to class.
You can write something like this:
ObjectMapper objectMapper = new ObjectMapper();
SampleClass abc= objectMapper.readValue(jsonData, SampleClass .class);

Parse Json with com.fasterxml.jackson instead of org.json

I was wondering if it is possible to do this exact operation but with the jackson library.
String repo = response.toString();
JSONObject json = new JSONObject (repo);
String nameOfUser = json.getJSONObject(facebookID).getString("name");
Thank you,
Yes. Something like:
ObjectMapper mapper = new ObjectMapper(); // reuse, usually static final
JsonNode ob = mapper.readTree(response.toString()); // or from File, URL, InputStream, Reader
String nameOfUser = ob.path(facebookID).path("name").asText();
// note: '.get()' also works, but returns nulls, 'path()' safer
although even more convenient access is often done using JSON Pointer expressions, like:
String name = ob.at("/person/id").asText();
but I assume facebookID is an id from some other source.
UPDATE: as per comment below, structure you want may actually be POJO like:
public class Response {
public User facebookID;
}
public class User {
public String id;
public String email;
public String first_name;
// ... and so forth: fields and/or getter+setter
}
and then you can bind directly into class like so:
Response resp = mapper.readValue(response.toString(), Response.class);
String name = resp.facebookID.name;
So there's more than one way to do it with Jackson.

Parsing JSON object using jQuery and GSON returned by Spring controller

I was looking for some solution around here and I didnt find any correct answer to my question so I would like to ask you.
I have POJO with some simple attribs. and one List of another POJOs.
public class Standard implements Serializable {
private String id;
private String title;
private String description;
private Set<Interpretation> interpretations = new LinkedHashSet<Interpretation>();
}
public class Interpretation implements Serializable {
private String id;
private String title;
private String description;
}
In my controller class, I am returning Standard POJO with GSON.
#RequestMapping(value="/fillStandard", method= RequestMethod.GET)
public #ResponseBody String getStandard(#RequestParam String id) {
Standard s = DAOFactory.getInstance().getStandardDAO().findById(id);
return new Gson().toJson(s);
}
The question is, am I able to get the list of interpretations in my Standard POJO using jQuery ? Something like :
function newStandard() {
$.get("standard/fillStandard.htm", {id:"fe86742b2024"}, function(data) {
alert(data.interpretations[0].title);
});
}
Thanks a lot !
EDIT:
Well, thanks to #Atticus, there is solution of my problem. Hope that it will help somebody.
#RequestMapping(value="/fillStandard", method= RequestMethod.GET, produces="application/json")
public #ResponseBody Standard getStandard(#RequestParam String id) {
Standard s = DAOFactory.getInstance().getStandardDAO().findById(id);
return s;
}
Using #ResponseBody allows you to return the whole POJO, but you need to add produces="application/json" to your #RequestMapping annotation. Then you will be able to catch a returning object as JSON in jQuery like as I supposed.
function newStandard() {
$.get("standard/fillStandard.htm", {id:"idOfStandard"}, function(data) {
alert(data.id); //Standard id
alert(data.interpretations[0].title); //id of Interpretation on first place in array
});
Well you have to create and register your custom serializer.
It goes like this:
//You create your builder that registers your custom serializer with the class you want to serialize
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Standard.class, new StandardSerializer());
//Then you create your Gson object
Gson gson = builder.create();
//Then you pass your object to the gson like
Standard s = DAOFactory.getInstance().getStandardDAO().findById(id);
gson.toJson(s);
Your serializer looks like this:
public class StandardSerializer implements JsonSerializer<Standard>{
#Override
public JsonElement serialize(Standard src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
//You put your simple objects in like this
obj.add("id",new JsonPrimitive(src.getId()));
//You put your complex objects in like this
JsonObject interpretations = new JsonObject();
//Here you need to parse your LinkedHashSet object and set up the values.
//For the sake of simplicity I just access the properties (even though I know this would not compile)
interpretations.add("title", src.getInterpretation().getTitle());
obj.add("interpretations", interpretations);
return obj;
}
}
In this case your Json would look something like:
{"id":"idValue", "title":"titleValue", "description":"descriptionValue", "interpretations":["id":"interpretationIdValue"]}
Now, you can access your data with jQuery like this:
function newStandard() {
$.get("standard/fillStandard.htm", {id:"fe86742b2024"}, function(data) {
alert(data.interpretations.title);
});
}
I hope this helps.
EDIT:
I see that your response gets converted to the declared method argument type which is String (as stated here: 16.3.3.2 Supported method return types). But what you really want is your Standrad POJO converted to JSON. I am not very familiar with Spring but as I have read here (16.3.2.6 Producible Media Types) there is another, maybe easier solution. If you want to return a JSON object, then change the return type of the
getStandard method to Standard instead of String and add produces="application/json" to your #RequestMapping annotation. As far as I have read this should tell Spring that the return type should be converted to JSON. In this case you do not need to use Gson.

Categories

Resources