Parsing a Single Integer with Json Net - java

I am trying to parse a simple long integer with Json.Net. This is what the response looks like:
header:
{
Transfer-Encoding: chunked
Date: Fri, 03 Jul 2015 16:15:33 GMT
Server: Apache-Coyote/1.1
Content-Type: application/json
}
body is simply: 1435775316000
In gson library with Java, I can parse it like this:
Long one = gson.fromJson("1435775316000", Long.class);
I have a method in my .Net client to parse responses, but it expects it to be in Json format:
private static JObject sendRequest(String params)
{
try
{
HttpResponseMessage response = Client.GetAsync(params).Result;
if (response.IsSuccessStatusCode)
{
var jsonResponse = response.Content.ReadAsStringAsync().Result;
return JObject.Parse(jsonResponse);
}
else
{
//do something else
}
}
catch (Exception e)
{
//throw
}
}
this works fine if the response was in Json mapped format:
{ "version" : "1435775316000" }
but the service simply returns:
1435775316000
Again, the header of the response says it's in Json. How do I allow this with the Json.Net library.
EDIT:
I probably should have asked what is the correct way of arguing my case. The developer on the service end says returning an integer is ok, arguing that it's more work for the service implementation, and would have to create a json object. I disagree, and believe that it should return a proper json object, like every other call to said service. How can I convince the service developer to do so? Am I asking too much? I mean, it is easier on the service end to return a simple int, but that means that on my end I have to check whether or not to parse it as an object, or a token json value.

If the service just returns "1435775316000" then that isn't really JSON - or at least, it's not a JSON object, which is at least a rather more widely-used approach to returning JSON. You can just parse it with long.Parse:
long value = long.Parse(jsonResponse);
If you really need to create a JObject from that, you can easily do so:
JObject wrapped = new JObject(value);
... but I'd question whether it's really a good idea.
Another option is to understand it as a JSON value though. You could change your method to return JToken, and use:
return JToken.Parse(jsonResponse);
Here's an example showing that working:
using System;
using Newtonsoft.Json.Linq;
class Test
{
static void Main(string[] args)
{
var jsonObject = "{ \"name\": \"foo\" }";
var jsonLong = "123456";
Console.WriteLine(JToken.Parse(jsonObject).GetType()); // JObject
Console.WriteLine(JToken.Parse(jsonLong).GetType()); // JValue
}
}

Using Value property of object, casting it for non-string types:
dynamic json = JsonConvert.DeserializeObject(result);
item.CredentialDescription = json.Credentials[0].CredentialDescription.Value;
item.CardNumber = (int)json.Credentials[0].CardNumber.Value;

Related

Send byte[] over http

I do have get request over http from an angular based client side which expects as an answer an array of bytes from a java server.
angular.ts
downloadDocument(documentId: string) {
const params = new HttpParams().set('docId', documentId);
return this.httpClient.get<any>(`/downloadpdf/`,
{ params: params});
}
controller.java
#GetMapping("/downloadpdf")
public String downloadDocument(#RequestParam("docId") final String docId) {
String response = (new String(getBytesArray(docId)));
// getBytesArray returns a byte[]
// response correctly computed
return response;
}
Parsing error is encountered while transmitting over http:
"HttpErrorResponse":
message: 'Http failure during parsing for http://localhost...'
error: 'error: SyntaxError: Unexpected token % in JSON at position 0 at JSON.parse () at XMLHttpRequest.onLoad'
Any ideas why this is happening?
It's happening because you call the overload of get() that takes a generic parameter:
this.httpClient.get<any>(...)
This overload sets the response type to JSON, thus telling the HttpClient to parse the response body to JSON and to returned the generated object or array. Since you do not want to receive JSON, you must use another overload.
The documentation is your friend.
If you want to receive a Blob, for example, you would use the second overload, documented as returning an Observable<Blob>, and expecting options with responseType: 'blob'.

Rest Assured code not allowing to use println

I am trying to automate twitter API. when tried to print "js.get("text") using
System.out.println(js.get("text")); I am getting error as
"The method println(boolean) is ambiguous for the type PrintStream"
I downloaded jars and passed in Build path as well "scribejava-apis-2.5.3" and "scribejava-core-4.2.0"
Below code is not allowing me use println for ------>js.get("text")
public class Basicfunc {
String Consumerkeys= "**************";
String Consumersecretkeys="*******************";
String Token="*******************";
String Tokensecret="***************************";
#Test
public void getLatestTweet(){
RestAssured.baseURI = "https://api.twitter.com/1.1/statuses";
Response res = given().auth().oauth(Consumerkeys, Consumersecretkeys, Token, Tokensecret).
queryParam("count","1").
when().get("/home_timeline.json").then().extract().response();
String response = res.asString();
System.out.println(response);
JsonPath js = new JsonPath(response);
System.out.println(js.get("text"));
}
}
Use System.out.println(js.getString("text")); instead of System.out.println(js.get("text"));, because get returns any primitive value.
I think your problem is that your twitter response is actually a list.
Try to use System.out.println(js.getList()[0].get("text")); and be aware that you are only using the first [0] entry and ignoring the rest.

JSONObject toString and Base64 performance

