Having issue collecting Json object and array with java - java

First of all, i am new to this so please pardon me. Have been working on a music app and I am trying to parse JSON code from a streaming link and display "artist" name and "title" of song to my app users. But i am having issues collecting the data.
Here is my JSON code from the streaming link:
{"type":"result","data":[{"title":"My Stream ","song":"Unknown - The Authorised One","track":{"artist":"Unknown Artist","title":"The Authorised One","album":"Unknown","royaltytrackid":181938.0000,"started":1498151105,"id":181938,"length":0,"playlist":{"id":3520,"title":"Rev Arome E. Adah"},"buyurl":"https:\/\/itunes.apple.com\/us\/album\/the-unknown-god\/id772022436?uo=4","imageurl":"http:\/\/is5.mzstatic.com\/image\/thumb\/Music5\/v4\/d7\/6d\/52\/d76d52df-db43-7130-0e37-62241ff50a21\/source\/100x100bb.jpg"},"bitrate":"128 Kbps","server":"Online","autodj":"Online","source":"Yes","offline":false,"summary":"<a href=\"http:\/\/cp9.serverse.com:2199\/tunein\/-stream\/svhxmwhp.pls\">Eloti Designs Stream - Unknown - The Authorised One<\/a>","listeners":0,"maxlisteners":1000,"reseller":0,"serverstate":true,"sourcestate":true,"sourceconn":1,"date":"Jun 22, 2017","time":"07:06 PM","rawmeta":"Unknown - The Authorised One ","mountpoint":"\/stream","tuneinurl":"http:\/\/209.133.216.3:7550\/stream","directtuneinurl":"","proxytuneinurl":"http:\/\/209.133.216.3\/proxy\/svhxmwhp?mp=\/stream","tuneinformat":"mp3","webplayer":"muses","servertype":"ShoutCast2","listenertotal":0,"url":"http:\/\/cp9.serverse.com:2199\/rpc"}]
I used this code to post "artist" name of "Unkwown Artist" to my text field but it didn't work for me.
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
JSONObject finalObject = parentArray.getJSONObject(0);
String songName = finalObject.getString("artist");
return songName;

track is a jsonobject containing artist and track is inside first jsonobject of
data array so fetch track then fetch artist from it
String songName = finalObject.getJSONObject("track").getString("artist");
{
"type":"result",
"data":[ // fetch JSONArray
{ // fetch first JSONObject
"title":"My Stream ","song":"Unknown - The Authorised One",
"track":{ // fetch track JSONObject
"artist":"Unknown .." // fetch string

Have you tried the jackson parser? It's super easy to use and can easily parse the string above. All you need to do is create 3/4 POJO classes that map your structure and then apply the readValue function of the Mapper to the outer class. Following is a small example with a List and one inner class:
import java.io.IOException;
import java.util.List;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
class OutterPojo {
public String aString;
public List<InnerPojo> aList;
public String getaString() {
return aString;
}
public void setaString(String aString) {
this.aString = aString;
}
public List<InnerPojo> getaList() {
return aList;
}
public void setaList(List<InnerPojo> aList) {
this.aList = aList;
}
#Override
public String toString() {
return new StringBuilder().append("{ #OutterPojo# ").append("aString:").append(aString).append(", ").append("aList:")
.append(aList).append(" }").toString();
}
}
class InnerPojo {
public String anotherString;
public String getanotherString() {
return anotherString;
}
public void setanotherString(String anotherString) {
this.anotherString = anotherString;
}
#Override
public String toString() {
return new StringBuilder().append("{ #InnerPojo# ").append("anotherString:").append(anotherString).append(" }")
.toString();
}
}
public class Test {
public static void main(String args[]) throws JsonParseException, JsonMappingException, IOException {
String jsonData = "{\"aString\":\"s\",\"aList\":[{\"anotherString\":\"ss\"},{\"anotherString\":\"sss\"}]}";
ObjectMapper objectMapper = new ObjectMapper();
OutterPojo testObject = objectMapper.readValue(jsonData, OutterPojo.class);
System.out.println(testObject);
}
}
As to dependencies all you need for this to work is jackson-core, jackson-databind and jackson-annotations - here's the link to maven:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core
Hope it helps! :)

Related

how to make java class behave like a normal object and list-of-object at runtime and as per need?

I have a simple class in java like below:
class Simple {
private String name;
private String email;
}
I want to have behaviour of java.util.List<Simple> and Simple both according to input data that my program receives.
i.e.
Case 1::
if my program receives below kind of json-array input
{"simple" : [ {"name":"a", "email" : "a#z.com"}, {"name":"b", "email" : "b#z.com"} ]}
I need to parse it using List<Simple>
Case 2::
if my program receives below kind of json-object input
{"simple" : {"name":"c", "email" : "c#z.com"} }
I need to parse it using Simple
Note: I have tried using JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, but the problem is it is basically converting single value also into json-array at the time of writing json.
I need to persist json as it is, is there any other way to achieve this?
To avoid any Jackson customisation I would create wrapper class with an Object simple property. We can add two extra checking methods and two extra casting methods. It will allow Jackson to do it's logic and in runtime we can check what actually we have:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
public class DateApp {
private final static JsonMapper JSON_MAPPER = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build();
public static void main(String[] args) throws Exception {
Simple object = new Simple("John", "john#doe.com");
SimpleWrapper wrapper = new SimpleWrapper();
wrapper.setSimple(object);
serializeAndDeserialize(wrapper);
wrapper.setSimple(Collections.singletonList(object));
serializeAndDeserialize(wrapper);
}
private static void serializeAndDeserialize(SimpleWrapper wrapper) throws JsonProcessingException {
String json = JSON_MAPPER.writeValueAsString(wrapper);
System.out.println("JSON:");
System.out.println(json);
wrapper = JSON_MAPPER.readValue(json, SimpleWrapper.class);
System.out.println("Wrapper:");
System.out.println(wrapper);
}
}
#Data
class SimpleWrapper {
private Object simple;
#JsonIgnore
public boolean isSimpleObject() {
return simple instanceof Simple;
}
#JsonIgnore
public boolean isSimpleList() {
return simple instanceof List;
}
#JsonIgnore
public Simple getSimpleAsObject() {
return (Simple) simple;
}
#JsonIgnore
public List<Simple> getSimpleAsList() {
return (List<Simple>) simple;
}
}
#Data
#NoArgsConstructor
#AllArgsConstructor
class Simple {
private String name;
private String email;
}
Above code prints:
JSON:
{
"simple" : {
"name" : "John",
"email" : "john#doe.com"
}
}
Wrapper:
SimpleWrapper(simple={name=John, email=john#doe.com})
JSON:
{
"simple" : [ {
"name" : "John",
"email" : "john#doe.com"
} ]
}
Wrapper:
SimpleWrapper(simple=[{name=John, email=john#doe.com}])
You can use JsonNode.isArray() (or JsonNode.isObject()) to perform this check.
Then you can parse the node into a list with ObjectReader.readValue() or into a POJO using ObjectMapper.treeToValue().
String myJson = """
{"simple" : {"name":"c", "email" : "c#z.com"} }
""";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(myJson);
if (node.isArray()) {
ObjectReader reader = mapper.readerFor(new TypeReference<List<Simple>>() {});
List<Simple> list = reader.readValue(node);
// do something with a list
} else {
Simple pojo = mapper.treeToValue(node, Simple.class);
// do something else with a single object
}
Jackson is able to parse any json into a map where value is any object. you can then inquire on the type of the map value
Map<String, Object> map = new ObjectMapper().readValue(jsonInput, Map.class);
Object value = map.get("simple");
if (value instanceof Collection) { // will return false for null
Collection<Simple> simples = (Collection<Simple>)value;
}
else if (value instanceof Simple) {
Simple simple = (Simple)value;
}
else {
System.err.println("unrecognized");
}
You only need to read the first node, simple and check if it is an array - using isArray() method.
public class Main{
public static void main(String args[]) {
//String inputString = [your input];
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(inputString);
JsonNode simpleNode = root.findPath("simple");
if(simpleNode.isArray()) {
//you have an array
} else {
// you have an element
}
}
}

JSON text to Java conversion issue with random number generation

For example my JSON text is coming like this.
"pages":{"42010":{"pageid":42010,"ns":0,"title":"Queen (band)"}}
Because everytime my json text is coming with different number which is inside pages tag.
How do i convert this to Java equivalent class?
Currently my generated java class is something like this.
#Generated("org.jsonschema2pojo")
public class Pages {
#SerializedName("42010")
#Expose
private _42010 _42010;
}
That _42010 class contains the inner fields like "pageid":42010,"ns":0,"title":"Queen (band)", since i am getting everytime new number inside pages, its not working. its working only for the specific json text.
You can use a custom deserialiser that ignored the changing number. For example:
package jacksonTest;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class CustomDeserialiser {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
String json = "{\"42010\":{\"pageid\":42010,\"ns\":0,\"title\":\"Queen (band)\"}}";
String json2 = "{\"12345\":{\"pageid\":12345,\"ns\":0,\"title\":\"Queen (band)\"}}";
Gson g = new GsonBuilder().registerTypeAdapter(Pages.class, new PagesDeserialiser()).create();
Pages fromJson = g.fromJson(json, Pages.class);
System.out.println(fromJson);
fromJson = g.fromJson(json2, Pages.class);
System.out.println(fromJson);
}
public static class PagesDeserialiser implements JsonDeserializer<Pages> {
#Override
public Pages deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws com.google.gson.JsonParseException {
JsonObject object = json.getAsJsonObject();
Pages p = new Pages();
object.entrySet().forEach( e -> {
JsonObject tmp = e.getValue().getAsJsonObject();
if(tmp.get("pageid") != null) {
// right object
p._42010 = new _42010();
p._42010.ns = tmp.get("ns").getAsInt();
p._42010.pageid = tmp.get("pageid").getAsInt();
p._42010.title = tmp.get("title").getAsString();
}
});
return p;
}
}
public static class Pages {
_42010 _42010;
#Override
public String toString() {
return _42010.toString();
}
}
public static class _42010 {
int pageid;
int ns;
String title;
#Override
public String toString() {
return title + " " + pageid + " " + ns;
}
}
}
The deserialiser for type pages simply checks the entries to find the one that contains a pageId and then populates the class.
Running my test gives you:
Queen (band) 42010 0
Queen (band) 12345 0
I am assuming that you are using Gson as your json library.
Regards,
Artur
Why do not use an JSON library like jackson or org.json?
Make your json correct like
{
"pages":{
"42010":{
"pageid":42010,
"ns":0,
"title":"Queen (band)"
}
}
}
And you will be able to use it like :
JSONObject jsonObjet = new JSONObject(yourJson);
jsonObjet.get("pages");
Ideally it should be using Map.
This helps in forming the values as Map<Integer, Pojo>.
Lets say
public class Pojo{
private int pageid;
private String title;
private int ns;
// getter and setter
}
This suffices the requirement of holding the random digits, generated at runtime,

How to extract array values within nested JSON data

I have JSON data in the following format:
{
"data": {
"id": 14810798216415,
"name": "crescentbahuman.com",
"is_organization": true,
"email_domains": [
"crescentbahuman.com"
]
}
}
I want to get the string in the "email_domains" field. I wrote the following code as my attempt:
JSONObject dataObject2= (JSONObject)jsonObject2.get("data");
long id = (long) dataObject2.get("id");
System.out.println("worksapce id is: " + id);
String name = (String) dataObject2.get("name");
System.out.println("The worksapce name is: " + name);
boolean is_organization = (boolean) dataObject2.get("is_organization");
System.out.println("The workspace is organization: " + is_organization);
JSONArray email_domains = (JSONArray) jsonObject2.get("email_domains");
Iterator<String> iterator = email_domains.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
In this code to get "email_domains" only, a JSON Array object is created that get data from the JSON object and then its iterator is used to get values from within the array. However, it throws a NullPointerException on this line:
Iterator<String> iterator = email_domains.iterator();
I am stuck due to this problem. Can anyone kindly suggest a solution?
If you are using the JSON library from http://www.json.org/java/, then you should not be using JSONObject.get() so frequently. The library has other methods to get specific types, such as getLong(), getJSONArray(), and so forth. For your case with the "email_domains" field, you should try:
JSONArray array = dataObject2.getJSONArray("email_domains");
String value = array.getString(0);
org.json.JSONArray email_domains = (org.json.JSONArray) json.get("email_domains");
int length = email_domains.length();
for(int i = length-1; i > 0; i--) {
org.json.JSONObject jsonData = (org.json.JSONObject) email_domains.get(i);
System.out.println(jsonData);
}
My solution? I hate to be someone to offer a solution in another library... but look into google collections and the Gson helper. It can turn your Json into a map for you, and then back to json again when you are done.
Map map = gson.fromJson(jsonText, Map.class);
JsonArray's can then be cast into List's
try this to fetch "email_domains"
JSONArray email_domains = ((JSONArray) jsonObject).get("email_domains");
or
JSONObject obj = new JSONObject(jsonObject.Tostring());
JSONArray email_domains = obj.optJSONArray("email_domains");
"email_address" is JSONArray so we need to fetch this like
JSONArray email_domains = (JSONArray) dataObject2.getJSONArray("email_domains");
email_domains.get(0); // this will return crescentbahuman.com
Use this implementation
import java.lang.reflect.Field;
import java.util.List;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonConvertor {
private static GsonBuilder gsonBuilder;
private static Gson gson;
private JsonConvertor() {
}
public static Object fromJson(String json, Class clz)
{
gson=new Gson();
return gson.fromJson(json,clz);
}
public static String toJson(Object obj) {
gsonBuilder = new GsonBuilder();
gsonBuilder = gsonBuilder
.addSerializationExclusionStrategy(new CustomIclusionStrategy(
obj.getClass()));
gson = gsonBuilder.create();
String json = gson.toJson(obj);
return json;
}
}
class CustomIclusionStrategy implements ExclusionStrategy {
private Class classToIclude;
private Field[] declaredFields;
private List<FieldAttributes> fields;
public CustomIclusionStrategy(List<FieldAttributes> fields) {
this.fields = fields;
}
public CustomIclusionStrategy(Class classToIclude) {
this.classToIclude = classToIclude;
this.declaredFields=classToIclude.getDeclaredFields();
}
// called only if shouldSkipClass returns false
#Override
public boolean shouldSkipField(FieldAttributes f) {
try {
classToIclude.getSuperclass().getDeclaredField(f.getName());
System.out.println(f.getName());
return true;
} catch (Exception e) {
}
return false;
}
#Override
public boolean shouldSkipClass(Class<?> clazz) {
// if returns false shouldSkipField will be called, otherwise
//shouldSkipField will not be called
return false;
}
}
public class Org {
private Data data;
public Org(Data data) {
super();
this.data = data;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String toJson()
{
return JsonConvertor.toJson(this);
}
public static void main(String[] args) {
String json="{\"data\": {\"id\":\"1\",\"name\":\"org1\",\"is_organization\":true,\"email_domains\": [\"email1\",\"email2\",\"email3\",\"email4\"]}}";
Org o=(Org) JsonConvertor.fromJson(json, Org.class);
System.out.println(o.getData().getEmail_domains());
}
}

Deserialize a JSON response with Gson containing a field of variable type

The responses of a REST API always return a JSON with the following structure:
{
"status": "<status_code>",
"data": <data_object>
}
My problem is that the value of data doesn't have an unique type, but it can be a String, a JSON Object or a JSON Array, depending on the called endpoint. I can't figure out how to deserialize it in the right way to create the different Java objects...
For example, I've already prepared some POJOs: the root element
public class ApiResult {
#SerializedName("status")
public String status;
#SerializedName("data")
public JsonElement data; // should I define it as a JsonElement??
}
and two objects that reflects two of the endpoints:
// "data" can be a list of NavItems
public class NavItem {
#SerializedName("id")
public String id;
#SerializedName("name")
public String name;
#SerializedName("icon")
public String icon;
#SuppressWarnings("serial")
public static class List extends ArrayList<NavItem> {}
}
and
// "data" can be a single object representing a Profile
public class Profile {
#SerializedName("id")
public String id;
#SerializedName("fullname")
public String fullname;
#SerializedName("avatar")
public String avatar;
}
Reading some StackOverflow questions, I've seen I should use the JsonDeserializer<T> interface. But how if the type of data in ApiResult is variable?
You should use a a custom JsonDeserializer and write all your logic there, like this
ApiResult.java
public class ApiResult {
#SerializedName("status")
public String status;
#SerializedName("data")
public Object data;
}
ApiResultDeserializer.java
import java.lang.reflect.Type;
import java.util.List;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
public class ApiResultDeserializer implements JsonDeserializer<ApiResult> {
private Type listType = new TypeToken<List<NavItem>>(){}.getType();
#Override
public ApiResult deserialize(JsonElement value, Type type,
JsonDeserializationContext context) throws JsonParseException {
final JsonObject apiResultJson = value.getAsJsonObject();
final ApiResult result = new ApiResult();
result.status = apiResultJson.get("status").getAsString();
JsonElement dataJson = apiResultJson.get("data");
if(dataJson.isJsonObject()) {
result.data = context.deserialize(dataJson, NavItem.class);
} else if(dataJson.isJsonPrimitive()) {
result.data = context.deserialize(dataJson, String.class);
} else if(dataJson.isJsonArray()) {
result.data = context.deserialize(dataJson, listType);
}
return result;
}
}
and try to create different kinds of data (List, Object, or String) as you mentioned
Main.java
Gson gson = new GsonBuilder()
.registerTypeAdapter(ApiResult.class, new ApiResultDeserializer())
.create();
List<NavItem> navItems = new ArrayList<NavItem>();
for(int i = 1 ; i < 6 ; ++i) {
navItems.add(new NavItem(i+"", "Name-" + i, "Icon-" + i ));
}
ApiResult result = new ApiResult();
result.status = "OK";
result.data = navItems;
// Serialization
System.out.println(gson.toJson(result)); // {\"status\":\"OK\",\"data\":[{\"id\":\"1\",\"name\":\"Name-1\",\"icon\":\"Icon-1\"},{\"id\":\"2\",\"name\":\"Name-2\",\"icon\":\"Icon-2\"},{\"id\":\"3\",\"name\":\"Name-3\",\"icon\":\"Icon-3\"},{\"id\":\"4\",\"name\":\"Name-4\",\"icon\":\"Icon-4\"},{\"id\":\"5\",\"name\":\"Name-5\",\"icon\":\"Icon-5\"}]}
result.data = navItems.get(0);
System.out.println(gson.toJson(result)); // {\"status\":\"OK\",\"data\":{\"id\":\"1\",\"name\":\"Name-1\",\"icon\":\"Icon-1\"}}
result.data = "Test";
System.out.println(gson.toJson(result)); // {\"status\":\"OK\",\"data\":\"Test\"}
// Deserialization
String input = "{\"status\":\"OK\",\"data\":[{\"id\":\"1\",\"name\":\"Name-1\",\"icon\":\"Icon-1\"},{\"id\":\"2\",\"name\":\"Name-2\",\"icon\":\"Icon-2\"},{\"id\":\"3\",\"name\":\"Name-3\",\"icon\":\"Icon-3\"},{\"id\":\"4\",\"name\":\"Name-4\",\"icon\":\"Icon-4\"},{\"id\":\"5\",\"name\":\"Name-5\",\"icon\":\"Icon-5\"}]}";
ApiResult newResult = gson.fromJson(input, ApiResult.class);
System.out.println(newResult.data); // Array
input = "{\"status\":\"OK\",\"data\":{\"id\":\"1\",\"name\":\"Name-1\",\"icon\":\"Icon-1\"}}";
newResult = gson.fromJson(input, ApiResult.class);
System.out.println(newResult.data); // Object
input = "{\"status\":\"OK\",\"data\":\"Test\"}";
newResult = gson.fromJson(input, ApiResult.class);
System.out.println(newResult.data); // String
I managed to make it work as I wanted, and without using any custom deserializer!
For each endpoint, I wait for the response (btw I'm using Volley), then I first generate the "root" ApiResult object, check if the status is OK, then I proceed instantiating the data field as the requested type.
The POJOs are the same of the question. In ApiResult, "data" is a JsonElement.
// ... called the endpoint that returns a NavItem list
public void onResponse(String response) {
ApiResult rootResult = gson.fromJson(response.toString(), ApiResult.class);
if (rootResult.status.equals(STATUS_OK)) {
Log.d(LOG_TAG, response.toString());
NavItem.List resData = gson.fromJson(rootResult.data, NavItem.List.class); // <-- !!!!!
callback.onSuccess(resData);
}
else {
Log.e(LOG_TAG, response.toString());
callback.onError(-1, null);
}
}
Obviously the only thing to change for the "Profile" endpoint is the line with !!!!!

Converting Java objects to JSON with Jackson

I want my JSON to look like this:
{
"information": [{
"timestamp": "xxxx",
"feature": "xxxx",
"ean": 1234,
"data": "xxxx"
}, {
"timestamp": "yyy",
"feature": "yyy",
"ean": 12345,
"data": "yyy"
}]
}
Code so far:
import java.util.List;
public class ValueData {
private List<ValueItems> information;
public ValueData(){
}
public List<ValueItems> getInformation() {
return information;
}
public void setInformation(List<ValueItems> information) {
this.information = information;
}
#Override
public String toString() {
return String.format("{information:%s}", information);
}
}
and
public class ValueItems {
private String timestamp;
private String feature;
private int ean;
private String data;
public ValueItems(){
}
public ValueItems(String timestamp, String feature, int ean, String data){
this.timestamp = timestamp;
this.feature = feature;
this.ean = ean;
this.data = data;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getFeature() {
return feature;
}
public void setFeature(String feature) {
this.feature = feature;
}
public int getEan() {
return ean;
}
public void setEan(int ean) {
this.ean = ean;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return String.format("{timestamp:%s,feature:%s,ean:%s,data:%s}", timestamp, feature, ean, data);
}
}
I just missing the part how I can convert the Java object to JSON with Jackson:
public static void main(String[] args) {
// CONVERT THE JAVA OBJECT TO JSON HERE
System.out.println(json);
}
My Question is: Are my classes correct? Which instance do I have to call and how that I can achieve this JSON output?
To convert your object in JSON with Jackson:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(object);
I know this is old (and I am new to java), but I ran into the same problem. And the answers were not as clear to me as a newbie... so I thought I would add what I learned.
I used a third-party library to aid in the endeavor: org.codehaus.jackson
All of the downloads for this can be found here.
For base JSON functionality, you need to add the following jars to your project's libraries:
jackson-mapper-asl
and
jackson-core-asl
Choose the version your project needs. (Typically you can go with the latest stable build).
Once they are imported in to your project's libraries, add the following import lines to your code:
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
With the java object defined and assigned values that you wish to convert to JSON and return as part of a RESTful web service
User u = new User();
u.firstName = "Sample";
u.lastName = "User";
u.email = "sampleU#example.com";
ObjectMapper mapper = new ObjectMapper();
try {
// convert user object to json string and return it
return mapper.writeValueAsString(u);
}
catch (JsonGenerationException | JsonMappingException e) {
// catch various errors
e.printStackTrace();
}
The result should looks like this:
{"firstName":"Sample","lastName":"User","email":"sampleU#example.com"}
Just follow any of these:
For jackson it should work:
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
//will return json in string
For gson it should work:
Gson gson = new Gson();
return Response.ok(gson.toJson(yourClass)).build();
You could do this:
String json = new ObjectMapper().writeValueAsString(yourObjectHere);
This might be useful:
objectMapper.writeValue(new File("c:\\employee.json"), employee);
// display to console
Object json = objectMapper.readValue(
objectMapper.writeValueAsString(employee), Object.class);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json));
You can use Google Gson like this
UserEntity user = new UserEntity();
user.setUserName("UserName");
user.setUserAge(18);
Gson gson = new Gson();
String jsonStr = gson.toJson(user);
Well, even the accepted answer does not exactly output what op has asked for. It outputs the JSON string but with " characters escaped. So, although might be a little late, I am answering hopeing it will help people! Here is how I do it:
StringWriter writer = new StringWriter();
JsonGenerator jgen = new JsonFactory().createGenerator(writer);
jgen.setCodec(new ObjectMapper());
jgen.writeObject(object);
jgen.close();
System.out.println(writer.toString());
Note: To make the most voted solution work, attributes in the POJO have to be public or have a public getter/setter:
By default, Jackson 2 will only work with fields that are either
public, or have a public getter method – serializing an entity that
has all fields private or package private will fail.
Not tested yet, but I believe that this rule also applies for other JSON libs like google Gson.
public class JSONConvector {
public static String toJSON(Object object) throws JSONException, IllegalAccessException {
String str = "";
Class c = object.getClass();
JSONObject jsonObject = new JSONObject();
for (Field field : c.getDeclaredFields()) {
field.setAccessible(true);
String name = field.getName();
String value = String.valueOf(field.get(object));
jsonObject.put(name, value);
}
System.out.println(jsonObject.toString());
return jsonObject.toString();
}
public static String toJSON(List list ) throws JSONException, IllegalAccessException {
JSONArray jsonArray = new JSONArray();
for (Object i : list) {
String jstr = toJSON(i);
JSONObject jsonObject = new JSONObject(jstr);
jsonArray.put(jsonArray);
}
return jsonArray.toString();
}
}

Categories

Resources