I have a page that comes back as an UnexpectedPage in HtmlUnit, the response is JSON. Can I use HTMLUnit to parse this or will I need an additional library?
HtmlUnit doesn't support it. It can at highest execute a JS function. You need to check beforehand if the Content-Type of the returned response matches application/json and then use the suitable tool to parse it. Google Gson is useful in this.
WebClient client = new WebClient();
Page page = client.getPage("https://stackoverflow.com/users/flair/97901.json");
WebResponse response = page.getWebResponse();
if (response.getContentType().equals("application/json")) {
String json = response.getContentAsString();
Map<String, String> map = new Gson().fromJson(json, new TypeToken<Map<String, String>>() {}.getType());
System.out.println(map.get("displayName")); // Benju
}
If the JSON structure is known beforehand, you can even use Gson to convert it to a fullworthy Javabean. You can find an example in this answer.
BalusC provided a good answer, but to answer the literal question, you don't really need an additional library: you can use Groovy's neat built-in JsonSlurper, e.g:
def jsonSlurper = new groovy.json.JsonSlurper()
def parsed = jsonSlurper.parseText(response.getContentAsString())
println("Found ${parsed.TotalCount} records.");
to print out 1 for a response such as
'{"Records":[{"ID":"123","Address":"Zagreb",],"TotalCount":1}'
Related
I'm writing an app that uses JSON (from a Kimonolabs API) and while I was able to utilize my API effortlessly in Python as such:
results = json.loads(urllib.request.urlopen(KimonoAPIlink).read().decode('utf-8'))
Which returns a useable JSON dictionary:
title = results['results']['suart'][0]['stitle']['text']
href = results['results']['suart'][0]['stitle']['href']
In Java (Android specifically) I have to do it this way (Using Gson):
URL url = new URL(KimonoAPIlink);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
JsonElement x = rootobj.getAsJsonObject("results").getAsJsonArray("suart").get(0);
JsonObject y = x.getAsJsonObject();
title.setText(y.getAsJsonObject("stitle").getAsJsonPrimitive("text").toString().replace("\"", "").replace("\\","\""));
Is there any way to do this that isn't so verbose and complicated? (my code works, I'd just like it to be more simple and clean)
Moreover, can I somehow parse the whole nested JSON object into something useful (like python does) and not reparse it each layer I access?
Thanks in advance.
Edit: I've also seen people use Apache commons.io on here for this, but I don't think it returns a different JSON object (i.e. I'd still have to parse every layer)
Check out GSON, Jackson or Moshi
What you are looking for is lookup using JsonPath, wherein JSON coordinates are represented by a string with syntax pretty similar to the one you are using in Python (as well as other featuress).
For example, in your case it would be $.results.suart[o].stitle.text.
A quick look in the docs and the gson github shows it is not implemented in gson, although the JsonReader class does support a method to return that value.
There is a library implementation JsonPath in java (called JsonPath). Here's a one line code for your case (ignoring connection detail):
String result = JsonPath.parse("[some json]").read("$.results.suart[o].stitle.text");
I need to send a String that is already in JSON format using the Jersey client 1.19 and genson 1.3
Client.create().resource(path).webResource.type(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE).put(ClientResponse.class, jsonAsString)
The problem with this is that the client is parsing the string, I need it to be sent as it is.
I'm sending something like { "name":"Foo" } and the client is converting it to "{ \"name\":\"Foo\" }". If I change the type to PLAIN_TEXT it sends the request correctly but I need to send it as application/json .
So yes Genson will try to encode your string as a literal json string. In this case it is maybe not what you would want, but more generally it is what people would expect: serialize à java string as a json string.
The solution I see is too extend GensonJsonConverter and override isWritable to return false when the input type is string. Then just register it. That should work.
I've opened this issue so it can be added as a more flexible feature.
Try changing MediaType.APPLICATION_JSON_TYPE to MediaType.APPLICATION_JSON
http://examples.javacodegeeks.com/enterprise-java/rest/jersey/json-example-with-jersey-jackson/
I tried your code with Jersey 1.19, Genson 1.3 and Wireshark. It works fine without Genson so it appears Genson is treating it as a literal string (since it is of type String) and therefore quoting the double quotes.
The following works.
String jsonAsString = "{ \"name\":\"Foo\" }";
Map<String, String> map = (new Genson()).deserialize(jsonAsString, Map.class);
String path = "...";
ClientResponse resp =
Client.create().resource(path)
.type(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.put(ClientResponse.class, map);
I have used Map because it is sufficient for the example but you can deserialize it to the appropriate object.
If you looking for an option to specify that the string should be passed as is, I am not yet aware of it but this should at least provide a solution to the problem of sending that string as application/json.
I need to parse json response in a play application and get all the fields/values in a list.
I'm getting the response as below:
WSRequestHolder request = WS.url("someurl");
request.setQueryParameter("somekey", "somevalue");
Promise<Response> promise = request.get();
Response response = promise.get();
JsonNode json = response.asJson();
The response comes like below:
{"results":{"key1":value1,"key2":value2,"key3":value3},"errorMessage":"","statusCode":2000,"success":true,"version":"1.01"}
I need to get all the feilds/values from "results" list. How can i do this using play json libraries / apis available? I'm using play 2.1.1.
Thanks.
Since the result is a JsonNode, you have all the niceties of JsonNode available to you.
For instance, if you want to access "results", do:
JsonNode results = json.get("results");
You also have methods such as .has(), .path(), .entries(), etc etc. One JsonNode can represent any JSON value, including null.
To test the type you can use the .is*() methods: .isObject(), .isNumber(), .isMissing() (note: the latter requires the use of .path() instead of .get()).
Example:
json.path("foo").isMissing(); // true
json.path("errorMessage").getTextValue(); // ""
json.get("results").get("key2"); // value2
json.get("success").getBooleanValue(); // true
Etc etc. See the javadoc for JsonNode.
Another solution would be to deserialize that JSON into a POJO. But that means creating the POJO in the first place, and then use an ObjectMapper to .read*() the value.
(side note: it is surprising that Play uses Jackson 1.9.x whereas 2.0+ has been available for many years...)
Hi friends i have a java.util.Map object in Ajax method like this..
Map<String,List<String>> sm = new TreeMap<>();
List<String> str = new ArrayList<String>();
str.add("val1");
str.add("val2");
str.add("val3");
str.add("val4");
sm.put("shift1", str);
sm.put("shift2", str);
sm.put("shift3", str);
sm.put("shift4", str);
JSONObject json = new JSONObject(sm);
response.getWriter().print(json);
In run time Map elements will be increase or decrease
according to map elements I have to generate table
This is Ajax call.. I don't know how to parse that Map object and dynamically generate the table in javascript.
Please show me how.
I am just answering your question. I don't know java and also i don't understand the details you gave above. If I am wrong, I am sorry and kindly ignore it.
To parse the string to object
In the jQuery, $.parseJSON(string);
In js, JSON.parse(string);
I hope this will help U. Thanks.
var json = $.parseJSON( jsonString );
// This one wouldn't be supported in old browsers
json = JSON.parse( jsonString );
Additionally, you could, in Java, respond with the Content-Type application/json and then in the jQuery AJAX you will receive the JSON already parsed for you.
Of course this will not happen if you specifically configure your jQuery AJAX call to receive an plain text, or HTML, or other content-type response.
For more reference, see here, at the dataType setting.
I want to send few dictionaries from django to android through HTTP after getting query in HTTP get. How can I do this and what formatting should I use?
I currently respond using HttpResponse. Name of keys are constant.
Read about serializing objects in django.
You can choose between xml, json or yaml. It's pointless to add documentation here. Goto the link.
EDIT: Django's doc is really nice. Example shouldn't really be needed. But, still, an example from one of my projects [Line 492-507 from views.py].
def pendingOrders(request):
userprof = UserProfile.objects.get(user= request.user)
if userprof.is_student:
student_account = request.user
dish = Dishes.objects.all()
#Getting all pending orders
order_all_pending = Orders.objects.filter(student_id = student_account,delivered = False)
pending_orders = Orders.objects.filter(~Q(status = 2),delivered = False)
for order in order_all_pending:
#Hack to change QuerySet to pass as JSON
order.quantity = pending_orders.filter(id__lt = order.id,counterid= order.counterid).count() + 1
#Returning JSON response to the objects obtained in above statement
return HttpResponse(serializers.serialize('json',order_all_pending,use_natural_keys=True),mimetype='application/json')
else:
return HttpResponse("Something went wrong")
https://stackoverflow.com/a/2845612/931277 Has an example of parsing json from an HttpResponse in Android.
You should use JSON. Django even makes it easy for you.