In my app I am sending base64 encoded files in Json format. My code is:
JSONObject jsonRequest = prepareJsonObject(expense, contentUri);
String jsonString = jsonRequest.toString();
StringEntity se = new StringEntity(jsonString);
The jsonRequest object looks like this:
{
"category":"660",
"user":"458",
"dated_on":"Wed Mar 12 10:38:11 GMT+00:00 2014",
"description":"document",
"gross_value":"-2.0",
"currency":"GBP",
"attachment":{
"data":"<base64>"
"mimetype":"image/jpeg"
}
}
The problem is that jsonRequest.toString() is taking like 2 minutes for a 700Kb file.
Is there a way to make this quicker? Am I doing something wrong?
thanks.
EDIT: I am testing in an actual Nexus 4 running KITKAT.
For completion purpose, this is the code for prepareJsonObject(), which runs in less than 2 secs.
public static JSONObject prepareJsonObject(Expense expense, String contentUri){
JSONObject expenseJson = null;
try{
expenseJson = new JSONObject();
if(expense.getUserId()!=null) expenseJson.put("user", expense.getUserId().toString());
if(expense.getProjectId()!=null) expenseJson.put("project", expense.getProjectId().toString());
if(expense.getCurrency()!=null) expenseJson.put("currency", expense.getCurrency().toString());
if(expense.getGrossValue()!=null) expenseJson.put("gross_value", expense.getGrossValue().toString());
if(expense.getNativeGrossValue()!=null) expenseJson.put("native_gross_value", expense.getNativeGrossValue().toString());
if(expense.getSalesTaxRate()!=null) expenseJson.put("sales_tax_rate", expense.getSalesTaxRate().toString());
if(expense.getDescription()!=null)expenseJson.put("description", expense.getDescription().toString());
if(expense.getDated()!=null)expenseJson.put("dated_on", expense.getDated());
if(expense.getCategoryId()!=null) expenseJson.put("category", expense.getCategoryId().toString());
if(expense.getManualSalesTaxAmount()!=null)expenseJson.put("manual_sales_tax_amount", expense.getManualSalesTaxAmount().toString());
if(contentUri!=null){
JSONObject attachmentJson = new JSONObject();
String base64data = AttachmentsUtils.getBase64ForUri(Uri.parse(contentUri));
attachmentJson.put("data", base64data);
attachmentJson.put("content_type", AttachmentsUtils.getMimetypeFromContentUri(Uri.parse(contentUri)));
expenseJson.put("attachment", attachmentJson);
}
}catch(Exception e){
Log.e("ExpensesUtils", "Couldn't encode attachment: "+e.getLocalizedMessage());
return null;
}
return expenseJson;
}
I think this is because the toString pare the full content of your base64 data to handle unicode characters and escape some specific characters. You can see this in JSONStringer#string, which is called for every string value in your JsonObject when you call toString.
Of course, as your data is base64, you don't actually need this. So I think you will need to implement your own toString implementation, probably based on the JSONStringer without escaping

Empty object in browser when returning JSONObject

I have this method :
#GET
#Path("/myservice")
#Produces(MediaType.APPLICATION_JSON)
public Response mysercice() {
boolean userExists = false;
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoStore(true);
JSONObject jsonObject = new JSONObject();
jsonObject.put("userExists", userExists);
return Response.ok(jsonObject, MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
}
When accessing to the URL of the method in the browser, I get { }, it means that the object is empty.
So, I tried to use :
return Response.ok(jsonObject.toString(), MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
So, I get in the browser {"userExists" : false}
But I didn't understand why when returning simply the JSONObject, we get in the browser an empty object.
Most JAX-RS implementations come with a provider for mapping response entities to JSON. So when you write:
return Response.ok(jsonObject, MediaType.APPLICATION_JSON).build();
You are basically requesting that the JAX-RS provider marshall the JSONObject into JSON for you. The only problem being that JSONObject isn't really meant to be serialized this way. Instead its meant to be used to build a JSON representation incrementally, then convert that representation into a JSON string value. You have two options:
Create a POJO containing all the fields you want to send back to the client. Return this POJO in your method and it will be automatically converted to JSON (`return Response.ok(myPojo, MediaType.APPLICATION_JSON).build()
Return the JSON data directly as a String (which you already did in your example that works).

Json From .Net Server to android client

I'm trying to call a ApiController from android apllication.
This is the api controller:
[AcceptVerbs("GET", "POST")]
public string Get(string coords)
{
using (var context = new Entities())
{
var records = from poi in context.Pois
where poi.Latitude >= fromLatitude &&
poi.Latitude <= toLatitude &&
poi.Longitude >= fromLongitude &&
poi.Longitude <= toLongitude
select new
{
poiName = poi.Name,
poiLatitude = poi.Latitude,
poiLongitude = poi.Longitude
};
return JsonConvert(records);
}
}
}
private string JsonConvert(object records)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(records,);
}
At the android code, I'm creating json array with new JSON(string).
The problem is java throws an excetpion: the json string is not valid.
When i look at the debuuger, I see that the string have 2 backslash before ",
and java dont know how to parse that.
Where is the problem?
Thank you
Update: Solved. The WebApi returned XML with the json as string. changed the WebApi Not to return XML, then changed it to return object (and removed the JSONConvert) - and it works.
I know this is an old question, but i had a similar problem and found a solution.
In my case i had to pass a complex JSON object (nested) from a .NET Client to a Java Rest API and was using a string parameter which turned out to be an invalid JSON due to the double backslash (I seralized it so it was escaped and then .NET escaped it again before sending).
So, in order to avoid that i used StringContent
MyType obj = new MyType()
{
...
};
string obJSON = JsonConvert.SerializeObject(obj);
StringContent sc = new StringContent(obJSON, Encoding.UTF8,"application/json");
HttpResponseMessage response = client.PostAsync(ruta, sc).Result;
Hope this helps someone!

Categories