Serializing JSON string to object - java

I am trying to parse through a JSON string and convert it to the following POJO:
package apicall;
//POJO representation of OAuthAccessToken
public class OAuthAccessToken {
private String tokenType;
private String tokenValue;
public OAuthAccessToken(String tokenType,String tokenValue) {
this.tokenType=tokenType;
this.tokenValue=tokenValue;
}
public String toString() {
return "tokenType="+tokenType+"\ntokenValue="+tokenValue;
}
public String getTokenValue() {
return tokenValue;
}
public String getTokenType() {
return tokenType;
}
}
In order to do this I have written the following code:
Gson gson=new Gson();
String responseJSONString="{\"access_token\" : \"2YotnFZFEjr1zCsicMWpAA\",\"token_type\" : \"bearer\"}";
OAuthAccessToken token=gson.fromJson(responseJSONString, OAuthAccessToken.class);
System.out.println(token);
When I run the code, I get the following output:
tokenType=null
tokenValue=null
Instead of
tokenType=bearer
tokenValue=2YotnFZFEjr1zCsicMWpAA
I don't understand if there's anything I've done wrong. Please help.

You can get the expected result by annotating your fields like:
#SerializedName("token_type")
private final String tokenType;
#SerializedName("access_token")
private final String tokenValue;

How is Gson supposed to know how to populate your object? You don't have a no-arg constructor, and the fields of your object don't match the fields in the JSON object.
Make your object as following:
public class OAuthAccessToken {
private String accessToken;
private String tokenType;
OAuthAccessToken() {
}
...
}

The class should have the exact field name as the json, so if your json have 2 keys: "access_token" and "token_type", the class should have 2 fields:
private String access_token;
private String token_type;
And, of course you need to change the getters/setters accordingly.

Related

Jackson ObjectMapper readValue() unrecognized field when parsing to Object

I am creating simple rest client in Java/Spring. My request has been consumed properly by remote service and I got the response String something:
{"access_token":"d1c9ae1b-bf21-4b87-89be-262f6","token_type":"bearer","expires_in":43199,"grant_type":"client_credentials"}
The code below is the Object where I want to bind values from Json Response
package Zadanie2.Zadanie2;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Token {
String access_token;
String token_type;
int expiresIn;
String grantType;
//////////////////////////////////////////////////////
public Token() {
/////////////////////////////////
}
/////////////////////////////////////////////////////
public void setAccessToken(String access_token) {
this.access_token=access_token;
}
public String getAccessToken() {
return access_token;
}
////////////////////////////////////////////////
public void setTokenType(String token_type) {
this.token_type=token_type;
}
public String getTokenType() {
return token_type;
}
//////////////////////////////////////////////////////
public void setExpiresIn(int expiresIn) {
this.expiresIn=expiresIn;
}
public int getExpiresIn() {
return expiresIn;
}
//////////////////////////////////////////////////////////
public void setGrantType(String grantType) {
this.grantType=grantType;
}
public String getGrantType() {
return grantType;
}
}
all the time I am getting "unrecognized field access_token" but when I add objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
then access_token will be null
jsonAnswer=template.postForObject(baseUriAuthorize, requestEntity, String.class);
System.out.println(jsonAnswer);
Token token=objectMapper.readValue(jsonAnswer, Token.class);
System.out.println(token.getAccessToken());
I tried with #JsonProperty annotations. I tried with changing field by for example "#JsonProperty(accessToken)" because I thought there is an issue with "_" sign in variable name. I added getters and setters. Maybe there is a problem with the version I use but I don't think so because I am using "com.fasterxml.jackson.core"
You tried with "#JsonProperty(accessToken)". But your json contains access_token. how it works?
Try with this class:
public class Token {
#JsonProperty("access_token")
String accessToken;
#JsonProperty("token_type")
String tokenType;
int expiresIn;
String grantType;
//getter setter
}
Your setters do not match with the JSON key.
To read it correctly, you should change your setters to:
setAccess_token()
setToken_type()
...
But honestly, this is so ugly.
Try following the Java bean name convention and customize the JSON key with #JsonProperty:
public class Token {
#JsonProperty("access_token")
String accessToken;
....
}

toJson() of GSON library returning wrong json

