Couldn't get "name" value from json via Retrofit - android

I have a problem for getting "ad" value from mysql database.
Here is my listele.php code to get a json format including values.
<?php
//If the values are not blank
//Connecting to our database by calling dbConnect script
include('connection.php');
Class Kullanici{
public $id = "";
public $ad = "";
public $soyad = "";
}
$kl = new Kullanici();
$sql = "SELECT * FROM kullanici";
$list = mysqli_query($conn,$sql);
$resultFromSql = mysqli_num_rows($list);
$sayac = 0;
echo("[");
while($result = mysqli_fetch_assoc($list)){
$sayac = $sayac + 1;
$kl->id = $result["id"];
$kl->ad = $result["ad"];
$kl->soyad = $result["soyad"];
echo json_encode($kl,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
if($resultFromSql != $sayac){
echo(",");
}
}
echo("]");
?>
When I run the code snippet, I get the json format
[{ "id": "27", "ad": "Aslı", "soyad": "Şafak" },{ "id": "29", "ad": "Ali", "soyad": "Ak" },{ "id": "30", "ad": "Ersin", "soyad": "Demir" },{ "id": "31", "ad": "Sercan", "soyad": "Demirbaş" }]
When I get these values from json format to insert all them into the listview, "ad" value is null but others have their values.
kullanicilist = new ArrayList<>();
Call<List<Kullanici>> x = Manager.getInstance().goster();
x.enqueue(new Callback<List<Kullanici>>() {
#Override
public void onResponse(Call<List<Kullanici>> call, Response<List<Kullanici>> response) {
Log.i(LOG,"istek | onResponse is working");
if (response.isSuccessful()) {
kullanicilist = response.body();
Log.i(LOG,"istek | kullanicilist : " + kullanicilist.toString());
adp = new KullaniciAdapter(kullanicilist, getApplicationContext(), MainActivity.this);
listView.setAdapter(adp);
}
}
#Override
public void onFailure(Call<List<Kullanici>> call, Throwable t) {
Log.i(LOG,"istek | onFailure is working");
Log.i(LOG,t.getMessage());
}
});
First Log statement in onResponse
I/com.example.dbtojson.activity.MainActivity: istek | kullanicilist : [Kullanici{id='27', isim='null', soyad='Şafak'}, Kullanici{id='29', isim='null', soyad='Ak'}, Kullanici{id='30', isim='null', soyad='Demir'}, Kullanici{id='31', isim='null', soyad='Demirbaş'}]

Data you get from server is
{ "id": "27", "ad": "Aslı", "soyad": "Şafak" }
Data you are printing in retrofit client is
Kullanici{id='27', isim='null', soyad='Şafak'}
Server is sending value "Asli" in key name ad. Your client has member variable isim which is a different key name, that's why it is not getting mapped.
In client,
Change your member variable name from isim to ad
OR
if you are using GSON then put annotation above it.
#SerializedName("ad")
String isim
This will map value of key ad to isim

Related

Retrofit2 Android: retrieve nested data (current error: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $)

I'm trying to retrieve some character data from the Marvel API which looks like this:
{
"code": 200,
"status": "Ok",
"copyright": "© 2019 MARVEL",
"attributionText": "Data provided by Marvel. © 2019 MARVEL",
"attributionHTML": "Data provided by Marvel. © 2019 MARVEL",
"etag": "cc6c6c3e7f5e336ecf899ab5652d55e6a3a51b09",
"data":
{
"offset": 0,
"limit": 20,
"total": 1493,
"count": 20,
"results":
[
{
"id": 1011334,
"name": "3-D Man",
"description": "",
"modified": "2014-04-29T14:18:17-0400",
"thumbnail": {
"path": "http://i.annihil.us/u/prod/marvel/i/mg/c/e0/535fecbbb9784",
"extension": "jpg"
},
"resourceURI": "http://gateway.marvel.com/v1/public/characters/1011334",
"comics": {},
"series": {},
"stories": {},
"events": {},
"urls": []
},
But I obviously only want to show the results (data -> results -> array of characters), I was watching this tutorial where someone was able to get some data from a simple API where it was just an array (not nested). How could I make this work? Currently I got this code inside my activity:
textViewResult = findViewById(R.id.textView_result);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://gateway.marvel.com/v1/public/")
.addConverterFactory(GsonConverterFactory.create())
.build();
MarvelAPI marvelAPI = retrofit.create(MarvelAPI.class);
Call<List<Character>> call = marvelAPI.getCharacters();
call.enqueue(new Callback<List<Character>>() {
#Override
public void onResponse(Call<List<Character>> call, Response<List<Character>> response) {
if(!response.isSuccessful()){
textViewResult.setText("Code: " + response.code());
return;
}
List<Character> characters = response.body();
for (Character character : characters){
String content = "";
content += "ID: " + character.getId() + "\n";
content += "Name: " + character.getName() + "\n";
content += "Description: " + character.getDescription() + "\n";
content += "Modified: " + character.getModified() + "\n";
content += "Thumbnail: " + character.getThumbnail() + "\n";
textViewResult.append(content);
}
}
#Override
public void onFailure(Call<List<Character>> call, Throwable t) {
textViewResult.setText(t.getMessage());
}
});
MarvelAPI interface which is being used in the activity:
public interface MarvelAPI {
#GET("characters")
Call<List<Character>> getCharacters();
}
This obviously doesn't work because it gives me an "Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $" error. I also tried to make 2 new classes: CharacterData which has a list of results and also CharactersResults which has a list of Characters, but this doesn't work either (even after trying to change the call.enqueue and the MarvelAPI interface).. Or I just don't really know how to change my call.enqueue to let it take the right data with those 3 classes. Anyone able to point me in the right direction?
(PS: I do know that putting all the results into a textview is messy but it's just first version to make the API retrieve the correct data, I do plan on putting it into a grid or something else)
The easiest way to deal with this is actually using the models you mention. Essentially, make the java objects mimic the json structure. In this case you can do something like:
class CharacterData {
#SerializedName("results")
List<Character> characters;
// ...
}
class CharactersResults {
#SerializedName("data")
CharacterData data;
// ...
}
Like you said, now you need to change the retrofit calls. The interface for the proxy must now return CharactersResults:
public interface MarvelAPI {
#GET("characters")
Call<CharactersResults> getCharacters();
}
which in turn changes the callback parameters too:
call.enqueue(new Callback<CharactersResults>() {
#Override
public void onResponse(Call<CharactersResults> call, Response<CharactersResults> response) {
// ...
List<Character> characters = response.body().data.characters;
// ...
}
#Override
public void onFailure(Call<CharactersResults> call, Throwable t) {
// ...
}
});
PS: For brevity, I've ignored creating getters and setters

GSON issue when parsing a strange JSON string

i have the below json string,
"objects": [{
"d430f6c0-a293-4fb9-86fe-a163618cf180": {
"id": "d430f6c0-a293-4fb9-86fe-a163618cf180",
"in_use": 0,
"alterable": 1,
"comment": ""
},
"123-a293-4fb9-86fe-a163618cf180": {
"id": "123-a293-4fb9-86fe-a163618cf180",
"in_use": 2,
"alterable": 3,
"comment": "dfgfg"
}
}]
and cant figure out a way to parse it, all objects in the array have the id in front as shown above.
Thanks for the help in advance.
Firstly your json array is in wrong format you can check it jsonviewer
your json data will be like this:
{"objects": [{
"d430f6c0-a293-4fb9-86fe-a163618cf180": {
"id": "d430f6c0-a293-4fb9-86fe-a163618cf180",
"in_use": 0,
"alterable": 1,
"comment": ""
},
"123-a293-4fb9-86fe-a163618cf180": {
"id": "123-a293-4fb9-86fe-a163618cf180",
"in_use": 2,
"alterable": 3,
"comment": "dfgfg"
}
}]}
now for parsing this data you can use this method:
public void parseData(String jsonObjectData) {
try {
JSONObject jsonObject = new JSONObject(jsonObjectData);
JSONArray jsonArray = jsonObject.getJSONArray("objects");
for (int i = 0 ; i <jsonArray.length(); i ++)
{
String id = jsonArray.getJSONObject(i).getJSONObject("d430f6c0-a293-4fb9-86fe-a163618cf180").getString("id");
Log.d("id", id);
}
} catch (Exception e) {
}
}
you have to get json object like this String id = jsonArray.getJSONObject(i).getJSONObject("d430f6c0-a293-4fb9-86fe-a163618cf180").getString("id");
it will provide single object data, you cannot fetch all because your json is not in proper format.

Getting element of JSON object when key isn't the same [Android]

I want to learn a bit more about android and wanted to create an app that will track the price of cryptocurrencies. I choosed this API: https://www.cryptocompare.com/api/#introduction
My problem is the following: When I want to get the list of all the coin the JSON response looks like this:
{
"Response": "Success",
"Message": "Coin list succesfully returned!",
"BaseImageUrl": "https://www.cryptocompare.com",
"BaseLinkUrl": "https://www.cryptocompare.com",
"Data": {
"42": {
"Id": "4321",
"Url": "/coins/42/overview",
"ImageUrl": "/media/19984/42.png",
"Name": "42",
"CoinName": "42 Coin",
"FullName": "42 Coin (42)",
"Algorithm": "Scrypt",
"ProofType": "PoW",
"FullyPremined": "0",
"TotalCoinSupply": "42",
"PreMinedValue": "N/A",
"TotalCoinsFreeFloat": "N/A",
"SortOrder": "34"
},
"365": {
"Id": "33639",
"Url": "/coins/365/overview",
"ImageUrl": "/media/352070/365.png",
"Name": "365",
"CoinName": "365Coin",
"FullName": "365Coin (365)",
"Algorithm": "X11",
"ProofType": "PoW/PoS",
"FullyPremined": "0",
"TotalCoinSupply": "2300000000",
"PreMinedValue": "299000000",
"TotalCoinsFreeFloat": "N/A",
"SortOrder": "916"
},
(here is the URL I use (https://www.cryptocompare.com/api/data/coinlist/)
I want to keep all the informations about the coin (everything from "Data") but the key isn't the same.
How can I get those informations to create my differents coins?
Thank's in advance
You can use JSONObject#names() to get all the keys as JSONArray and loop the JSONArray.
JSONObject data = response.getJSONObject("Data");
JSONArray array = data.names(); // contains all the keys inside Data
// now loop the array
for (int i = 0; i < array.length(); i++ ) {
String key = array.getString(i); // 42 or 365 for your example code
JSONObject obj = data.getJSONObject(key); // contains the JSONObject of the key 42 or 365
}
Another way is to use JSONObject#keys() but that uses Iterator and hasNext() for iteration which is less performance efficient than the above normal for loop approach in Android.
The accepted answer is fine. I would like to show the way of parsing using Gson from your JSON. Here's how it can be parsed using Gson.
You need to have two classes.
Here's your APIResponse.java
public class APIResponse {
public String Response;
public String Message;
public String BaseImageUrl;
public String BaseLinkUrl;
public HashMap<String, DataObject> Data;
}
And the DataResponse class should look like
public class DataObject {
public String Id;
public String Url;
public String ImageUrl;
public String Name;
public String CoinName;
public String FullName;
public String Algorithm;
public String ProofType;
public String FullyPremined;
public String TotalCoinSupply;
public String PreMinedValue;
public String TotalCoinsFreeFloat;
public String SortOrder;
}
Now its pretty easy.
Type type = new TypeToken<APIResponse>(){}.getType();
APIResponse response = new Gson().fromJson(yourJsonString, type);
Now iterate the HashMap for getting the keys and corresponding values.
You can fetch all the keys and iterate as below
try {
JSONObject dataObj = obj.getJSONObject("Data"); //obj is the parent json object.
Iterator<?> keys = dataObj.keys();
while(keys.hasNext()) {
JSONObject coinObj = dataObj.getJSONObject(keys.next().toString());
}
} catch (JSONException e) {
e.printStackTrace();
}

Get JSONArray with Volley in Android

I'm trying to get this JSONArray with android but I can't get codigo and nombre of all items.
I leave the JSON that I'm trying to get:
{"categorias":
{"cfcd208495d565ef66e7dff9f98764da":{"orden":0,"codigo":"001","nombre":"TUBO Y ACCESORIO DE COBRE, LATON"},
"c4ca4238a0b923820dcc509a6f75849b":{"orden":1,"codigo":"002","nombre":"TUBO Y ACCESORIO PVC PRESION"},
"c81e728d9d4c2f636f067f89cc14862c":{"orden":2,"codigo":"003","nombre":"AISLAMIENTO"},
"eccbc87e4b5ce2fe28308fd9f2a7baf3":{"orden":3,"codigo":"004","nombre":"MONTAJE DE AGUA SANITARIA"},
"a87ff679a2f3e71d9181a67b7542122c":{"orden":4,"codigo":"005","nombre":"ABRAZADERAS FONTANERIA"},"e4da3b7fbbce2345d7772b0674a318d5":{"orden":5,"codigo":"006","nombre":"FLEXOS DE ACERO"},
"1679091c5a880faf6fb5e6087eb1b2dc":{"orden":6,"codigo":"007","nombre":"ACCESORIOS DE SANEAMIENTO"},
...
...
...
This is my code on Android, and I always get null response:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, showUrl, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println("Respuesta:"+ response.toString());
try {
listaCategorias.clear();
int array=0;
JSONArray categorias = response.getJSONArray("categorias");
for (int i = 0; i < categorias.length(); i++) {
JSONObject objet = categorias.getJSONObject(i);
String titulo = objet.getString("nombre");
if (isIntegerParseInt(String.valueOf(titulo.charAt(0))))
listaCategorias.add(titulo);
}
array++;
onCallBack.onSuccess(listaCategorias);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("ErrorRespuesta: "+error.getMessage());
}
});
requestQueue.add(jsonObjectRequest);
its not an JSON ARRAY
Its JSON OBJECT
for your reference I'm posting sample json array
"three_day_forecast": [
{
"conditions": "Partly cloudy",
"day" : "Monday",
"temperature": 20
},
{
"conditions": "Showers",
"day" : "Tuesday",
"temperature": 22
},
{
"conditions": "Sunny",
"day" : "Wednesday",
"temperature": 28
}
]
Data was used by this reference.
It's not an Array but a JSONObject you need to modify your JSON to get an array with [] and not {}. Or you get it by getJSONObject.
With reference to the JSON String you've posted categorias is not a JSONArray. it's an object and the JSON string is still invalid.
On the top of the String you have the key as categories, now if you want to use that as an array you must have the value of categories to array which is specified within [ ] in JSON strings.
Another thing is try to avoid random key of the JSON Array if you're using it within loops with indexes. So your JSON String might look like following to support your Android code.
{
"categories": [
{ object 1... },
{ object 2... },
and so on...
]
}
You can see the type of JSON you will need here:
http://json-parser.com/53b37f69

insert data to mssql with webservice from Android

my webservice codes here:
namespace AndWeb
{
public partial class Products : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e1)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
List<Employee> eList = new List<Employee>();
string temp = "";
try
{
SqlConnection connection = new SqlConnection(
WebConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString);
connection.Open();
string query = "select * from AndLogin";
SqlCommand cmd = new SqlCommand(sorgu, connection);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Employee e = new Employee();
e.ID = Convert.ToInt32(reader["ID"].ToString());
e.Name = reader["Name"].ToString();
e.SurName = reader["SurName"].ToString();
e.Password = reader["Password"].ToString();
eList.Add(e);
}
}
catch (Exception ex)
{
temp = "Hata : " + ex.Message;
}
string ans = JsonConvert.SerializeObject(eList, Newtonsoft.Json.Formatting.Indented);
temp = "{\"login\":" + ans + "}";
Response.Write(temp);
}
}
public class Employee
{
public int ID;
public string Name;
public string SurName;
public string Password;
}
}
webservice Json output is:
{"login":[ { "ID": 1112602055, "Name": "david", "SurName": "suarez", "Password": "****" }, { "ID": 1112602056, "Name": "damon", "SurName": "gomez", "Password": "****" }, { "ID": 1112602057, "Name": "kinsella", "SurName": "mark", "Password": "****" } ]}
i can read my datas from mssql with JSON but how can i insert data to sql from my android application??
There are many tutorials out there explaining how to execute a SQL statement from .Net
You should try reading some of them.
By the way, What you're showing is not a traditional .Net Webservice, it's a WebForm.
Your approach can still work, but your application would need to post data to the web form, same as the user clicking the submit button in a browser.
I don't want to go into too much detail, because I feel you should try and find the answer yourself, but
To insert the data, instead of calling
SqlDataReader reader = cmd.ExecuteReader();
You need to add parameters to your cmd object. Yyou should be able to read them from the Request.Form object if your post was successful.. i.e.
cmd.Parameters.Add("SomeName", Request.Form["SomeName"]);
you would then use
cmd.ExecuteNonReader();

Categories

Resources