Java json parse - java

Well I've been trying for like 3 hours now. Using lots of apis it still doesn't work.
I'm trying to parse
{
"id": 8029390,
"uid": "fdABNhroHsr0",
"user": {
"username": "Skrillex",
"permalink": "skrillex"
},
"uri": "/skrillex/cat-rats",
"duration": 305042,
"token": "VgA2a",
"name": "cat-rats",
"title": "CAT RATS",
"commentable": true,
"revealComments": true,
"commentUri": "/skrillex/cat-rats/comments/",
"streamUrl": "http://media.soundcloud.com/stream/fdABNhroHsr0?stream_token=VgA2a",
"waveformUrl": "http://w1.sndcdn.com/fdABNhroHsr0_m.png",
"propertiesUri": "/skrillex/cat-rats/properties/",
"statusUri": "/transcodings/fdABNhroHsr0",
"replacingUid": null,
"preprocessingReady": null
}
in to an array/list.
Any help?

I'm using Jackson from http://codehaus.org/ and so far it has lived up to all my needs.
You don't quite deal with json as raw strings in an arraylist, but rather as POJOs, here's a quick example with a subset of your json.
public class JacksonExample {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
String text = "{ \"id\": 8029390, \"user\": { \"username\": \"Skrillex\" } }";
ObjectMapper mapper = new ObjectMapper();
Pojo pojo = mapper.readValue(text, Pojo.class);
System.out.println(pojo.id);
System.out.println(pojo.user.username);
}
}
class Pojo {
public String id;
public User user;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public User getUser() { return user; }
public void setUser(User user) { this.user = user; }
public static class User {
public String username;
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
}
}
The mapper creates a Pojo object with the values filled in. Then you can use that object for anything you need.
Here are a couple of links for the Jackson project:
http://jackson.codehaus.org/
http://wiki.fasterxml.com/JacksonInFiveMinutes
The latest all in one JAR is here:
http://jackson.codehaus.org/1.9.1/jackson-all-1.9.1.jar

You should try JavaJson from source forge... you can parse that this way:
JsonObject json = JsonObject.parse("...");
/*
* or also JsonObject.parse(inputStream);
*/
then you can get fields this way:
String title = json.getString("title");
String username = json.get("user", "username").toString();
and so on. here's the link: https://sourceforge.net/projects/javajson/

Related

How to keep the JSON's order preserved while sending to frontend application from SpringBoot Application's service?

