I have a REST api GET call that takes an array of strings formatted as JSON. I'd like to use Jersey to convert that array of strings to something like a string array or List. I've reviewed http://jersey.java.net/nonav/documentation/latest/json.html, but it looks like Jersey wants me to create an object that specifies how it should be mapped, which I really don't want to do because it's just a simple array.
#GET
public Response get(#QueryParam("json_items") String requestedItems) throws IOException
{
//Would like to convert requestedItems to an array of strings or list
}
I know there are lots of libraries for this - but I'd prefer to use Jersey and not introduce any new libraries.
Create a wrapper object for you data (in this case the Person class) and annotate it with #XMLRootElement
Your post method should look like this
#POST
#Consumes(MediaType.APPLICATION_JSON)
public void post(List<Person> people) {
//notice no annotation on the method param
dao.putAll(people);
//do what you want with this method
//also best to return a Response obj and such
}
this is the right way to do this stuff where the data is sent in the request.
but if you want to have a QueryParam as the JSON data you can do this
say your request param looks like this:
String persons = "{\"person\":[{\"email\":\"asdasd#gmail.com\",\"name\":\"asdasd\"},{\"email\":\"Dan#gmail.com\",\"name\":\"Dan\"},{\"email\":\"Ion#gmail.com\",\"name\":\"dsadsa\"},{\"email\":\"Dan#gmail.com\",\"name\":\"ertert\"},{\"email\":\"Ion#gmail.com\",\"name\":\"Ion\"}]}";
you notice that its a JSONObject named "person" that contains a JSONArray of other JSONObjets of type Person with name an email :P
you can itterate over them like this:
try {
JSONObject request = new JSONObject(persons);
JSONArray arr = request.getJSONArray("person");
for(int i=0;i<arr.length();i++){
JSONObject o = arr.getJSONObject(i);
System.out.println(o.getString("name"));
System.out.println(o.getString("email"));
}
} catch (JSONException ex) {
Logger.getLogger(JSONTest.class.getName()).log(Level.SEVERE, null, ex);
}
sry
Just try to add to your Response the array, like
return Response.ok(myArray).build();
and see what happen.
If it's just a very simple array it should be parsed without any problem.
EDIT:
If you want to receive it then just accept an array instead of a String. Try with a List or something like this.
Otherwise you can try to parse it using an ObjectMapper
mapper.readValue(string, List.class);
Related
I am getting String jsonObject in my controller.
The structure is following:
{
"name":"name",
"schema": {
...
...
}
}
I need to parse it into a Plain Old Java Object and receive schema as a String (saving the structure). When I am using System.out.print("schema"), I expect to see:
{
...
...
}
I have a POJO Collection with String name and Object schema fields.
I am using GSON to get Collection.class from String json:
new Gson().fromJson(json, Collection.class);
When I try to print Collection.schema I get the following output:
{......} - in a one row.
I really need to get this object as a String without formatting
This should work. Basically, you hydrate your Collection object and then just send your schema back through Gson. Done.
Gson gson = new Gson();
Collection collection = gson.fromJson(json, Collection.class);
String schema = gson.toJson(collection.getSchema());
System.out.println(schema);
Question could be asked as to why you are accepting a String from your controller? Perhaps you can get the framework you are using to pass in a fully converted Collection object and save yourself a step?
Also, for your Collection.schema, it's common to use Map<String, Object> instead of Object for this type of "schema"-less type of paradigm.
The code that we already have return us JsonObject. What I want to do is to add a new key and the value for it.
For example, we have an object like this:
{"id":"12","name":"test"}
I want to transform it into this:
{"id":"12","name":"test","status":"complete"}
I didn't find what I need in documentation except using put method. So I wrote this code:
JsonObject object = getJsonObject();
JsonString val = new JsonString() {
public JsonValue.ValueType getValueType() {
return JsonValue.ValueType.STRING;
}
public String getString() {
return "complete";
}
public CharSequence getChars() {
return (CharSequence) "complete";
}
};
object.put("status", val);
But it doesn't work, crashing with :
java.lang.UnsupportedOperationException
I can't understand what is wrong. Have I any other option to complete such a task?
I don't think JsonObject instances are meant to be modified.
I think your best option is to create a new object, copy the existing properties and add the new property to it.
You can use https://docs.oracle.com/javaee/7/api/javax/json/JsonObjectBuilder.html
Not sure if object.put works but you can use the following way to append the details to JSON value:
You can create a different JSON object with the key and value that you want to add to the JSON object and the user object.merge(status, complete, String::concat);
merge() checks for the key:'status' in your JSON object if it does'nt find it then it adds that key:value pair or else it replaces it
.You are not able to compile it because you may not be using jre 1.8.
I've Just verified the following method:
Just create a new JSONObject(org.json.JSONObject not javax.json.JsonObject)
JSONObject modifiedJsonObject= new JSONObject(object.toString());
modifiedJsonObject.put("status", "complete");
I have a model object which is initialized with default values. To refresh the content of object I call an web service and get the response and get the content from json object.
I want to check If json response contains the object or not. If it does then call the setter and set the data and if it doesn't then leave then don't set it. I have approx 300 fields in my object. How I can do it with less code. I am listing my current approach.
My Model object is like
public class MyObject {
private String str1 = "Initial Value1";
private String str2 = "Initial Value2";
public void setStr1(String str1)
{
this.str1 = str1;
}
public void setStr2(String str2)
{
this.str2 = str2;
}
public String getStr1(){
return str1;
}
public String getStr2(){
return str2;
}
}
my json response be like
{
"val_one":"New Value1",
"val_two":"New_value2"
}
Now at run time I need to set the value from json response
MyObject myObject = new MyObject();
if(jsonObject.has("val_one"));
myObject.setStr1(jsonObject.get("val_one"));
if(jsonObject.has("val_two"));
myObject.setStr2(jsonObject.get("val_two"));
Now how to do it in a better and efficient
If both sides are using JAVA then why not just use json-io. You can create an object as normal. ie
Animal a = new Aminmal() andimal.setName("bob");
Then use json-io to make it into json -- stream to where ever it needs to be... use json io to change back to object
This can be done using
JsonWriter.objectToJson(Object o);
JsonReader.jsonToJava(String json);
https://code.google.com/p/json-io/
json-io is also extremely light weight and quicker than most if not all other third party json library's that I have used.
That being said if you want to have more control on the output ie.. date conversions etc.. then look at GSON.
https://code.google.com/p/google-gson/
Another option, in addition to the other suggestions is gson. Here the link for gson information.
Essentially the idea with gson being that you define an object to represent the JSON structure that you are receiving. So somewhat like what you have now, you'd just need to change the object attributes to match the names of the JSON fields, ie 'val_one' and 'val_two'.
Then you just need to use gson to create the object from the JSON text, eg:
Gson gson = new GsonBuilder().create();
MyObject json = gson.fromJson(jsonStr, MyObject.class);
Why do you want to take of the object model mapping yourself? If you take spring then you can use the jackson mapper and have it all done for you.
If you don't want to use spring then you still can use jackson2 and let it handle the parsing:
http://wiki.fasterxml.com/JacksonRelease20
I'm currently trying to use Flexjson to deserialize a JSON String and map it to the Object model of my
Android App. The application is a kind of library with several vendors that can have some catalogs with more catalogs
and documents in them. The json is fetched from a web service I have no influence on and looks something like this:
{
"library":{
"vendor":[
{
"id":146,
"title":"Vendor1",
"catalog":[
{
"id":847,
"document":[
{
"id":1628,
"title":"Document",
...
},
{
...
}
],
"title":"Catalog ",
},
{
...
}
]
},
{
...
}
]
}
}
So each vendor, catalog, document is represented by a JSONObject and all child catalogues and documents are within a JSONArray.
So far everything works fine with Flexjson and the following deserialization code:
LibraryResponse response = new JSONDeserializer<LibraryResponse>()
.use(Timestamp.class, new TimestampObjectFactory())
.deserialize(getLocalLibrary(), LibraryResponse.class);
return response.library;
I do have a Library object that has a List<Vendor>. Each vendor has a List<Catalog> and a List<Document>.
But unfortunately, the web service straps the JSONArrays to simple JSONObjects if a catalog contains only a single document
or a catalog contains just one catalog. So the json in that case looks like this:
"document":
{
"id":1628,
"title":"Document",
...
}
Now Flexjson doesn't know how to deserialize and I end up with a library.vendorX.getDocument() being a List<HashMap> instead of a List<Document>.
One idea is to tell Flexjson explicitly how to handle such cases, but I have no idea where to start with this. Another way could be to parse the initial json manually and replace such JSONObjects with the appropriate JSONArray. But I think that way is not really nice to go, as the library can be pretty deep.
I hope you can provide some guidance here.
Yikes this is some gnarly json mapping going on. What backend coder did that?! #NotHelping.
Well from looking at the code, Flexjson is coded to handle this out of the box. But it looks like it's not passing the typing information down to the bind so it doesn't know what type it's binding into so it just returns a Map. That's a bug that should probably be fixed. Good news is there is a work around.
Anyway, the simplest thing I can think of is to install an ObjectFactory on that list. Then you can check and see if you get a Map or a List when the stream is deserialized. Then you can wrap it in a List and send it on to the appropriate decoder. Something like:
LibraryResponse response = new JSONDeserializer<LibraryResponse>()
.use(Timestamp.class, new TimestampObjectFactory())
.use("library.vendor.values.catalog.values.document", new ListDocumentFactory() )
.deserialize(getLocalLibrary(), LibraryResponse.class);
Then
public class ListDocumentFactory implements ObjectFactory {
public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) {
if( value instanceof Collection ) {
return context.bindIntoCollection((Collection)value, new ArrayList(), targetType);
} else {
List collection = new ArrayList();
if( targetType instanceof ParameterizedType ) {
ParameterizedType ptype = (ParameterizedType) targetType;
collection.add( context.bind(value, ptype.getActualTypeArguments()[0]) );
} else {
collection.add( context.bind( value ) );
return collection;
}
}
}
}
I think that's roughly what would fix that bug, but should also fix your problem.
I'm using renderJSON() method to return an array of objects, with a custom JsonSerializer for the class of each element. The response has the following format:
[{"id":2,"name":"fred"},{...},...]
But I would like to add the name of the array at the begginning:
"arrayname":[{"id":2,"name":"fred"},{...},...]
How can I add the name of the object to a JSON response with renderJSON()? Should I use a template or can I do it with java code?
"arrayname":[{"id":2,"name":"fred"},{...},...]
looks like invalid Json, but if you wrap the array in an object you could get:
{"arrayname":[{"id":2,"name":"fred"},{...},...]}
E.g. something like this:
public class MyArrayWrapper {
public final User[] arrayname;
public MyArrayWrapper(User[] arrayname) {
this.arrayname = arrayname;
}
}
Then you can call renderJSON(new MyArrayWrapper(yourUserArray)); to get JSON like:
{"arrayname":[{"id":2,"name":"fred"},{...},...]}
Or just return as a list Arrays.asList(arr);