Json From .Net Server to android client - java

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!

Related

Why JsonParser gives double quotes in the return value, using com.google.gson API

I am currently using JsonObject and JsonParser of com.google.gson api (using gson-2.8.5 version) to parse and read the value form input JSON.
I have JSON filed like , smaple "resultCode":"SUCCESS", when I try to read the same value from json it gives the result as ""SUCCESS"" .
Every value I am reading, getting with double "" not sure why ? You can refer below screen of my debugging screen.
I am new to Json and parser, is that default behavior ?
I am expecting "SUCCESS", "S", "00000000" not like ""SUCCESS"" or ""S""
or ""00000000""
same I have highlighted in the below image .
Please share any idea how we can get apbsolute vlaue of string without """" double quote string it causing my string comparison fail.
String response_result = "{\"response\": {\"head\": {\"function\": \"acquiring.order.create\",\"version\": \"2.0\",\"clientId\": \"201810300000\",\"reqMsgId\": \"56805892035\",\"respTime\": \"2019-09-13T13:18:08+08:00\"},\"body\": {\"resultInfo\": {\"resultCode\": \"SUCCESS\",\"resultCodeId\": \"00000000\",\"resultStatus\": S,\"resultMsg\": \"SUCCESS\"},\"acquirementId\": \"2018080834569894848930\",\"merchantTransId\": \"5683668701112717398\",\"checkoutUrl\": \"http://localhost:8081/crm/operator/operator-search-init.action\"}},\"signature\":\"d+TUYLvt1a491R1e6aO8i9VwXWzVhfNgnhD0Du74f4RgBQ==\"}";
HttpInvoker.Result result = i.new Result(200, response_result);
JsonObject jo = new JsonParser().parse(response_result).getAsJsonObject();
String resultCode = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCode").toString();
String resultCodeId = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCodeId").toString();
String resultStatus = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultStatus").toString();
String checkoutUrl = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("checkoutUrl").toString();
if ( RESULT_CODE_GCASH_SUCCESS.equals(resultCode)
&& RESULT_STATUS_SUCCESS.equals(resultStatus)
&& StringUtils.isNotEmpty(checkoutUrl)) {
log.error("Testing ".concat(resultCode).concat(resultStatus).concat(checkoutUrl));
}
log.error("Testing ".concat(resultCode).concat(resultStatus).concat(checkoutUrl));
}
This is my input JSON
{
"response":{
"head":{
"function":"acquiring.order.create",
"version":"2.0",
"clientId":"201810300000",
"reqMsgId":"56805892035",
"respTime":"2019-09-13T13:18:08+08:00"
},
"body":{
"resultInfo":{
"resultCode":"SUCCESS",
"resultCodeId":"00000000",
"resultStatus":"S",
"resultMsg":"SUCCESS"
},
"acquirementId":"2018080834569894848930",
"merchantTransId":"5683668701112717398",
"checkoutUrl":"http://localhost:8081/crm/operator/operator-search-init.action"
}
},
"signature":"d+TUYLvtI38YL2hresd98Ixu1BXccvvh1IQMiHuMXUEeW/N5exUsW491R1e6aO8i9VwXWzVhfNgnhD0Du74f4RgBQ=="
}
JsonParser parses your json into JsonElement structure. The behaviour that you see is a normal since you are using toString method of JsonElement. To achieve your goal just use JsonElement::getAsString method :
String resultCode = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCode").getAsString();
which gives SUCCESS instead of "SUCCESS"
Note that JsonElement is an abstract class and classes, that extend this class, will override those helper getAs... methods. In your case JsonPrimitive::getAsString will be invoked.
Also you could create a POJO class for your json and use Gson::fromJson to parse json into object of your POJO class.
With the input from #Michalk:
I understand that easy way to read JSON data is using Gson::fromJson and creating POJO class for out json.
I have generated POJO Classes supplying my sample input JSON using this link
and Now I have POJO Classes called : CreateOrderJSONResponse
Gson::fromJson
Sample :
Gson gson = new Gson();
CreateOrderJSONResponse responseJson = gson.fromJson(inputJSON, CreateOrderJSONResponse.class);
Accessubg data :
String resultCodeText = responseJson.getResponse().getBody().getResultInfo().getResultCode();
String resultCodeId = responseJson.getResponse().getBody().getResultInfo().getResultCodeId();
String resultStatus = responseJson.getResponse().getBody().getResultInfo().getResultStatus();
String checkoutUrl = responseJson.getResponse().getBody().getCheckoutUrl();
Above Gson::fromJson example works smooth and it looks neat compare to direct accessing the filed with below sample code :
JsonObject jo = parser.parse(inputJSON).getAsJsonObject();
String resultCodeText = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultCode").getAsString();
String resultCodeId = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultCodeId").getAsString();
String resultStatus = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultStatus").getAsString();
String checkoutUrl = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().getAsJsonPrimitive("checkoutUrl").getAsString();
Note :
I have found this link of JSON or JAVA, SCALA, POJO generator tools as GitHub access you can access here

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.

Changing the format of list / array in URL [Retrofit 2]

As stated in the Retrofit documentation above the #Query annotation:
Passing a List or array will result in a query parameter for each
non-null item.
As of now my call looks something like this:
#GET("questions")
Call<List<QuestionHolder>> getQuestionsExcludingTheSpecified(
#Query("exclude_ids") long[] excludedQuestionIds
);
This works but results in fairly long URLs quite fast.
E.g. for excludedQuestionIds = new long[]{1L, 4L, 16L, 64L} the request URL already will be /questions?exclude_ids=1&exclude_ids=4&exclude_ids=16&exclude_ids=64.
Is there an easy way to exchange this behaviour resulting in arrays formatted as exclude_ids=[1,4,16,64] or something similar?
What came to my mind yet was, to:
use JsonArray as parameter, but then I need to convert every array / list before making the call
intercept every request and compress duplicated keys
override the built-in #Query decorator
Any ideas?
I decided to go with the Interceptor approach. I simply change any outgoing request that includes more than one value for a single query parameter.
public class QueryParameterCompressionInterceptor implements Interceptor {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
HttpUrl url = request.url();
for (String parameterName : url.queryParameterNames()) {
List<String> queryParameterValues = url.queryParameterValues(parameterName);
if (queryParameterValues.size() > 1) {
String formattedValues= "[" + TextUtils.join(",", queryParameterValues) + "]";
request = request.newBuilder()
.url(
url.newBuilder()
.removeAllQueryParameters(parameterName)
.addQueryParameter(parameterName, formattedValues)
.build()
).build();
}
}
return chain.proceed(request);
}
non android solution
TextUtils is part of the Android SDK, in case you're not developing for Android you might exchange TextUtils.join for a method like this:
public static String concatListOfStrings(String separator, Iterable<String> strings) {
StringBuilder sb = new StringBuilder();
for (String str : strings) {
sb.append(separator).append(str);
}
sb.delete(0, separator.length());
return sb.toString();
}
}
You may also have a look at this SO question for more solutions regarding the concatenation.

How to perform Amazon Cloud Search with .net code?

I am learning Amazon Cloud Search but I couldn't find any code in either C# or Java (though I am creating in C# but if I can get code in Java then I can try converting in C#).
This is just 1 code I found in C#: https://github.com/Sitefinity-SDK/amazon-cloud-search-sample/tree/master/SitefinityWebApp.
This is 1 method i found in this code:
public IResultSet Search(ISearchQuery query)
{
AmazonCloudSearchDomainConfig config = new AmazonCloudSearchDomainConfig();
config.ServiceURL = "http://search-index2-cdduimbipgk3rpnfgny6posyzy.eu-west-1.cloudsearch.amazonaws.com/";
AmazonCloudSearchDomainClient domainClient = new AmazonCloudSearchDomainClient("AKIAJ6MPIX37TLIXW7HQ", "DnrFrw9ZEr7g4Svh0rh6z+s3PxMaypl607eEUehQ", config);
SearchRequest searchRequest = new SearchRequest();
List<string> suggestions = new List<string>();
StringBuilder highlights = new StringBuilder();
highlights.Append("{\'");
if (query == null)
throw new ArgumentNullException("query");
foreach (var field in query.HighlightedFields)
{
if (highlights.Length > 2)
{
highlights.Append(", \'");
}
highlights.Append(field.ToUpperInvariant());
highlights.Append("\':{} ");
SuggestRequest suggestRequest = new SuggestRequest();
Suggester suggester = new Suggester();
suggester.SuggesterName = field.ToUpperInvariant() + "_suggester";
suggestRequest.Suggester = suggester.SuggesterName;
suggestRequest.Size = query.Take;
suggestRequest.Query = query.Text;
SuggestResponse suggestion = domainClient.Suggest(suggestRequest);
foreach (var suggest in suggestion.Suggest.Suggestions)
{
suggestions.Add(suggest.Suggestion);
}
}
highlights.Append("}");
if (query.Filter != null)
{
searchRequest.FilterQuery = this.BuildQueryFilter(query.Filter);
}
if (query.OrderBy != null)
{
searchRequest.Sort = string.Join(",", query.OrderBy);
}
if (query.Take > 0)
{
searchRequest.Size = query.Take;
}
if (query.Skip > 0)
{
searchRequest.Start = query.Skip;
}
searchRequest.Highlight = highlights.ToString();
searchRequest.Query = query.Text;
searchRequest.QueryParser = QueryParser.Simple;
var result = domainClient.Search(searchRequest).SearchResult;
//var result = domainClient.Search(searchRequest).SearchResult;
return new AmazonResultSet(result, suggestions);
}
I have already created domain in Amazon Cloud Search using AWS console and uploaded document using Amazon predefine configuration option that is movie Imdb json file provided by Amazon for demo.
But in this method I am not getting how to use this method, like if I want to search Director name then how do I pass in this method as because this method parameter is of type ISearchQuery?
I'd suggest using the official AWS CloudSearch .NET SDK. The library you were looking at seems fine (although I haven't look at it any detail) but the official version is more likely to expose new CloudSearch features as soon as they're released, will be supported if you need to talk to AWS support, etc, etc.
Specifically, take a look at the SearchRequest class -- all its params are strings so I think that obviates your question about ISearchQuery.
I wasn't able to find an example of a query in .NET but this shows someone uploading docs using the AWS .NET SDK. It's essentially the same procedure as querying: creating and configuring a Request object and passing it to the client.
EDIT:
Since you're still having a hard time, here's an example. Bear in mind that I am unfamiliar with C# and have not attempted to run or even compile this but I think it should at least be close to working. It's based off looking at the docs at http://docs.aws.amazon.com/sdkfornet/v3/apidocs/
// Configure the Client that you'll use to make search requests
string queryUrl = #"http://search-<domainname>-xxxxxxxxxxxxxxxxxxxxxxxxxx.us-east-1.cloudsearch.amazonaws.com";
AmazonCloudSearchDomainClient searchClient = new AmazonCloudSearchDomainClient(queryUrl);
// Configure a search request with your query
SearchRequest searchRequest = new SearchRequest();
searchRequest.Query = "potato";
// TODO Set your other params like parser, suggester, etc
// Submit your request via the client and get back a response containing search results
SearchResponse searchResponse = searchClient.Search(searchRequest);

RestSharp, spring boot and JSON.org encoding issue

I have one c# desktop client that reads a local DB and uploads the values into the web application.
On the c# side I am using RestSharp and Json.net.
private static void DBUpdater()
{
var client = new RestClient();
client.BaseUrl = BASE_URL;
string json = JsonConvert.SerializeObject(modelo.getComunidades(), Formatting.Indented);
Console.WriteLine(json);
var request = new RestRequest("/nuevascomunidades", Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddParameter("comunidades", json);
Console.WriteLine(client.Execute(request).ResponseStatus);
Console.ReadKey();
}
When I print out by console the generated json string all the characters are well represented.
However, when I get the values from the spring boot/spring data, any special character is represented completely wrong.
On the server side I am deserializing like this usng json.org:
#RequestMapping(value = "/nuevascomunidades", method = RequestMethod.POST)
public void nuevasComunidades(#RequestParam(value = "comunidades") String comunidades) {
logger.debug("######Entra en /nuevascomunidades");
JSONArray entrada = new JSONArray(comunidades);
JSONObject aux;
Comunidad comunidad;
int top = entrada.length();
for (int i = 0; i < top; i++) {
aux = entrada.getJSONObject(i);
comunidad = new Comunidad(Integer.valueOf(aux.getString("Numero")),
aux.getString("Nif"),
aux.getString("Nombre"),
aux.getString("Direccion"),
aux.getString("Cod_postal"),
aux.getString("Poblacion"),
aux.getString("Provincia"),
aux.getString("Pais"),
aux.getBoolean("Baja"));
comunidadRepositorio.save(comunidad);
logger.debug("######Comunidad añadida: " + comunidad.toString());
}
}
Any idea about how to fix the encoding?
Thanks in advance.
RIGHT REPRESENTATION: "Pais": "ESPAÑA # ºª ¡¿?!"
WRONG REPRESENTATION: pais='ESPA├?A # ┬║┬¬ ┬í┬┐?!'
EDIT:
I just added these settings in the application.properties without any success:
# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
Finally I got the problem.
Basically it was related to the Tomcat 8 settings.
You can read more in here:
http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q3

Categories