This is my api
{}JSON
[]products
{}0
product-name : "Fiting"
product-id : "1"
product-description : "Door"
product-image : "https://image/logo.jpg"
product-categoryid : "2"
category-name : "Furniture"
{}1
product-name : "Bathroom"
product-id : "2"
product-description : "Services"
product-image : "https://image/logo.jpg"
product-categoryid : "1"
category-name : "Plumber"
subcategory-id : "1"
subcategory-name : "Bathroom"
subCategoryDetailModelClass.setSubCategoryId(productObject.getInt("subcategory-id"));
subCategoryDetailModelClass.setSubCategoryName(productObject.getString("subcategory-name"));
i cannot add subcategory-id,subcategory-name in my arraylist since it is not available at 0th position.....so how to check condition that if in api subcategory-id,subcategory-name is not available add other items in the list
StringRequest stringRequest = new StringRequest(Request.Method.GET,URLs.productURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("zsded", response.toString());
try {
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("products");
//now looping through all the elements of the json array
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
SubCategoryDetailModelClass subCategoryDetailModelClass = new SubCategoryDetailModelClass();
// if(productObject.getInt("subcategory-id"))
subCategoryDetailModelClass.setProduct_name(productObject.getString("product-name"));
subCategoryDetailModelClass.setProduct_id(productObject.getInt("product-id"));
subCategoryDetailModelClass.setProduct_desc(productObject.getString("product-description"));
subCategoryDetailModelClass.setProduct_imgURL(productObject.getString("product-image"));
subCategoryDetailModelClass.setProduct_CategoryId(productObject.getInt("product-categoryid"));
subCategoryDetailModelClass.setProduct_Category_Name(productObject.getString("category-name"));
subCategoryDetailModelClass.setSubCategoryId(productObject.getInt("subcategory-id"));
subCategoryDetailModelClass.setSubCategoryName(productObject.getString("subcategory-name"));
subCategoryListDetailModelClassArray.add(subCategoryDetailModelClass);
Log.d("subcatdetail", String.valueOf(subCategoryDetailModelClass));
}
Use this class
public class JSONHelper {
public static String getString(JSONObject json, String tag) throws JSONException {
if(mJSONValueAvailable(json, tag)) {
return json.getString(tag);
}
return "";
}
public static int getInt(JSONObject json, String tag) throws JSONException {
if(mJSONValueAvailable(json, tag)) {
if(json.get(tag) instanceof String) {
if(json.getString(tag).equalsIgnoreCase("None")) {
return -1;
}
if(!json.getString(tag).equals("")) {
return Integer.parseInt(json.getString(tag));
} else {
return -1;
}
}
return json.getInt(tag);
}
return -1;
}
public static boolean getBoolean(JSONObject json, String tag) throws JSONException {
if(mJSONValueAvailable(json, tag)) {
Object value = json.get(tag);
if(value instanceof String) {
return PrimitiveHelper.StringToBoolean((String) value);
} else if (value instanceof Integer) {
return PrimitiveHelper.IntegerToBoolean((int)value);
}
return json.getBoolean(tag);
}
return false;
}
public static Boolean getBooleanBoxed(JSONObject json, String tag) throws JSONException {
if(mJSONValueAvailable(json, tag)) {
Object value = json.get(tag);
if(value instanceof String) {
return PrimitiveHelper.StringToBooleanBoxed((String) value);
} else if (value instanceof Integer) {
return PrimitiveHelper.IntegerToBooleanBoxed((int) value);
}
return json.getBoolean(tag);
}
return null;//false;
}
private static boolean mJSONValueAvailable(JSONObject json, String tag) {
return json.has(tag) && !json.isNull(tag);
}
// private static Boolean mJSONValueAvailableBoxed(JSONObject json, String tag) {
// return json.has(tag) && !json.isNull(tag);//
// }
public static JSONArray sortJsonArray(JSONArray array, String sort) {
final String sortKey = sort;
//Logger.d("sortJSONArray by::: " + sortKey);
List<JSONObject> jsons = new ArrayList<JSONObject>();
try {
for (int i = 0; i < array.length(); i++) {
jsons.add(array.getJSONObject(i));
}
Collections.sort(jsons, new Comparator<JSONObject>() {
#Override
public int compare(JSONObject lhs, JSONObject rhs) {
try {
String lid = lhs.getString(sortKey);
String rid = rhs.getString(sortKey);
// Here you could parse string id to integer and then compare.
return lid.compareTo(rid);
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
});
} catch (JSONException e) {
e.printStackTrace();
}
return new JSONArray(jsons);
}
}
Call this as follows
subCategoryDetailModelClass.setProduct_name(JSONHelper.getString(productObject, "product-name"));
subCategoryDetailModelClass.setProduct_id(JSONHelper.getInt(productObject,"product-id"));
subCategoryDetailModelClass.setProduct_desc(JSONHelper.getString(productObject, "product-description"));
subCategoryDetailModelClass.setProduct_imgURL(JSONHelper.getString(productObject, "product-image"));
subCategoryDetailModelClass.setProduct_CategoryId(JSONHelper.getInt(productObject,"product-categoryid"));
subCategoryDetailModelClass.setProduct_Category_Name(JSONHelper.getString(productObject, "category-name"));
subCategoryDetailModelClass.setSubCategoryId(JSONHelper.getInt(productObject, "subcategory-id"));
subCategoryDetailModelClass.setSubCategoryName(JSONHelper.getString(productObject,"subcategory-name"));
subCategoryListDetailModelClassArray.add(subCategoryDetailModelClass);
Use Opt methods, For e.g.
optInt(String name, int fallback)
Returns the value mapped by name if it exists and is an int or can be
coerced to an int, or fallback otherwise.
There are optMethods for mostly primitive datatypes, check here
Related
I have a some JSON Data -
{
"ActivityOrder":[
{
"Position":3,
"ActivityName":"Activity1"
},
{
"Position":5,
"ActivityName":"Activity2"
},
{
"Position":2,
"ActivityName":"Activity3"
},
{
"Position":1,
"ActivityName":"Activity4"
},
{
"Position":4,
"ActivityName":"Activity5"
}
]
}
According to above JSON data, call Intent from Single Activity or class. I mean First call Position1 activity (Activity4), then position2 (Activity3) and so on.
Note:- In JSON Data, Activity Position can be changed from backend.
As soon as you get your activity name , create the class like this :
Class activity= Class.forName("yourActivityName");
And then create the intent :
Intent intent = new Intent(this, activity);
Create pojo model class:
public class MyPojo {
String ActivityName;
int Position;
public MyPojo(String activityName, int position) {
ActivityName = activityName;
Position = position;
}
public int getPosition() {
return Position;
}
public void setPosition(int position) {
Position = position;
}
public String getActivityName() {
return ActivityName;
}
public void setActivityName(String activityName) {
ActivityName = activityName;
}
}
Now parse json to Model:
List<MyPojo> MyPojoList=new ArrayList<>();
try {
JSONObject jObj = new JSONObject("your json response");
JSONArray jArr = jObj.getJSONArray("ActivityOrder");
for (int i=0; i < jArr.length(); i++) {
JSONObject obj = jArr.getJSONObject(i);
String Position = jObj.getString("Position");
String ActivityName = jObj.getString("ActivityName");
MyPojoList.add(new MyPojo(ActivityName,Position));
}
}
catch(JSONException ex) {
ex.printStackTrace();
}
Now sort array :
Collections.sort(MyPojoList, new Comparator<MyPojo>(){
public int compare(MyPojo obj1, MyPojo obj2) {
return Integer.valueOf(obj1.getPosition()).compareTo(Integer.valueOf(obj2.getPosition()));
}
});
Finally, start the activity with position one by one:
Intent intent=new Intent();
intent.setComponent(new ComponentName(getApplicationContext(), MyPojoList.get(position).getActivityName()));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
I am currently using json for my code to retrieve an array of boolean values. However, i am adding a subfield to achieve another array within, but I am not good with json and kind of stuck how to go about it.
Here's my code so far:
field values :
public enum Field {
/**
* Runtime Config Fields
**/
FIELD_CAN_CHANGE_PASSWORD("canChangePassword", true, canUpdate),
FIELD_MAX_AUTO_DOWNLOAD_SIZE("maxAutoDownloadSize", 5000000L),
FIELD_ALWAYS_REAUTHENTICATE("alwaysReauthenticate", false, canUpdate),
FIELD_CAN_START_CALL("canStartCall", false),
FIELD_ROOMS_ENABLED("roomsEnabled", !Core.isMessenger()),
FIELD_CAN_CREATE_ROOM("canCreateRoom", !Core.isMessenger(), canUpdate),
FIELD_MAX_ENVELOPE_TTL("maxTTL", Core.isMessenger() ? 518400L : 31536000L, canUpdate),
FIELD_MAX_BURN_ON_READ_TTL("maxBOR", 0L, canUpdate),
FIELD_MAX_UPLOAD_SIZE("maxUploadSize", -1L, true),
FIELD_FRIEND_FINDER("friendFinder", !Core.isEnterprise(), canUpdate),
FIELD_ONLY_SHOW_IN_NETWORK_CONTACTS("onlyShowInNetwork", false),
FIELD_CAN_ADD_CONTACT("canAddContact", true, canUpdate),
FIELD_FORCE_DEVICE_LOCKOUT("forceDeviceLockout", 5L, canUpdate),
FIELD_VERIFICATION_MODE("verificationMode", VerificationMode.OPTIONAL.getValue(), true),
FIELD_ENABLE_NOTIFICATION_PREVIEW("enableNotificationPreview", true, true),
FIELD_DIRECTORY_ENABLED("directoryEnabled", true, true);
public String fieldName;
public Object defaultValue;
public boolean updateFromServer;
Field(String key, Object defaultValue) {
this(key, defaultValue, true);
}
Field(String key, Object defaultValue, boolean updateFromServer) {
this.fieldName = key;
this.defaultValue = defaultValue;
this.updateFromServer = updateFromServer;
}
}
putting values in field:
private void putValueForField(JSONObject configuration, Field field) {
try {
if (configuration.isNull(field.fieldName)) {
Object value = field.defaultValue;
if (value instanceof long[]) {
JSONArray array = new JSONArray();
for (long obj : (long[]) field.defaultValue) {
array.put(obj);
}
value = array;
}
runtimeConfiguration.put(field.fieldName, value);
} else {
runtimeConfiguration.put(field.fieldName, configuration.get(field.fieldName));
}
} catch (JSONException e) {
}
}
getting values :
private Object getValueForField(Field field) {
if (runtimeConfiguration.has(field.fieldName) && field.updateFromServer) {
try {
Object value = runtimeConfiguration.get(field.fieldName);
if (value instanceof JSONArray) {
JSONArray values = (JSONArray) value;
if (values.get(0) instanceof Number) {
long[] retVals = new long[values.length()];
for (int i = 0; i < values.length(); i++) {
retVals[i] = ((Number) values.get(i)).longValue();
}
return retVals;
}
} else if (value instanceof Number) {
return ((Number) value).longValue();
} else {
return value;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return field.defaultValue;
}
one of the methods using the fields above:
public boolean canChangePassword() {
return (boolean) getValueForField(Field.FIELD_CAN_CHANGE_PASSWORD);
}
My new json is :
{"enableNotificationPreview":true,"destructOnRead":[30,60,300],"alwaysReauthenticate":false,"forceDeviceLockout":0,"permmod":1516894585,"maxBOR":0,"roomsEnabled":true,"directoryEnabled":true,"canStartCall":true,"canAddContact":true,"legacyDownload":false,"verificationMode":1,"restrictedAdmin":false,"canChangePassword":true,"friendFinder":true,"NEWVALUE":{"canStartNewValue1":true,"canStartroupValue":true,"canVideoCall":true,"canStartRoomValue":true,"canAddtoValue":true,"canStartValueshare":true},"canCreateRoom":true,"maxTTL":2592000,"onlyShowInNetwork":false,"maxUploadSize":null,"availableEnvelopeTTL":[0,600,3600,86400,604800,2592000],"maxAutoDownloadSize":7340032}
where I am plugging in :
"NEWVALUE":{"canStartNewValue1":true,"canStartroupValue":true,"canVideoCall":true,"canStartRoomValue":true,"canAddtoValue":true,"canStartValueshare":true}
Not sure how to update my putValueForField to reflect this new json and the corresponding fields. Any idea?
To check and retrieve JSONObject from the json object you can modify your method to check for instance of JSONObject and assign value to it.
private void putValueForField(JSONObject configuration, Field field) {
try {
if (configuration.isNull(field.fieldName)) {
Object value = field.defaultValue;
if (value instanceof long[]) {
JSONArray array = new JSONArray();
for (long obj : (long[]) field.defaultValue) {
array.put(obj);
}
value = array;
}
// this is how you check if fieldName is of type jsonobject
if (value instanceof JSONObject) {
JSONObject valueObject = configuration.getJSONObject(field.fieldName);
value = valueObject;
}
runtimeConfiguration.put(field.fieldName, value);
} else {
runtimeConfiguration.put(field.fieldName, configuration.get(field.fieldName));
}
} catch (JSONException e) {
}
}
Form what I can understand you are just getting the values from JSON and saving it in field in that case:
I think in this method ultimately you are just storing all values as object only so while retrieving you have to do all this check again.
If you are getting the response from server with fixed Object fields and object values you should be creating a class from that configuration where you will know what exactly it will return. That would really make life easier.
Or maybe if you just need the configuration to get/update or put values you can maintain it in json object itself Android JSON doc reference
For example lets say you have this jsonobject itself, I have added the working example below, hope this helps.
import org.json.*;
class Main {
public static void main(String[] args) throws JSONException {
String jsn = "{\"enableNotificationPreview\":true,\"destructOnRead\":[30,60,300],\"" +
"alwaysReauthenticate\":false,\"forceDeviceLockout\":0,\"NEWVALUE\":{\"canStartNewValue1\":true," +
"\"canStartroupValue\":true,\"canVideoCall\":true,\"canStartRoomValue\":true},\"canCreateRoom\":true," +
"\"maxTTL\":2592000,\"onlyShowInNetwork\":false,\"maxUploadSize\":null,\"availableEnvelopeTTL\"" +
":[0,600,3600,86400,604800,2592000],\"maxAutoDownloadSize\":7340032}";
JSONObject jsnObj = new JSONObject(jsn);
Object enableNotificationPreview = jsnObj.get("enableNotificationPreview");
// or if you know it will be boolean
boolean enableNotificationPreviewBool = jsnObj.getBoolean("enableNotificationPreview");
System.out.println(enableNotificationPreview);
// output : true
System.out.println(enableNotificationPreviewBool);
// output : true
JSONObject NEWVALUEObj = jsnObj.getJSONObject("NEWVALUE");
// now again you can extract values from it
boolean canStartNewValue1 = NEWVALUEObj.getBoolean("canStartNewValue1");
System.out.println(canStartNewValue1);
NEWVALUEObj.put("canStartNewValue1", false);
System.out.println(NEWVALUEObj.toString());
jsnObj.put("forceDeviceLockout", 23456);
// now canStartNewValue1 value is changed to false in the object
// and forceDeviceLockout is also 23456
System.out.println(jsnObj.toString());
}
}
I am using GSON in my android app. Currently, I am setting a method that contains a value from my JSON string called "followed". One of items in the JSON string contains followed and the second string does not. I use Realm to persist the unique object so as you can see it just gets overwritten.
Here are 2 json strings to compare as an example:
{"customer_case":"OFFICE001","circle_id":"3","address":"10 Canal St","city":"Bristol","state":"PA","zip":"19007","county":"Bucks County","apt_no":"","latitude":"40.1012666","longitude":"-74.855304","profile_picture":"uploads/thumbnails/2014/06/07/16/1402165202_3_16_539356ad9134b3.jpg","id":"539356ad9134b3","google_address":"10 Canal Street","google_city":"Bristol","google_state":"Pennsylvania","verified_zip":"19007","google_county":"Bucks County","status":"Active","add_date":"2014-06-07","circle_name":"Test Portfolio","step":"Rental","loan":"","winterized":null,"boiler":null,"sump_pump":null,"septic":null,"police_id":null,"police":null,"police_phone":null,"electric_id":null,"electric":null,"electric_phone":null,"sewer_id":null,"sewer":null,"sewer_phone":null,"water_id":null,"water":null,"water_phone":null,"fsm_company_id":"5","fsm_company":"Assero Services LLC - FSM","fsm_email":"leemertins#assero24.com","fsm_phone":"2155868317","hoa_id":null,"hoa":null,"hoa_email":null,"hoa_phone":null,"client_id":"9","client":"Test Client","client_email":"krishna162#gmail.com","client_phone":"2157830782","broker_contact_id":null,"broker":null,"broker_email":null,"broker_phone":null,"lawn_contractor":null,"cleaning_contractor":null,"bedroom":null,"bathroom":null,"sqft":null,"lot_size":null,"list_price":"538525","built":null,"assign_date":"06/07/2014","lock_box":null,"gate_code":null,"key_code":null,"property_type":"Unknown","description":null,"sub_status":null,"occupancy_status":null,"street_view":"uploads/2015/06/25/4036/0470e4cd-ce9d-4439-8031-6be5101cd09c.JPG","marketing_front":"uploads/2015/06/25/4036/b099a190-f354-454a-8479-bec67bc41988.JPG","followed":"1"}
{"customer_case":"OFFICE001","circle_id":"3","address":"10 Canal St","city":"Bristol","state":"PA","zip":"19007","county":"Bucks County","apt_no":"","latitude":"40.1012666","longitude":"-74.855304","profile_picture":"uploads/thumbnails/2014/06/07/16/1402165202_3_16_539356ad9134b3.jpg","id":"539356ad9134b3","google_address":"10 Canal Street","google_city":"Bristol","google_state":"Pennsylvania","verified_zip":"19007","google_county":"Bucks County","status":"Active","add_date":"2014-06-07","circle_name":"Test Portfolio","step":"Rental","loan":"","winterized":null,"boiler":null,"sump_pump":null,"septic":null,"police_id":null,"police":null,"police_phone":null,"electric_id":null,"electric":null,"electric_phone":null,"sewer_id":null,"sewer":null,"sewer_phone":null,"water_id":null,"water":null,"water_phone":null,"fsm_company_id":"5","fsm_company":"Assero Services LLC - FSM","fsm_email":"leemertins#assero24.com","fsm_phone":"2155868317","hoa_id":null,"hoa":null,"hoa_email":null,"hoa_phone":null,"client_id":"9","client":"Test Client","client_email":"krishna162#gmail.com","client_phone":"2157830782","broker_contact_id":null,"broker":null,"broker_email":null,"broker_phone":null,"lawn_contractor":null,"cleaning_contractor":null,"bedroom":null,"bathroom":null,"sqft":null,"lot_size":null,"list_price":"538525","built":null,"assign_date":"06/07/2014","lock_box":null,"gate_code":null,"key_code":null,"property_type":"Unknown","description":null,"sub_status":null,"occupancy_status":null,"street_view":"uploads/2015/06/25/4036/0470e4cd-ce9d-4439-8031-6be5101cd09c.JPG","marketing_front":"uploads/2015/06/25/4036/b099a190-f354-454a-8479-bec67bc41988.JPG"}
Note the difference is the followed item at the end of the json string.
From the GSON documentation it says:
"While deserialization, a missing entry in JSON results in setting the corresponding field in the object to null."
Is there a way to override this and not automatically set it to null, instead just skip the field?
Here is some code that I am using to deserialize my json:
PropertyObject prop = visnetawrap.gsonClient.fromJson(properties.get(i).toString(), PropertyObject.class);
visnetawrap.gsonClient = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
#Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class) || f.getDeclaredClass().equals(Drawable.class);
}
#Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.registerTypeAdapter(Date.class, new GsonDateDeserializer())
.registerTypeAdapter(Double.class, new TypeAdapter<Double>() {
#Override
public void write(JsonWriter out, Double value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.value(value);
}
#Override
public Double read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String stringValue = in.nextString();
try {
return Double.valueOf(stringValue);
} catch (NumberFormatException e) {
return null;
}
}
})
.create();
Here is what I am doing as a work around:
.registerTypeAdapter(PropertyObject.class, new JsonDeserializer<PropertyObject>() {
#Override
public PropertyObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
PropertyObject prop = new PropertyObject();
JsonObject propObj = json.getAsJsonObject();
if (propObj.get("id") == null) {
return null;
}
prop.setPropertyId(propObj.get("id").getAsString());
if (propObj.get("followed") == null) {
Realm realmThread = Realm.getDefaultInstance();
PropertyObject existingProp = realmThread.where(PropertyObject.class).equalTo("propertyId", propObj.get("id").getAsString()).findFirst();
if (existingProp == null) {
prop.setPropertyFollowed(0);
}
else {
prop.setPropertyFollowed(existingProp.getPropertyFollowed());
}
realmThread.close();
}
else {
prop.setPropertyFollowed(propObj.get("followed").getAsInt());
}
return prop;
}
})
you may create your own TypeAdapter
public class YourTypeAdapter extends TypeAdapter<PropertyObject> {
#Override
public PropertyObject read(final JsonReader in) throws IOException {
final PropertyObject obj = new PropertyObject(); //I don't know how is your obj
in.beginObject();
boolean hasFollowedField = false;
while (in.hasNext()) {
switch (in.nextName()) {
case "gate_code":
//set value to your obj
obj.setValue(in.nextString())
break;
//do same thing to others...
//...
case "followed":
hasFollowedField = true;
//set value to obj
break;
}
if (!hasFollowedField) {
//set followed value to obj what you want
}
}
in.endObject();
return obj;
}
#Override
public void write(final JsonWriter out, final PropertyObject obj) throws IOException {
out.beginObject();
out.name("gate_code").value(gate_code.getGateCode());
//simple set name and value from obj to JsonWriter
out.endObject();
}
}
and then register the TypeAdapter to your GsonBuilder obj
hope it would help
I am facing a problem creating a Json which is actually a complex one and i need to create it through HashMap only..I was actually looking for some recursive function that could be a best solution to my problem.
JSON i need to create looks like..
{"pkt":{
"data2":{"z":"3", "y":"2", "x":"1"},
"data3":{"n":"3", "l":"1", "m":"2"},
"mid":"1328779096525",
"data1":{"b":"2", "c":"3", "a":"1"},
"msg":"10012"
}
}
any ideas??
You'd do something like this:
public void toJSON(Map<?, ?> map, JSONStringer stringer) throws JSONException {
stringer.object();
for (Map.Entry<?, ?> entry : map.entrySet()) {
stringer.key(String.valueOf(entry.getKey()));
toJSONValue(entry.getValue(), stringer);
}
stringer.endObject();
}
public void toJSONValue(Object value, JSONStringer stringer) throws JSONException {
if (value == null) {
stringer.value(null);
} else if (value instanceof Collection) {
toJSON((Collection<?>) value, stringer);
} else if (value instanceof Map) {
toJSON((Map<?, ?>) value, stringer);
} else if (value.getClass().isArray()) {
if (value.getClass().getComponentType().isPrimitive()) {
stringer.array();
if (value instanceof byte[]) {
for (byte b : (byte[]) value) {
stringer.value(b);
}
} else if (value instanceof short[]) {
for (short s : (short[]) value) {
stringer.value(s);
}
} else if (value instanceof int[]) {
for (int i : (int[]) value) {
stringer.value(i);
}
} else if (value instanceof float[]) {
for (float f : (float[]) value) {
stringer.value(f);
}
} else if (value instanceof double[]) {
for (double d : (double[]) value) {
stringer.value(d);
}
} else if (value instanceof char[]) {
for (char c : (char[]) value) {
stringer.value(c);
}
} else if (value instanceof boolean[]) {
for (boolean b : (boolean[]) value) {
stringer.value(b);
}
}
stringer.endArray();
} else {
toJSON((Object[]) value, stringer);
}
} else {
stringer.value(value);
}
}
public void toJSON(Object[] array, JSONStringer stringer) throws JSONException {
stringer.array();
for (Object value : array) {
toJSONValue(value, stringer);
}
stringer.endArray();
}
public void toJSON(Collection<?> collection, JSONStringer stringer) throws JSONException {
stringer.array();
for (Object value : collection) {
toJSONValue(value, stringer);
}
stringer.endArray();
}
To construct the example you gave:
// Using a variety of maps since all should work..
HashMap<String, Object> pkt = new HashMap<String, Object>();
LinkedHashMap<String, String> data1 = new LinkedHashMap<String, String>();
data1.put("b", "2");
data1.put("c", "3");
data1.put("a", "1");
LinkedHashMap<String, String> data2 = new LinkedHashMap<String, String>();
data2.put("z", "3");
data2.put("y", "2");
data2.put("x", "1");
TreeMap<String, Object> data3 = new TreeMap<String, Object>();
data3.put("z", "3");
data3.put("y", "2");
data3.put("x", "1");
pkt.put("data2", data2);
pkt.put("data3", data3);
pkt.put("mid", "1328779096525");
pkt.put("data1", data1);
pkt.put("msg", "10012");
try {
JSONStringer stringer = new JSONStringer();
stringer.object();
stringer.key("pkt");
toJSON(pkt, stringer);
stringer.endObject();
System.out.println(stringer.toString());
} catch (JSONException e) {
// Time for some error-handling
}
Which would result in (formatted for viewing):
{
"pkt":{
"data2":{
"z":"3",
"y":"2",
"x":"1"
},
"mid":"1328779096525",
"data3":{
"x":"1",
"y":"2",
"z":"3"
},
"msg":"10012",
"data1":{
"b":"2",
"c":"3",
"a":"1"
}
}
}
We're using GSON for our object/JSON conversions. Here's a link for more info: GSON
I am having a Web Client in Android using ksoap2 but I can't pass the string array as a parameter to the webservice.
Here's my code
String[] items={"hello","world"};
request.addproperty("str",items);
First use "soapUI" to see correct request structure(like item names,item namespaces , ...).
We assume that you want to write like this XML in request:(here n0 and n1 are namespaces)
<n0:strarray xmlns:n0="http://n0 ..." xmlns:n1="http://n1 ...">
<n1:string>hello</n1:string>
<n1:string>world</n1:string>
</n0:strarray>
extend a class from vector:
import java.util.Hashtable;
import java.util.Vector;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class StringArraySerializer extends Vector<String> implements KvmSerializable {
//n1 stores item namespaces:
String n1 = "http://n1 ...";
#Override
public Object getProperty(int arg0) {
return this.get(arg0);
}
#Override
public int getPropertyCount() {
return this.size();
}
#Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
arg2.setName = "string";
arg2.type = PropertyInfo.STRING_CLASS;
arg2.setNamespace = n1;
}
#Override
public void setProperty(int arg0, Object arg1) {
this.add(arg1.toString());
}
}
To build the request you have to do this:
1-make a new Vector-Object from this class:
StringArraySerializer stringArray = new StringArraySerializer();
2-then you can add elements:
stringArray.add("hello");
stringArray.add("world");
3-then you create a PropertyInfo with it:
//n0 stores array namespace:
String n0 = "http://n0 ...";
stringArrayProperty = new PropertyInfo();
stringArrayProperty.setName("strarray");
stringArrayProperty.setValue(stringArray);
stringArrayProperty.setType(stringArray.getClass());
stringArrayProperty.setNamespace(n0);
4-then you add all the properties to the request:
Request = new SoapObject(NAMESPACE, METHOD_NAME);
Request.addProperty(stringArrayProperty);
Reference:
ksoap2-android,CodingTipsAndTricks
it is like that you shold add it one by one.
public class ExtendedSoapObject extends SoapObject
{
public ExtendedSoapObject(String namespace, String name)
{
super(namespace, name);
}
public ExtendedSoapObject(SoapObject o)
{
super(o.getNamespace(), o.getName());
for (int i = 0; i < o.getAttributeCount(); i++)
{
AttributeInfo ai = new AttributeInfo();
o.getAttributeInfo(i, ai);
ai.setValue(o.getAttribute(i));
addAttribute(ai);
}
for (int i = 0; i < o.getPropertyCount(); i++)
{
PropertyInfo pi = new PropertyInfo();
o.getPropertyInfo(i, pi);
pi.setValue(o.getProperty(i));
addProperty(pi);
}
}
#Override
public SoapObject addProperty(String name, Object value)
{
if (value instanceof Object[])
{
Object[] subValues = (Object[]) value;
for (int i = 0; i < subValues.length; i++)
{
super.addProperty(name, subValues[i]);
}
}
else
{
super.addProperty(name, value);
}
return this;
}
#Override
public Object getProperty(String name)
{
List<Object> result = new ArrayList<Object>();
for (int i = 0; i < properties.size(); i++)
{
PropertyInfo prop = (PropertyInfo) properties.elementAt(i);
if (prop.getName() != null && prop.getName().equals(name))
{
result.add(unwrap(prop));
}
}
if (result.size() == 1)
{
return result.get(0);
}
else if (result.size() > 1)
{
return result.toArray(new Object[0]);
}
else
{
return null;
}
}
public Object[] getArrayProperty(String name)
{
Object o = getProperty(name);
Object values[] = null;
if (o != null)
{
if (o instanceof Object[])
{
values = (Object[]) o;
}
else
{
values = new Object[1];
values[0] = o;
}
}
return values;
}
Object unwrap(Object o)
{
if (o instanceof PropertyInfo)
{
return unwrap(((PropertyInfo) o).getValue());
}
else if (o instanceof SoapPrimitive || o instanceof SoapObject)
{
return o;
}
return null;
}
}