How to parse input stream using net.sf.json library - json

Following is the response in Json i am getting after making get request to Http API Format,
[{"name":"test","tracing":false},{"name":"dyn1","tracing":false},
{"name":"dyn2","tracing":false},{"name":"esb","tracing":false}]
Could you please post a sample code to parse this json object to get individual Host object with name and tracing.
Thanks,
Amol

String myDataAsAString = "[{\"name\":\"test\",\"tracing\":false},{\"name\":\"dyn1\",\"tracing\":false},
{\"name\":\"dyn2\",\"tracing\":false},{\"name\":\"esb\",\"tracing\":false}]";
JSONArray hostArray = JSONArray.fromObject(myDataAsAString);
for(int i = 0; i < hostArray.size(); i++)
{
JSONObject hostObject = hostArray.getJSONObject(i);
String hostName = hostObject.getString("name");
boolean tracing = hostObject.getBoolean("tracing");
...your code for each element here
}

You can yse GSON library http://code.google.com/p/google-gson/
Try:
import com.google.gson.Gson;
public class Test {
public static void main(String[] args){
String json = "[{'name':'test','tracing':false},{'name':'dyn1','tracing':false},\n" +
"{'name':'dyn2','tracing':false},{'name':'esb','tracing':false}]";
HostObj[] hostObjects = new Gson().fromJson(json, HostObj[].class);
}
class HostObj {
private String name;
private boolean tracing;
HostObj() {
}
public String getName() {
return name;
}
public void setName(String name) {
name = name;
}
public boolean isTracing() {
return tracing;
}
public void setTracing(boolean tracing) {
tracing = tracing;
}
}
}

Related

Getting json data from Spoonacular in Android Studio

trying to get to an Android App random recipes from Spoonacular. For some reason, I'm not getting the data from the json. I know how to do this in Javascript, but that's no use to me in Java.
My repository file:
public class RecipeRepository {
private static final String API_KEY = "472f31ce4a5e4e5792ca9ab6d1833e51";
private static final String URL = "https://api.spoonacular.com/recipes/random?apiKey=%s";
private final Application application;
private final MutableLiveData<ArrayList<Recipe>> recipeLiveData;
private final ArrayList<Recipe> arrayList = new ArrayList<>();
public RecipeRepository(Application application) {
this.application = application;
recipeLiveData = new MutableLiveData<>();
}
public void getDayRecipe() {
Ion.with(application)
.load(String.format(URL,API_KEY)).asJsonObject()
.setCallback((e, result) -> {
Log.i( "getRandomRecipe",result.getAsJsonPrimitive().toString());
parseResults(result);
});
}
public String removeAbles(String text) {return text.substring(1,text.length()-1); }
private void parseResults(JsonObject result) {
JsonObject randomRecipe = (JsonObject) result.getAsJsonArray("recipes").get(0);
String title = String.valueOf(randomRecipe.get("title"));
String instructions = String.valueOf(randomRecipe.get("Instructions"));
//ingredients
//image
recipeLiveData.setValue(arrayList);
}
public MutableLiveData<ArrayList<Recipe>> getRecipeLiveData() {
return recipeLiveData;
}
}
I get a 'variable is never used' with title, instructions and removeAbles

Node.js equivalent for GSON Json creation?

I have a Java class in a servlet that uses GSON to render posted JSON Strings into a Java object. The beauty of the approach is, that GSON filters out all JSON elements that don't match a class property, so I never end up with JSON content that I don't want to process. The servlet's doPost (simplified) looks like this:
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
PrintWriter out = null;
try {
InputStream in = request.getInputStream();
Demo d = Demo.load(in);
in.close();
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
out = response.getWriter();
out.println(d.toJson);
} catch (Exception e) {
e.printStackTrace();
out.println(e.getMessage());
}
out.close();
}
The Demo class (and that's the one I need to recreate in common.js or node.js looks like this:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Demo implements Serializable {
public static Demo load(InputStream in) {
Demo result = null;
try {
Gson gson = new GsonBuilder().create();
result = gson.fromJson(new InputStreamReader(in), Demo.class);
} catch (Exception e) {
result = null;
}
return result;
}
#TypeDiscriminator
#JsonProperty("_id")
private String id = UUID.randomUUID().toString();
private Date created = new Date();
private String color;
private String name;
private String taste;
public String getColor() {
return this.color;
}
public String getName() {
return this.name;
}
public String getTaste() {
return this.taste;
}
public Date getCreated() {
return this.created;
}
public String getId() {
return this.id;
}
public void setName(String name) {
this.name = name;
}
public void setTaste(String taste) {
this.taste = taste;
}
public void setColor(String color) {
this.color = color;
}
public String toJson() {
GsonBuilder gb = new GsonBuilder();
gb.setPrettyPrinting();
gb.disableHtmlEscaping();
Gson gson = gb.create();
return gson.toJson(this);
}
}
Obviously I stripped out all the processing logic and the servlet just echos the JSON back, which is not what the app does, but serves to illustrate the point. I can throw pretty any String in a HTTP Post at that example and I only get valid Demo objects.
How would I do something like this in node.js?
Node.js is Javascript so has built in support for json. You can use JSON.parse to convert from string to json and wrap in try catch block.
To only include select properties there is no built in feature in node that I know of unless you are using Mongodb with mongoose, but you could do following: Have a "class" that is an object containing all properties that you want and delete those from parsed json object that are not in that "class" object.
var class = {x: null, y:null};
for(var prop in object){
if (!class.hasOwnProperty (prop)) {
delete object [prop]
}
It would be best to use this class as object and expose parseJSON function to encapsulate this functionality

GSON throwing “Expected BEGIN_OBJECT but was STRING

This is Json Object
[
{
"UserId":"demouser1",
"Catagories":[
{
"CatagoryName":"Entertainment",
"Persent":"25"
},
{
"CatagoryName":"Household",
"Persent":"25"
},
{
"CatagoryName":"Movie",
"Persent":"25"
},
{
"CatagoryName":"Misc",
"Persent":"25"
}
],
"RequestId":null,
"ResponseStatus":false,
"Token":null
}
]
Used The Following approach to parse the above Json
public class CategoryEntity {
private String CatagoryName;
private String Persent;
public String getCatagoryName() {
return CatagoryName;
}
public void setCatagoryName(String catagoryName) {
CatagoryName = catagoryName;
}
public String getPersent() {
return Persent;
}
public void setPersent(String persent) {
Persent = persent;
}
}
import java.util.List;
public class Entity {
private String UserId;
public String getUserId() {
return UserId;
}
public void setUserId(String userId) {
UserId = userId;
}
public List<CategoryEntity> getListCatagories() {
return ListCatagories;
}
public void setListCatagories(List<CategoryEntity> listPMMCatagories) {
ListCatagories = listPMMCatagories;
}
public String getRequestId() {
return RequestId;
}
public void setRequestId(String requestId) {
RequestId = requestId;
}
public boolean isResponseStatus() {
return ResponseStatus;
}
public void setResponseStatus(boolean responseStatus) {
ResponseStatus = responseStatus;
}
private List<CategoryEntity> ListCatagories;
private String RequestId;
private String Token;
public String getToken() {
return Token;
}
public void setToken(String token) {
Token = token;
}
private boolean ResponseStatus;
}
And
Following approach to convert the json object to corresponding object
Gson gson =new Gson();
JsonPrimitive listCatagoriesElement= element.getAsJsonPrimitive();
System.out.println("listCatagoriesElement.getAsString()>>"+listCatagoriesElement.getAsString());
sysout prints: listCatagoriesElement.getAsString()>>[{"UserId":"user1","ListCatagories":[{"CatagoryName":"Entertainment","Persent":"25"},{"CatagoryName":"Household","Persent":"25"},{"CatagoryName":"Movie","Persent":"25"},{"CatagoryName":"Misc","Persent":"25"}],"RequestId":null,"ResponseStatus":false,"Token":null}]
Entity entity = gson.fromJson(listCatagoriesElement, Entity.class);
Any ideas how should I fix it?
Thanks!
Your class CategoryEntity is correct, but in your class Entity, the attribute ListCatagories should be called Catagories to match the name in the JSON!
Apart from that, in order to parse the JSON you'd better do something like this:
Gson gson = new Gson();
Type listType = new TypeToken<List<Entity>>() {}.getType();
List<Entity> entities = gson.fromJson(yourJsonString, listType);
So you'll have a List containing just one Entity object, and you can access the values just with:
String catagoryNameI = entities.get(0).getCatagories().get(i).getCatagoryName();
String persentI = entities.get(0).getCatagories().get(i).getPersent();
You have to do this because your whole JSON response is an array, surrounded by [ ... ], so you need to parse it into some List...

Create JSON using GSON with a colon as part of a field's name

I've created a set of classes (pojos) that need to be transformed into json. because i have a constraint that json field names adhere to a certain format, i've settled on gson as my library of choice, as it allows for annotations of field names.
so, i have json field names like asset_type, preview_image_thumbnail, etc. along with that, any metadata fields must have the format, metadata:<metadata-field-name>.
so, what this comes down to is that my metadata:tags and metadata:site annotations will not be transformed by gson, since they are not valid json field names, according to gson, at least.
all works well, except for those darned metadata field names. my goal is to have output like the following:
{
"name": "Test Remote Asset",
"description": "test-remote-asset",
"asset_type": "remote_asset",
"duration": 172360,
"stream_urls": {
"flash": "http://www.test-site.com/videos/a-video.flv",
"iphone": "http://www.test-site.com/videos/a-video.3gp",
"ipad": "http://www.test-site.com/videos/a-video.3gp",
"source_file": "http://www.test-site.com/videos/a-video.mp4"
},
"metadata:tags": "tag1,tag2,tag3",
"metadata:site": "test-site"
}
here is the exception i get when attempting to transform my class to json:
java.lang.IllegalArgumentException: metadata:tags is not a valid JSON field name.
and here is the class i want to transform:
public class RemoteAsset {
/** The video's name **/
private String name;
/** The video's description **/
private String description;
/** The video asset type **/
#SerializedName("asset_type")
private String assetType;
/** The video's duration, in milliseconds **/
private long duration;
/** The video's thumbnail preview URL **/
#SerializedName("preview_image_url")
private String previewImageUrl;
/** The video's OpenCms Structure ID **/
#SerializedName("external_id")
private String externalId;
/** The video's various streaming URLs **/
#SerializedName("stream_urls")
private StreamUrls streamUrls;
/** The video's tags, coma-separated **/
#SerializedName("metadata:tags")
private String metadataTags;
/** The video's host site **/
#SerializedName("metadata:site")
private String metadataSite;
public String getMetadataTags() {
return metadataTags;
}
public void setMetadataTags(String metadata_tags) {
this.metadataTags = metadata_tags;
}
public String getMetadataSite() {
return metadataSite;
}
public void setMetadataSite(String metadata_site) {
this.metadataSite = metadata_site;
}
public RemoteAsset() {
this.streamUrls = null;
this.assetType = null;
this.previewImageUrl = "";
this.metadataSite = "";
this.metadataTags = "";
this.externalId = "";
this.description = "";
this.duration = 0L;
this.name = "";
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public String getAssetType() {
return this.assetType;
}
public void setAssetType(ASSET_TYPE asset_type) {
this.assetType = asset_type.getTypeName();
}
public long getDuration() {
return this.duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public String getPreviewImageUrl() {
return this.previewImageUrl;
}
public void setPreviewImageUrl(String preview_image_url) {
this.previewImageUrl = preview_image_url;
}
public String getExternalId() {
return this.externalId;
}
public void setExternalId(String external_id) {
this.externalId = external_id;
}
public StreamUrls getStreamUrls() {
return this.streamUrls;
}
public void setStreamUrls(StreamUrls stream_urls) {
this.streamUrls = stream_urls;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("RemoteAsset [name=").append(this.name)
.append(", description=").append(this.description)
.append(", assetType=").append(this.assetType)
.append(", duration=").append(this.duration)
.append(", previewImageUrl=").append(this.previewImageUrl)
.append(", externalId=").append(this.externalId)
.append(", streamUrls=").append(this.streamUrls).append("]");
return builder.toString();
}
}
The problem is that those can't be mapped directly to Java variables because you can't have a colon in a variable name. You need to use the Gson #SerializedName annotation. The following works at least in Gson version 2.2.2:
public static void main( String[] args )
{
String json = "{\"some:field\":\"foo\"}";
Gson gson = new Gson();
MyClass mc = gson.fromJson(json, MyClass.class);
json = gson.toJson(mc);
System.out.println(json);
}
class MyClass
{
// String some:field; <- You can do that!
#SerializedName("some:field")
String someField;
}
Output:
{"some:field":"foo"}

Unmarshalling JSON array via Jettison/Resteasy

Ran into a similar problem like the following forum post:
http://jersey.576304.n2.nabble.com/parsing-JSON-with-Arrays-using-Jettison-td5732207.html
Using Resteasy 2.0.1GA with Jettison 1.2 and getting a problem marshalling arrays when involving namespace mappings. See code below. Basically if the number of array entries are greater than one and namespace mappings are used. Anybody else run into this problem? The Nabble form poster got around it by writing a custom unmarshaller.
I either need to isolate the Jettison bug or write a Resteasy extension of the JettisonMappedUnmarshaller class (which hands over the namespace mappings and unmarshaller to the Jettison Configuration).
The following code doesn't unmarshall (post step) if the properties variables contains 2 or more entries.
public class Experimenting {
#Path("test")
public static class MyResource {
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Property", propOrder = { "name", "value" })
public static class MyProperty {
#XmlElement(name = "Name", required = true)
protected String name;
#XmlElement(name = "Value", required = true)
protected String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
#XmlType(name = "MyElement", propOrder = { "myProperty" })
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "MyElement", namespace = "http://www.klistret.com/cmdb/ci/commons")
#Mapped(namespaceMap = { #XmlNsMap(namespace = "http://www.klistret.com/cmdb/ci/commons", jsonName = "com.klistret.cmdb.ci.commons") })
public static class MyElement {
#XmlElement(name = "MyProperty", namespace = "http://www.klistret.com/cmdb/ci/commons")
protected List myProperty;
public List getMyProperty() {
if (myProperty == null) {
myProperty = new ArrayList();
}
return this.myProperty;
}
public void setMyProperty(List myProperty) {
this.myProperty = myProperty;
}
}
#GET
#Path("myElement/{id}")
#Produces(MediaType.APPLICATION_JSON)
public MyElement getMy(#PathParam("id")
Long id) {
MyElement myElement = new MyElement();
MyProperty example = new MyProperty();
example.setName("example");
example.setValue("of a property");
MyProperty another = new MyProperty();
another.setName("another");
another.setValue("just a test");
MyProperty[] properties = new MyProperty[] { example, another };
myElement.setMyProperty(Arrays.asList(properties));
return myElement;
}
#POST
#Path("/myElement")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public MyElement createMy(MyElement myElement) {
List properties = myElement.getMyProperty();
System.out.println("Properties size: " + properties.size());
return myElement;
}
}
private Dispatcher dispatcher;
#Before
public void setUp() throws Exception {
// embedded server
dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addPerRequestResource(MyResource.class);
}
#Test
public void getAndCreate() throws URISyntaxException,
UnsupportedEncodingException {
MockHttpRequest getRequest = MockHttpRequest.get("/test/element/44");
MockHttpResponse getResponse = new MockHttpResponse();
dispatcher.invoke(getRequest, getResponse);
String getResponseBodyAsString = getResponse.getContentAsString();
System.out.println(String.format(
"Get Response code [%s] with payload [%s]", getResponse
.getStatus(), getResponse.getContentAsString()));
MockHttpRequest postRequest = MockHttpRequest.post("/test/element");
MockHttpResponse postResponse = new MockHttpResponse();
postRequest.contentType(MediaType.APPLICATION_JSON);
postRequest.content(getResponseBodyAsString.getBytes("UTF-8"));
dispatcher.invoke(postRequest, postResponse);
System.out.println(String.format(
"Post Response code [%s] with payload [%s]", postResponse
.getStatus(), postResponse.getContentAsString()));
}
}
Do you have to use Jettison? If not I would recommend just switching to use Jackson instead; this typically solves array/list related problems (problem with Jettison is that it converts to XML model, which makes it very hard to tell arrays from objects -- there are bugs, too, but it is fundamentally hard thing to get working correctly).