I am using GSON library to pass json to server as header.
But it is not generating my expected json.
My Pojo class "TestRequest.java" is like:
public class TestRequest {
private String mobileNumber;
public TestRequest(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
}
Here is my code to call the GSON class to make json:
Gson gson = new Gson();
TestRequest tt = new TestRequest("+8801913000000");
String json = gson.toJson(tt);
My expected json is :
{"mobileNumber":"+8801913000000"}
But I am getting:
{"aIf":"+8801913000000"}
Note: This code was working perfectly 2 days before.
Try to change your pojo class like
public class TestRequest implements Serializable {
#SerializedName("mobileNumber")
private String mobileNumber;
public TestRequest(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
}
Let me know if not work

JSON.decodeValue Decode Exception

I want to make this java code works:
RequestManager rm = Json.decodeValue(request.getBodyAsString(), RequestManager.class);
But i have this error:
io.vertx.core.json.DecodeException: Failed to decode:No suitable constructor found for type [simple type, class RequestManager]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: {"messageId":"fsdfsdf"}; line: 1, column: 2]
And here the code of my class :
public class RequestManager {
private String messageId;
private String messageContent;
public RequestManager(String messageId, String messageContent) {
this.messageId = messageId;
this.messageContent = messageContent;
}
public String getMessageId() {
return messageId;
}
public String getMessageContent() {
return messageContent;
}
}
I really don't know why it's not working and there is only few topics about it, but they were irrelevant.
Someone can help ?
EDIT--
I know have the RequestManager class like this:
public class RequestManager {
private String messageId;
private String messageContent;
public RequestManager(String messageId, String messageContent) {
this.messageId = messageId;
this.messageContent = messageContent + "check";
}
public RequestManager() {
}
public String getMessageId() {
return messageId;
}
public String getMessageContent() {
return messageContent;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public void setMessageContent(String messageContent) {
this.messageContent = messageContent;
}
}
But know when i try to print the fields of my RequestManager object created with the JSON.decodeValue it's return me null. I've already done that in the past and had the same error. I think it's because the empty constructor is used instead.
I still don't really understand....
EDIT--2
I have tried to change my class again, here it is:
#JsonIgnoreProperties(ignoreUnknown=true)
public class RequestManager {
#JsonProperty("messageId") private String messageId;
#JsonProperty("messageContent") private String messageContent;
#JsonCreator
public RequestManager(#JsonProperty("messageId") String messageId, #JsonProperty("messageContent") String messageContent) {
this.messageId = messageId;
this.messageContent = messageContent;
System.out.println("This constructor is used.");
}
public RequestManager() {
}
public String getMessageId() {
return messageId;
}
public String getMessageContent() {
return messageContent;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public void setMessageContent(String messageContent) {
this.messageContent = messageContent;
}
}
And this is in my main :
final RequestManager rm = Json.decodeValue("{\"messageId\":\"themessage\"}", RequestManager.class);
System.out.println(rm.getMessageContent());
"{\"messageId\":\"themessage\"}" = the JSON format, i'm sure of it because decodeValue would return a Decode Exception if it wasn't.
Now the field is "nullcheck" when i print it. So it means that the constructor is well used but the fields are nulls. Where am i doint it wrong ?
You could try to have an empty constructor.
It's because you have your own constructor, and JSON doesn't know what values should be passed into it.
There is documentation on their GitHub page explaining how to set up a data object that you expect to be given to you as JSON and converted to Java.
https://github.com/vert-x3/vertx-codegen#data-objects
As per the example that you linked to: http://vertx.io/blog/some-rest-with-vert-x/, notice how they explicitly provide a constructor that takes no arguments, and public setter methods
Whisky()
setName(String name)
setOrigin(String origin)
The alternative is to provide annotations: https://github.com/FasterXML/jackson-annotations. You can choose how to do it, using annotation if you want, or using a bean class (getters and setters). Annotation has the advantage that you can say things like "ignore this value when you convert to JSON", etc. You can be more explicit with annotation. I would recommend picking one and staying with it. Consistency becomes important as your projects grow.

How to access JSON subfield using #JsonProperty annotation?

I need transform json in another diferent json , im using #JsonProperty annotation for change name fields JSON result , but i dont know access fields encapsulate in differents json level for example :
{ "prop1" : "value1",
"prop2" : "value2",
"prop3" : {
"prop4" : "value4",
"prop5" : {
"prop6" : "value6"
}
}
}
json result
{
"prop1_new_name":"value1",
"prop4_new_name":"value4",
"prop6_new_name":"value6"
}
This seems like a continuation of your previous question. So, in addition of using #JsonUnwrapped as explained in the answer, you need to add #JsonProperty on the field in the class where it is declared. Modifying the previous answer with #JsonProperty gives you this:
#RunWith(JUnit4.class)
public class Sample {
#Test
public void testName() throws Exception {
SampleClass sample = new SampleClass("value1", "value2", new SubClass("value4", "value5", new SubSubClass("value7")));
new ObjectMapper().writeValue(System.out, sample);
}
#JsonAutoDetect(fieldVisibility=Visibility.ANY)
public static class SampleClass {
private String prop1;
private String prop2;
#JsonUnwrapped
private SubClass prop3;
public SampleClass(String prop1, String prop2, SubClass prop3) {
this.prop1 = prop1;
this.prop2 = prop2;
this.prop3 = prop3;
}
}
#JsonAutoDetect(fieldVisibility=Visibility.ANY)
public static class SubClass {
#JsonProperty("prop4_new_name")
private String prop4;
private String prop5;
#JsonUnwrapped
private SubSubClass prop6;
public SubClass(String prop4, String prop5, SubSubClass prop6) {
this.prop4 = prop4;
this.prop5 = prop5;
this.prop6 = prop6;
}
}
#JsonAutoDetect(fieldVisibility=Visibility.ANY)
public static class SubSubClass{
#JsonProperty("prop7_new_name")
private String prop7;
public SubSubClass(String prop7) {
this.prop7 = prop7;
}
}
}
With this as a result:
{"prop2":"value2","prop5":"value5","prop7_new_name":"value7","prop4_new_name":"value4","prop1_new_name":"value1"}
"prop3" would be a Map in your Java object when deserializing (if you have it properly annotated). Then you can create a custom JsonSerializer to output your expected result.
To create your custom JsonSerializer, you can follow this guide: http://dev.sghill.net/2012/04/how-do-i-write-jackson-json-serializer.html

Json string to java object

I'm having following class
public class ReturnData {
public ReturnData() {
OperationResult = Result.Failed;
Messages = "An Error Occured";
UpdateAvailable = "0";
ResultData = "";
}
public Result OperationResult;
public String Messages;
public String UpdateAvailable;
public Object ResultData;
}
I'm having json string like,
{"OperationResult":0,"Messages":"","UpdateAvailable":"","ResultData":{"SessionId":"3b44a524-fc2a-499b-a16e-6d96339a6b5b","UserName":"admin","AccoundId":null,"Roles":["Administrator"],"DisplayName":"Admin","Status":3,"Type":1}}
I want to assign this json string to above class.I'm using GSON for assign json string to java object.In normal class i can assign json string to java object. But for this class i couldn't assign directly. Please any one help me,
Now i'm assigning like,
String formatedjsonstring = {json string};
Log.i("FORMAT STRING:",formatedjsonstring);
Gson gson = new Gson();
ReturnData returndata = (ReturnData) gson.fromJson(
formatedjsonstring, ReturnData.class);
You could use JavaJson from sourceforge. You could pass your json string to JsonObject .parse().
Try this
JsonObject json = JsonObject .parse("{\"OperationResult\":0, \"Messages\":\"UpdateAvailable\"");
System.out.println("OperationResult=" + json.get("OperationResult"));
System.out.println("Messages=" + json.get("Messages"));
https://sourceforge.net/projects/javajson/
Since your Java class doesn't resemble your JSON in any way, shape or form ... you're going to have a problem with that.
Problem #1: OperationResult should be an int
Problem #2: You're declared ResultData as an Object ... Java doesn't work like that.
You need your POJO to match the JSON:
public class ReturnData {
public ReturnData() {
OperationResult = Result.Failed;
Messages = "An Error Occured";
UpdateAvailable = "0";
ResultData = "";
}
public int OperationResult;
public String Messages;
public String UpdateAvailable;
public MyResultData ResultData;
}
class MyResultData {
public String SessionId;
public String UserName;
public String AccountId;
public List<String> Roles;
public String DisplayName;
public int Status;
public int Type;
}
ReturnData rd = new Gson().fromJson(jsonString, ReturnData.class);
I'd also consider using Gson's #SerializedName("name") annotation to convert the PascalCase field names in your JSON to camelCase field names in Java.
#SerializedName("OperationResult") public int operationResult;
Try this:
java.lang.reflect.Type type = new TypeToken<ReturnData>(){}.getType();
ReturnData rd = new Gson().fromJson(jsonString, type);

Categories