I tried to parse json from Web request in Xamarin Android application. But i am getting the below json string
[{\"type1\":val1,\"type2\":\"val2",\"type3\":\"val3\",\"type4\":val4},
{\"type1\":val1,\"type2\":\"val2",\"type3\":\"val3\",\"type4\":val4}]
How to convert this into string like below
[{"type1":"val1","type2":"val2","type3":"val3","type4":"val4"},
{"type1":"val1","type2":"val2","type3":"val3","type4":"val4"}]
Did you get the string value by copying the C# runtime value? If so, it looks to be correct with some minor errors.
[{\"type1\":val1,\"type2\":\"val2",\"type3\":\"val3\",\"type4\":val4},
{\"type1\":val1,\"type2\":\"val2",\"type3\":\"val3\",\"type4\":val4}]
Should probable be:
[{\"type1\":\"val1\",\"type2\":\"val2\",\"type3\":\"val3\",\"type4\":\"val4\"},
{\"type1\":\"val1\",\"type2\":\"val2\",\"type3\":\"val3\",\"type4\":\"val4\"}]
Some of the val*'s didn't have quotes at all and the type2 was missing \ on the quote.
Is it your own web service? Did your web request specify JSON as format? If the service is running JavaScript, does it call JSON.stringify(...) to normalize the JSON object? If you are using MVC or other MS technology make sure you are not wrapping the response in double JSON (f.e. returning a string by the controller where the string is JSON serialized as this will cause the doubling).
Good tool to verify the JSON returned by the web service is PostMan. If it also returns the string with the \'s in it then something is wrong with the service itself.
Here is a little tester for Android with JSON.Net serializer:
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Collections.Generic;
using Android.Util;
namespace JsonTest
{
public class TypeClass
{
public string type1 { get; set; }
public string type2 { get; set; }
public string type3 { get; set; }
public string type4 { get; set; }
}
[Activity (Label = "JsonTest", MainLauncher = true)]
public class MainActivity : Activity
{
int count = 1;
private const string JsonText = "[{\"type1\":\"val1\",\"type2\":\"val2\",\"type3\":\"val3\",\"type4\":\"val4\"}," +
"{\"type1\":\"val1\",\"type2\":\"val2\",\"type3\":\"val3\",\"type4\":\"val4\"}]";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate
{
var resp = Newtonsoft.Json.JsonConvert.DeserializeObject<List<TypeClass>>(JsonText);
foreach (var t in resp)
{
Log.Info("Type1", t.type1);
Log.Info("Type2", t.type2);
Log.Info("Type3", t.type3);
Log.Info("Type4", t.type4);
}
};
}
}
}
Try this
String jsonString = json.replaceAll("\\\\", "");
Related
I put json file in Application.persistentDataPath,then It's can load and work on PC.
But It can't work in Android ,I'm stuck for a long time.
I found the many way , but no one can fix it .
please help me , thank you!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class QuizCon : MonoBehaviour
{
public RoundData[] allRoundData;
private string gameDataFileName = "quiz.json";
private void Start()
{
DontDestroyOnLoad(gameObject);
LoadGameData();
}
public RoundData GetCurrectRoundData()
{
return allRoundData[0];
}
private void LoadGameData()
{
string filePath = Path.Combine(Application.persistentDataPath, gameDataFileName);
if(File.Exists(filePath))
{
string dataJson = File.ReadAllText(filePath);
GameData loadedData = JsonUtility.FromJson<GameData>(dataJson);
allRoundData = loadedData.allRoundData;
}
else
{
Debug.LogError("Cannot load game data!");
}
}
Try writing the file to External (SDCard) instead of Internal.
You can change this under PlayerSettings -> Android
Complete base 64 string is not uploding to json request
Actual json request is:
{
"obj":
{
"FarmerName":"abcd",
"IdAgent":"123",
"TPFileUpload":"_9j_4AAQSkZJRgABAQAAAQABAAD_2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFx..............",
"TPFileUploadType":"jpg"
}
}
But From code json request as follows:
{"obj":{"FarmerName":"","
IdAgent":"",
"TPFileUpload":"_9j_4AAQSkZJRgABAQAAAQABAAD_2wBDABALDA4MChAODQ4
Issues are:
1)json is not closed
2)base 64 string of image is not completely uploading to json request.
3)The parameter after "TPFileUpload" are not adding to json request because
of Base 64 encoded string of image.
Service Request as follows:
#Headers("Content-Type: application/json")
#POST("service/saveinput")
Call<SaveInputResponse> saveInput(#Body SaveInput saveinput);
saveInput pojo class:
public class SaveInput {
#SerializedName("obj")
#Expose
private Input obj;
public Input getObj() {
return obj;
}
public void setObj(Input obj) {
this.obj = obj;
}
}
Input class:
public class FooInput {
#SerializedName("FarmerName")
#Expose
private String farmerName;
#SerializedName("IdAgent")
#Expose
private String idAgent;
#SerializedName("TPFileUpload")
#Expose
private String tPFileUpload;
#SerializedName("TPFileUploadType")
#Expose
private String tPFileUploadType;
//Getters and setters of Variables...
}
I have tried the request using retrofit library and also with volley library,but no result,can you please provide suggestion to upload base64 string to json request in android.and some times "/" is replaced by "_"base64 string of request...
Note:base64 encode string is too large i.e,more than 180 lines..
I am also using this. I add my code. May help this.
01. First get your image and convert it base64.
02. Http request with Json format.
[
{
"attachment": "Your base64 String",
"clients": {
"CLIENTS_ID": "18081000000120"
},
"projects": {
"PROJECT_ID": "18081000000306"
},
"userCode": "18011000000027"
}
]
I am trying to get the CompanyEndpoint for each client's site but I am confused with the use of retrofit on the interface.
Here's what I have so far:
CompanyName : "company1"
CompanyEndpoint : "https://example.com"
IdentityEndpoint : "https://example.com/identity"
AppLoginMode : "Anonymous"
AppRouterApi.java
public interface AppRouterApi {
#GET("api/sites/{CompanyName}")
Call<Company> getCompanyName (#Url String companyName);
}
Company.java
public class Company {
String Endpoint;
public String getEndpoint() {
return endpoint;
}
}
MainActivity.java
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
appRouterApi = retrofit.create(AppRouterApi.class);
getCompany();
}
private void getCompany(){
retrofit2.Call<Company> companyRequest = appRouterApi.getCompanyName(); //Error here saying a string cant be applied to ()
companyRequest.enqueue(new retrofit2.Callback<Company>() {
#Override
public void onResponse(retrofit2.Call<Company> call, retrofit2.Response<Company> response) {
if(!response.isSuccessful()){
textViewResult.setText("Code:" + response.code());
return;
}
Company company = response.body();
String content = "";
content += "Url" + company.getEndpoint();
textViewResult.setText(content);
}
#Override
public void onFailure(retrofit2.Call<Company> call, Throwable t) {
}
});
}
https://example/sites/{companyName}
So if I search for:
https://example/sites/company1
The JSON will have one object and I need to get the endpoint URL value which would be: https://company1.com
Edit: My textViewReslt is returning 403
There are several things going on as far as I can tell. Let me break it into chunks.
First thing is you're confusing the annotation #Path with the annotation #Url. They serve different purposes.
You use #Path when you want to format a bit of the path into the url inside the annotations like #GET.
public interface AppRouterApi {
#GET("api/sites/{CompanyName}")
Call<Company> getCompanyName (#Path("CompanyName") String companyName);
}
This interface will format the argument passed to getCompanyName as part of the path. Calling getCompanyName("foo") will call the endpoint "https://example.com/api/sites/foo".
You use #Url when you want to simply call that url. In this case, you only annotate the interface method with the http method. For example,
public interface AppRouterApi {
#GET
Call<Company> getCompanyName (#Url String url);
}
You then would have to call the method with the entire url. To call the same url as before you'd have to call getCompanyName("https://example.com/api/sites/foo").
This is the main difference of usage between these 2 annotations. The reason why you're seeing null in your text view is because you're model's attribute name doesn't match the json. You have 2 options.
First, you can change the model to:
public class Company {
String CompanyEndpoint;
public String getEndpoint() {
return endpoint;
}
}
CompanyEndpoint is the exact same name as you have in the json. Another approach, is to tell your json serializer what name you want to use. Since you're using gson, you can use #SerializedName like so:
public class Company {
#SerializedName("CompanyEndpoint")
String Endpoint;
public String getEndpoint() {
return endpoint;
}
}
#SerializedName("CompanyEndpoint") tells gson which name to use while serializing and deserializing.
In essence, you have 2 options. You either use the endpoint, or the company's name. If you don't expect the domain to change, I'd suggest using the first approach with the #Path annotation. This is what it's usually done with Retrofit and personally, I think it's easier to handle than passing urls around. My suggestion is, use a model like:
public class Company {
#SerializedName("CompanyName")
String name;
public String getName() {
return name;
}
}
This would let you access the company's name property and call getCompanyName(company.getName()). Retrofit would format the company's name into the path and you'd call the right url.
so I'm trying to send a simple String to my REST server from an Android app using androidannotations.
http://localhost:8080/TestServer_RESTJersey/api/lanceurs/parPays
Using Advanced REST client chrome extension, I send the parameter :
country=Europe
and it's working fine. Now my problem whith the Android app is that my request is received by the server, but the country parameter is always null. My others GET requests are all working perfectly.
Here is my RestClient class :
#Rest(converters = {MappingJacksonHttpMessageConverter.class, FormHttpMessageConverter.class})
public interface RestClient extends RestClientRootUrl, RestClientSupport{
#Get("/poke/simple")
public MessageResponse simplePoke();
#Get("/api/lanceurs/{name}")
public LaunchVehicleResponse nameRequest(String name);
//server doesn't get the parameter here...
#Post("/api/lanceurs/parPays")
public LaunchVehicleResponse countryRequest(String country);
}
Any help would be appreciated as usual, thanks!
EDIT :
server-side REST api :
#Path("api/lanceurs/parPays")
#POST
public String getLanceurByCountry(#FormParam("country") String country)
{
initData();
LaunchVehicleResponse lvr = new LaunchVehicleResponse();
ArrayList<LaunchVehicle> allv = myDatabase.getDataByCountry(country);
lvr.setData(allv);
return parseObjectToJson(lvr);
}
In JAX-RS, use #QueryParam annotation to inject URI query parameter into Java method. example,#QueryParam("country") String countryName,
Try the below, i guess, it should work
#Post("/api/lanceurs/parPays")
public LaunchVehicleResponse countryRequest(#QueryParam("country") String country);
Ok, it seems I figured out a way to get myself out of this mess.
I made a class LaunchVehicleRequest on my client, containing (among other things) a country String. When I need to send a request to my server, I instantiate this class and initialize LaunchVehicleRequest.country with the value I want (ex: "USA"). Then I send the whole object to my RestClient.
LaunchVehicleRequest lvreq = new LaunchVehicleRequest();
lvreq.setCountry("Europe");
LaunchVehicleResponse lvr = pm.countryRequest(lvreq);
...
#Rest(converters = {MappingJacksonHttpMessageConverter.class, FormHttpMessageConverter.class}, interceptors = { LoggingInterceptor.class } )
public interface RestClient extends RestClientRootUrl, RestClientSupport, RestClientHeaders{
#Post("/api/lanceurs/parPays")
public LaunchVehicleResponse countryRequest(LaunchVehicleRequest request);
}
I set up the same class on my server-side, which get the request as a string and then convert it in an object.
#Path("api/lanceurs/parPays")
#POST
public String getLanceurByCountry(String request)
{
// request={"country":"USA"}
//my json parsing function here
LaunchVehicleRequest lvreq = parseJsonToRequest(request);
...
}
I don't know is this is the best way, but hey it's working fine now and I'm using my LaunchVehicleRequest class for every different request I can need to, so it's not THAT bad I guess ^^'
Thanks everyone anyway ;)
As explained on the wiki, you can send form parameters this way:
#Rest(rootUrl = "http://company.com/ajax/services", converters = { FormHttpMessageConverter.class, MappingJackson2HttpMessageConverter.class })
public interface MyRestClient extends RestClientHeaders {
#RequiresHeader(HttpHeaders.CONTENT_TYPE)
#Post("/api/lanceurs/parPays")
public LaunchVehicleResponse countryRequest(MultiValueMap<String, Object> data);
}
MultiValueMap<String, Object> data = new LinkedMultiValueMap<>();
data.set("country, "Europe");
client.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE);
client.countryRequest(data);
I have a web-service:
#Path("/")
#RequestScoped
public class RegistrationService implements Serializable {
#Inject
private DeviceService deviceService;
#PUT
#Path( "/register/{device}" )
#Consumes( MediaType.TEXT_PLAIN )
#Produces( MediaType.TEXT_PLAIN )
public String device(#PathParam("device") String device) {
this.deviceService.saveNewDevice(device);
return "Succesful!";
}
}
And I have a restlet:
public void sendRegistration() {
ClientResource resource = new ClientResource(REG_URL);
resource.addSegment(ctx.getString(R.string.config_segment_register));
... (?)
}
So the current URL will be something like http:// host:port/application/ws/register/pathParam
How can I do the PUT-call to the web-service? There are methods to add queryParams and I could do addSegment to append the ID to the path, but somehow I need to do the PUT then.
almost there try
resource.put(representation);
where the representation is your plain text document. Probably a StringRepresentation but that is up to you.
Due to unfortunately not getting to work (maybe because of too little knowledge about/understanding of the API and processing) the suggestion by #Caleryn, I made some similar solution to https://stackoverflow.com/a/735090/1343241
#Path("/")
#RequestScoped
public class RegistrationService implements Serializable {
#Inject
private DeviceService deviceService;
#PUT
#Path( "/register" )
#Consumes( MediaType.APPLICATION_FORM_URLENCODED )
#Produces( MediaType.TEXT_PLAIN )
public String device(#FormParam("regId") String regId) {
this.deviceService.saveNewDevice(regId);
return "Succesful!";
}
}
And in the restlet:
Form queryParams = resource.getReference().getQueryAsForm();
queryParams.set("regId", regId);
resource.put(queryParams);