I'm developing a springboot application.
I've a class with the following fields
class MyClass
{
String s1;
String s2;
String s3;
String s4;
//getters setters constructors
}
I'm calling an API which in turn calls a service.
public String myService()
{
JSONArray arr1 = new JSONArray();
for (Items item : itemsList)
{
JSONObject itemObj = new JSONObject();
itemObj.put("s1","Value1");
itemObj.put("s2","Value2");
itemObj.put("s3","Value3")
itemObj.put("s4","Value4");
arr1.put(itemObj);
}
JSONObject out = new JSONObject();
out.put("total_Items", arr1);
return out.toString(); // this is org.json.JSONObject
}
This way I'm able to get the excel with the reordered members as the columns when a button is clicked at the frontend angular app.
What I want is the order of the the members in the columns remains preserved when exporting into an excel sheet.
s1|s2|s3|s4 //as per the above example
I've many other services as well, which return different types of Objects(apart from the MyClass mentioned here) so I wanted to return the elements in the order defined (as per the order of members in the class) from the backend itself.
I know that JSON does not allow us to preserve the order as it internally uses a HASHMAP.
Is there a way to return a JSON response such that the order remains same as that of the class members?
I also tried using GSON in the below way.
public String myService()
{
MyClass itemsArray[] = new MyClass[itemsList.size()];
int i=0;
for (Items item : itemsList)
{
MyClass itemObj = new MyClass();
itemObj.setS1("Value1");
itemObj.setS2("Value2");
itemObj.setS3("Value3")
itemObj.setS4("Value4");
itemsArray[i]=itemObj;
}
Gson gson = new Gson();
return gson.toJson(itemsArray); // this is java.lang.String
}
In this scenario I'm able to get the API response(on POSTMAN) with the elements in ordered fashion but when exporting on the frontend angular app it freezes at the downloading screen.
I tried doing conversion to JSONObject and other things randomly but was not able to make the code work properly.
Is there anyway the problem can be resolved at the backend...or something needs to be done at the frontend only?
Thanks in advance.
If you want to do using DataStructure use LinkedHashMap as given below. It will serialize in inserted order.
public static void main(String args[]){
ObjectMapper mapper = new ObjectMapper();
Map<String, String> itemObj = new LinkedHashMap<>();
itemObj.put("s91","Value1");
itemObj.put("s2","Value2");
itemObj.put("s3","Value3");
itemObj.put("s4","Value4");
try {
String jsonString = mapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(itemObj);
System.out.println(jsonString);
}
catch (IOException e) {
e.printStackTrace();
}
}
{
"s91" : "Value1",
"s2" : "Value2",
"s3" : "Value3",
"s4" : "Value4"
}
If you want to serialize in sorted order the use TreeMap, it will serialize in sorted key
Map<String, String> itemObj = new TreeMap<>();
...
{
"s2" : "Value2",
"s3" : "Value3",
"s4" : "Value4",
"s91" : "Value1"
}
This can be done using Jackson library using the #JsonPropertyOrder annotation.
You can define the order of elements as given below above class
#JsonPropertyOrder({ "s3", "s2", "s1", "s4"})
Refer to below a working example
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.istack.NotNull;
import java.io.IOException;
import java.util.UUID;
#JsonPropertyOrder({ "id", "password", "name", "email", "enabled" })
public class UserResource {
private UUID id;
#NotNull
private String name;
#NotNull
private String email;
private boolean enabled;
private String password;
public UserResource(UUID id, String name, String email, boolean enabled, String password) {
this.id = id;
this.name = name;
this.email = email;
this.enabled = enabled;
this.password = password;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static void main(String args[]){
ObjectMapper mapper = new ObjectMapper();
try {
UserResource student = new UserResource(UUID.randomUUID(), "sheel", "sheel#c4c.com",true, "$$$$$$%%##^^$DSGHHH");
String jsonString = mapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(student);
System.out.println(jsonString);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
and output as given below
{
"id" : "fbfcd21d-731e-4acb-9fec-90a499e47cc9",
"password" : "$$$$$$%%##^^$DSGHHH",
"name" : "sheel",
"email" : "sheel#c4c.com",
"enabled" : true
}

Jackson: Ignore deserializing one property and leave it as list of strings [duplicate]

I've got a following JSON from API:
"hotel_data": {
"name": "Hotel Name",
"checkin_checkout_times": {
"checkin_from": "14:00",
"checkin_to": "00:00",
"checkout_from": "",
"checkout_to": "12:00"
},
"default_language": "en",
"country": "us",
"currency": "USD",
"city": "Miami"
}
I'm using Jackson library to deserialize this JSON to Java object. I don't want to create a special class for checkin_checkout_times object. I just want to get it as a plain text. Like this "checkin_from": "14:00", "checkin_to": "00:00", "checkout_from": "", "checkout_to": "12:00".
In my POJO for hotel_data this checkin_checkout_times should be as a string i.e.:
#JsonProperty("checkin_checkout_times")
private String checkinCheckoutTimes
Is this possible to get this part of the JSON as a plain text?
EDIT: Error that I'm getting com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String out of START_OBJECT token
at [Source: (String)...
Make use of JsonNode.
Just make the following setter for the field checkinCheckoutTimes in your POJO for hotel_data and it should work for you.
public void setCheckinCheckoutTimes(JsonNode node) {
this.checkinCheckoutTimes = node.toString();
}
Example
String str = "{ \"id\": 1, \"data\": { \"a\": 1 } }";
try {
System.out.println(new ObjectMapper().readValue(str,Employee.class));
} catch (IOException e) {
e.printStackTrace();
}
Where Employee is as follows:
class Employee
{
private int id;
private String data;
public Employee() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(JsonNode node) {
this.data = node.toString();
}
#Override
public String toString() {
return "Employee{" +
"id=" + id +
", data='" + data + '\'' +
'}';
}
}
gives the following output:
Employee{id=1, data='{"a":1}'}
You can also write a custom deserializer as described in the article:
public class RawJsonDeserializer extends JsonDeserializer<String> {
#Override
public String deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode node = mapper.readTree(jp);
return mapper.writeValueAsString(node);
}
}
and then use it with annotation in your class:
public class HotelData {
#JsonProperty("checkin_checkout_times")
#JsonDeserialize(using = RawJsonDeserializer.class)
private String checkinCheckoutTimes;
// other attributes
// getters and setters
}

Gson string with key

I am using Gson to get convert the object to json string, and its working fine but when I am sending that json to a webservice method using post, I have to add the post method's parameter name in the string.
Example:
jsonString I get from Gson new Gson().toJson(requestDataDTO) :
{
"req": {
"AppId": "2",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
},
"req1": {
"AppId": "-33",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
}
}
jsonString I want :
{
"requestDataDTO": {
"req": {
"AppId": "2",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
},
"req1": {
"AppId": "-33",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
}
}
}
for now I am adding this "requestDataDTO" string at the start of json string I got from Gson.
is there a way to achieve this ?
Assuming you have an object which looks somehow like this:
package com.dominikangerer.q25077756;
import com.google.gson.annotations.SerializedName;
public class RequestDataDTO {
// {"AppId":"2","ThirdParty":"3","UserId":"1","UserToken":"4"}
#SerializedName("AppId")
private String appId;
#SerializedName("ThirdParty")
private String thirdParty;
#SerializedName("UserId")
private String userId;
#SerializedName("UserToken")
private String userToken;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getThirdParty() {
return thirdParty;
}
public void setThirdParty(String thirdParty) {
this.thirdParty = thirdParty;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserToken() {
return userToken;
}
public void setUserToken(String userToken) {
this.userToken = userToken;
}
}
The easiest and also for me most readable solution would be to create an wrapper/container Class which contains a HashMap (key/value) like this:
package com.dominikangerer.q25077756;
import java.util.HashMap;
public class RequestDataDTOContainer {
private HashMap<String, RequestDataDTO> requestDataDTO = new HashMap<String, RequestDataDTO>();
public HashMap<String, RequestDataDTO> getRequestDataDTO() {
return requestDataDTO;
}
public void setRequestDataDTO(HashMap<String, RequestDataDTO> requestDataDTO) {
this.requestDataDTO = requestDataDTO;
}
public void putRequestDataDTO(String key, RequestDataDTO value){
this.requestDataDTO.put(key, value);
}
}
To run it simply test it with a main like this:
// enable pretty printing
Gson gson = new GsonBuilder().setPrettyPrinting().create();
// too lazy to fill the objects by hand
String reqJson = "{\"AppId\":\"2\",\"ThirdParty\":\"3\",\"UserId\":\"1\",\"UserToken\":\"4\"}";
String req1Json = "{\"AppId\":\"-33\",\"ThirdParty\":\"3\",\"UserId\":\"1\",\"UserToken\":\"4\"}";
// deserialize it with gson
RequestDataDTO req = gson.fromJson(reqJson, RequestDataDTO.class);
RequestDataDTO req1 = gson.fromJson(req1Json, RequestDataDTO.class);
// initiliaze the container
RequestDataDTOContainer container = new RequestDataDTOContainer();
// adding the 2 req objects with the certain key
container.putRequestDataDTO("req", req);
container.putRequestDataDTO("req1", req1);
// Print it as pretty json
System.out.println(gson.toJson(container));
You are now more flexibility if you want to add more meta information like a whole meta object or similar without adding a hardcoded String to that json.
You can find the whole Example in this github repository: Java Stackoverflow Answers by DominikAngerer

http 400 bad request exception for converting json to java object representation

When I attempt to send json to server I receive http 400 bad request exception.
The format of the json is :
{
"role": "home",
"name": "group1: False, group2: False"
}
The java class to represent this json is :
public class Params {
private String role;
private String[] name;
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
public String getRole() {
return profileRuleName;
}
public void setRole(String role) {
this.role = role;
}
}
Is this format of the java class correct in order to represent this json ?
You can construct an array in JSON like this:
{
"role": "home",
"name": ["group1","group2"]
}
Here's a link to the JSON format that shows arrays (and objects and everything else)
http://json.org

Using Jackon ObjectMapper to map to array of classes, alongside other fields?

I have some Json in the following form:
"items": [
{
"id": 1,
"text": "As a user without a subscription, I get a choice of available ones.",
"status": "finished",
"tags": [
{
"id": 1234,
"name": "feature=subs"
},
{
"id": 1235,
"name": "epic=premium"
}
]
},
{
"id": 2,
...
There are more fields but I have ommitted them for clarity.
I am trying to map each story to a Story Class with fields ID, Text, Status and a list of Tags. I've got it working fine using the following:
public Project JsonToProject(byte[] json) throws JsonParseException, JsonMappingException, IOException
{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JsonNode rootNode = mapper.readValue(json, JsonNode.class);
int storyCount = rootNode.get("totalItems").asInt();
ArrayNode itemsNode = (ArrayNode) rootNode.get("items");
Project project = new Project();
for (int i = 0; i < storyCount; i++)
{
Story story = JsonToStory(rootNode.get(i));
project.addStory(story);
}
return project;
}
Where a project is simple an ArrayList of Stories, and JsonToStory is the following method:
public Story JsonToStory(JsonNode rootNode) throws JsonParseException, JsonMappingException, IOException
{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Story story = mapper.readValue(rootNode, Story.class);
return story;
}
The Story Class is as follows:
public class Story {
private int id;
private String text = new String();
private String status = new String();
private final List<Tag> tags = new ArrayList<Tag>();
public void setId(int i)
{
id = i;
}
public void setText(String s)
{
text = s;
}
public void setStatus(String s)
{
status = s;
}
public void setTags(Tag[])
{
???
}
}
with the get methods and print methods. The Tag Class simply contains two string fields.
I don't know how to structure the setTags method, in order to result in an arraylist of Tag objects, and haven't been able to find anything to help.
Thanks!
You have marked your tags as final, which will probably block the setter from setting the tags. You can try this:
public class Story {
private int id;
private String text = new String();
private String status = new String();
private List<Tag> tags;
public void setTags(List<Tag> tags){
this.tags = tags;
}
OR
public class Story {
private int id;
private String text = new String();
private String status = new String();
private Tag[] tags;
public void setTags(Tag[] tags){
this.tags = tags;
}

Categories

Resources