I think I have a very common problem but I cant find a solution :(
I am using spring with restTemplate to recover a JSON object like this:
ResponseEntity<Download_urls> result= restTemplate.exchange(URL, HttpMethod.GET, entity, Download_urls.class);
Where "Download_urls " class have a JSON array inside:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class Download_urls {
private Video[] video;
}
And Video.class
#JsonIgnoreProperties(ignoreUnknown = true)
public class Video {
private String type;
private String label;
private String file;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
}
Obviously Video[] doesn't work to map JSON array. Any help?
Thanks
UPDATE:
Example JSON payload:
{
"id": 737132,
"asset": {
"_class": "asset",
"id": 538362,
"download_urls": {
"Video": [{
"type": "video/mp4",
"label": "360"
}, {
"type": "video/mp4",
"label": "720"
}]
}
}
}
Your Java class names and its properties should follow Java naming conventions. Then your code is much more readable and nicer. And to convert JSON field names to and fro you can use naming strategies, e.g.: LowerCaseWithUnderscoresStrategy, PascalCaseStrategy, etc.
Here you are how I thing classes should look like:
Video.java - same as yours.
DownloadUrls.java:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.PascalCaseStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
#JsonIgnoreProperties(ignoreUnknown = true)
// PascalCaseStrategy is used here because of "Video" JSON field. I would expect
// it to be called "video".
#JsonNaming(PascalCaseStrategy.class)
public class DownloadUrls {
private Video[] video;
public Video[] getVideo() {
return video;
}
public void setVideo(Video[] video) {
this.video = video;
}
}
Asset.java:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
#JsonIgnoreProperties(ignoreUnknown = true)
// LowerCaseWithUnderscoresStrategy is common strategy when used with JSON, but
// in this case it is used because of "download_url" JSON field only.
#JsonNaming(LowerCaseWithUnderscoresStrategy.class)
public class Asset {
int id;
DownloadUrls downloadUrls;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public DownloadUrls getDownloadUrls() {
return downloadUrls;
}
public void setDownloadUrls(DownloadUrls downloadUrls) {
this.downloadUrls = downloadUrls;
}
}
and outer type just for completeness sake:
public class OuterType {
int id;
Asset asset;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Asset getAsset() {
return asset;
}
public void setAsset(Asset asset) {
this.asset = asset;
}
}
Michal
Solved!!
It was my:
private Video[] video;
tried with public attribute and it works:
public Video[] video;
Related
I have below avro schema User.avsc
{
"type": "record",
"namespace": "com.myorg",
"name": "User",
"fields": [
{
"name": "id",
"type": "long"
},
{
"name": "name",
"type": "string"
}
]
}
The below java User.java class is generated from above User.avsc using avro-maven-plugin.
package com.myorg;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.nio.ByteBuffer;
import org.apache.avro.AvroRuntimeException;
import org.apache.avro.Schema;
import org.apache.avro.Schema.Parser;
import org.apache.avro.data.RecordBuilder;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.message.BinaryMessageDecoder;
import org.apache.avro.message.BinaryMessageEncoder;
import org.apache.avro.message.SchemaStore;
import org.apache.avro.specific.AvroGenerated;
import org.apache.avro.specific.SpecificData;
import org.apache.avro.specific.SpecificRecord;
import org.apache.avro.specific.SpecificRecordBase;
import org.apache.avro.specific.SpecificRecordBuilderBase;
#AvroGenerated
public class User extends SpecificRecordBase implements SpecificRecord {
private static final long serialVersionUID = 8699049231783654635L;
public static final Schema SCHEMA$ = (new Parser()).parse("{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.myorg\",\"fields\":[{\"name\":\"id\",\"type\":\"long\"},{\"name\":\"name\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}]}");
private static SpecificData MODEL$ = new SpecificData();
private static final BinaryMessageEncoder<User> ENCODER;
private static final BinaryMessageDecoder<User> DECODER;
/** #deprecated */
#Deprecated
public long id;
/** #deprecated */
#Deprecated
public String name;
private static final DatumWriter<User> WRITER$;
private static final DatumReader<User> READER$;
public static Schema getClassSchema() {
return SCHEMA$;
}
public static BinaryMessageDecoder<User> getDecoder() {
return DECODER;
}
public static BinaryMessageDecoder<User> createDecoder(SchemaStore resolver) {
return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver);
}
public ByteBuffer toByteBuffer() throws IOException {
return ENCODER.encode(this);
}
public static User fromByteBuffer(ByteBuffer b) throws IOException {
return (User)DECODER.decode(b);
}
public User() {
}
public User(Long id, String name) {
this.id = id;
this.name = name;
}
public Schema getSchema() {
return SCHEMA$;
}
public Object get(int field$) {
switch(field$) {
case 0:
return this.id;
case 1:
return this.name;
default:
throw new AvroRuntimeException("Bad index");
}
}
public void put(int field$, Object value$) {
switch(field$) {
case 0:
this.id = (Long)value$;
break;
case 1:
this.name = (String)value$;
break;
default:
throw new AvroRuntimeException("Bad index");
}
}
public Long getId() {
return this.id;
}
public void setId(Long value) {
this.id = value;
}
public String getName() {
return this.name;
}
public void setName(String value) {
this.name = value;
}
public void writeExternal(ObjectOutput out) throws IOException {
WRITER$.write(this, SpecificData.getEncoder(out));
}
public void readExternal(ObjectInput in) throws IOException {
READER$.read(this, SpecificData.getDecoder(in));
}
static {
ENCODER = new BinaryMessageEncoder(MODEL$, SCHEMA$);
DECODER = new BinaryMessageDecoder(MODEL$, SCHEMA$);
WRITER$ = MODEL$.createDatumWriter(SCHEMA$);
READER$ = MODEL$.createDatumReader(SCHEMA$);
}
}
I want to write an instance of User SpecificRecord into File using apache flink`s FileSink.
Below is the program that I wrote -
import org.apache.flink.connector.file.sink.FileSink;
import org.apache.flink.core.fs.Path;
import org.apache.flink.formats.avro.AvroWriters;
import org.apache.flink.streaming.api.CheckpointingMode;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import com.myorg.User;
import org.apache.flink.streaming.api.functions.sink.filesystem.OutputFileConfig;
import org.apache.flink.streaming.api.functions.sink.filesystem.bucketassigners.DateTimeBucketAssigner;
import org.apache.flink.streaming.api.functions.sink.filesystem.rollingpolicies.OnCheckpointRollingPolicy;
import java.util.Arrays;
public class AvroFileSinkApp {
private static final String OUTPUT_PATH = "./il/";
public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().enableCheckpointing(5000);
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
env.setParallelism(4);
OutputFileConfig config = OutputFileConfig
.builder()
.withPartPrefix("il")
.withPartSuffix(".avro")
.build();
DataStream<User> source = env.fromCollection(Arrays.asList(getUser(), getUser(), getUser(), getUser(), getUser(), getUser()));
source.sinkTo(FileSink.forBulkFormat(new Path(OUTPUT_PATH), AvroWriters.forSpecificRecord(User.class)).withBucketCheckInterval(5000).withRollingPolicy(OnCheckpointRollingPolicy.build())
.withOutputFileConfig(config).withBucketAssigner(new DateTimeBucketAssigner<>("yyyy/MM/dd/HH")).build());
env.execute("FileSinkProgram");
Thread.sleep(300000);
}
public static User getUser() {
User u = new User();
u.setId(1L);
u.setName("raj");
return u;
}
}
I wrote this program using this and this as reference. The project is on github here.
When I run the program, the in progress files are getting created but not checkpointing and committing the temp files. I've added Thread.sleep(300000); but couldn't see the inprogress files to avro files.
I've awaited the main thread for an hour as well but no luck.
Any idea what is stopping in-progress files moving to finished state?
This problem is mainly because Source is a BOUNDED Source. The execution of the entire Flink Job is over before the Checkpoint has been executed.
You can refer to the following example to generate User records instead of fromCollection
/** Data-generating source function. */
public static final class Generator
implements SourceFunction<Tuple2<Integer, Integer>>, CheckpointedFunction {
private static final long serialVersionUID = -2819385275681175792L;
private final int numKeys;
private final int idlenessMs;
private final int recordsToEmit;
private volatile int numRecordsEmitted = 0;
private volatile boolean canceled = false;
private ListState<Integer> state = null;
Generator(final int numKeys, final int idlenessMs, final int durationSeconds) {
this.numKeys = numKeys;
this.idlenessMs = idlenessMs;
this.recordsToEmit = ((durationSeconds * 1000) / idlenessMs) * numKeys;
}
#Override
public void run(final SourceContext<Tuple2<Integer, Integer>> ctx) throws Exception {
while (numRecordsEmitted < recordsToEmit) {
synchronized (ctx.getCheckpointLock()) {
for (int i = 0; i < numKeys; i++) {
ctx.collect(Tuple2.of(i, numRecordsEmitted));
numRecordsEmitted++;
}
}
Thread.sleep(idlenessMs);
}
while (!canceled) {
Thread.sleep(50);
}
}
#Override
public void cancel() {
canceled = true;
}
#Override
public void initializeState(FunctionInitializationContext context) throws Exception {
state =
context.getOperatorStateStore()
.getListState(
new ListStateDescriptor<Integer>(
"state", IntSerializer.INSTANCE));
for (Integer i : state.get()) {
numRecordsEmitted += i;
}
}
#Override
public void snapshotState(FunctionSnapshotContext context) throws Exception {
state.clear();
state.add(numRecordsEmitted);
}
}
}
I'm deserializing Json from an air quality site that has an array with latitude and longitude. The Json looks like this:
{
"geo": [
-36.05035,
146.942
],
"name": "Albury South-west Slopes, Australia",
"url": "https://aqicn.org/city/australia/nsw/albury/south-west-slopes"
}
I have written a custom deserializer which does the job but I can't deserialize "geo": [-36.05035, 146.942].
My code looks like this:
public static class City {
private Geo[] geo;
private String name;
private String url;
public Geo[] getGeo() {
return geo;
}
public void setGeo(Geo[] geo) {
this.geo = geo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
public static class Geo {
//what are the getters and setters for an array with no names just numbers?
}
It has me stumped
Thanks Phil
You can use Jackson with custom deserializer. For reference, you can look at Custom deserializer
Let geo be a List<Double> instead of a nested class:
public static class City {
private List<Double> geo;
private String name;
private String url;
public List<Double> getGeo() {
return geo;
}
public void setGeo(List<Double> geo) {
this.geo = geo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Deserialization should then be straightforward:
String json = "{\"geo\":[-36.05035,146.942],\"name\": \"Albury South-west Slopes, Australia\",\"url\": \"https://aqicn.org/city/australia/nsw/albury/south-west-slopes\"}";
City city = new Gson().fromJson(json, City.class);
I want to access JSON array . so I created 2 Object !!Have a look at my code , Url
Url-cricapi.com/api/matches/?apikey=JimJAfsmRGOnDpCrRrqO6htlilg1
My MatchesArrayClass
package com.piyushjaiswal.jsonpractis;
public class MatchesArray {
private Matches matches;
private provider provider2;
public MatchesArray(Matches matches, provider provider2) {
this.matches = matches;
this.provider2 = provider2;
}
public Matches getMatches() {
return matches;
}
public void setMatches(Matches matches) {
this.matches = matches;
}
public provider getProvider2() {
return provider2;
}
public void setProvider2(provider provider2) {
this.provider2 = provider2;
}
}
Matches Class
package com.piyushjaiswal.jsonpractis;
import com.google.gson.annotations.SerializedName;
public class Matches {
private int unique_id;
private String date;
private String dateTimeGMT;
#SerializedName("team-1")
private String team1;
#SerializedName("team-2")
private String team2;
private String type;
private String toss_winner_team;
private boolean squad;
private boolean matchStarted;
public int getUnique_id() {
return unique_id;
}
public void setUnique_id(int unique_id) {
this.unique_id = unique_id;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getDateTimeGMT() {
return dateTimeGMT;
}
public void setDateTimeGMT(String dateTimeGMT) {
this.dateTimeGMT = dateTimeGMT;
}
public String getTeam1() {
return team1;
}
public void setTeam1(String team1) {
this.team1 = team1;
}
public String getTeam2() {
return team2;
}
public void setTeam2(String team2) {
this.team2 = team2;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getToss_winner_team() {
return toss_winner_team;
}
public void setToss_winner_team(String toss_winner_team) {
this.toss_winner_team = toss_winner_team;
}
public boolean isSquad() {
return squad;
}
public void setSquad(boolean squad) {
this.squad = squad;
}
public boolean isMatchStarted() {
return matchStarted;
}
public void setMatchStarted(boolean matchStarted) {
this.matchStarted = matchStarted;
}
}
My Provider class
package com.piyushjaiswal.jsonpractis;
public class provider {
private String source;
private String url;
private String pubDate;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPubDate() {
return pubDate;
}
public void setPubDate(String pubDate) {
this.pubDate = pubDate;
}
}
MainActivity Class
package com.piyushjaiswal.jsonpractis;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private JsonPlaceHolderApi jsonPlaceHolderApi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textview);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://cricapi.com/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);
getMatchList();
}
private void getMatchList() {
Call<List<MatchesArray>> call = jsonPlaceHolderApi.getPosts("JimJAfsmRGOnDpCrRrqO6htlilg1");
call.enqueue(new Callback<List<MatchesArray>>() {
#Override
public void onResponse(Call<List<MatchesArray>> call, Response<List<MatchesArray>> response) {
if(!response.isSuccessful()){
textView.setText(response.message() + "123");
return;
}
List<MatchesArray> list = response.body();
textView.setText(list.get(0).getMatches().getDate());
}
#Override
public void onFailure(Call<List<MatchesArray>> call, Throwable t) {
textView.setText(t.getMessage() +"22");
}
});
}
}
But output on screenshot is
"Expected BEGIB_ARRAY but was BEGIN_OBJECT at line 1 column 2 patg $2"
Your JSON syntax is wrong. The response starts with {"matches":[, this means it is an object, with the parameter matches that is of type match[].
So, you need a new class along the lines of:
public class MatchesWrapper {
private List<Matches> matches;
}
And change all your Call<List<MatchesArray>> to Call<MatchesWrapper>.
The error you received tells you this. You expected an array of Matches (Expected BEGIN_ARRAY), but instead received an object (was BEGIN_OBJECT).
i have json, and i want to retrieve using gson,below my json :
{
"status_code":1,
"message":"response ok",
"api_version":"v1",
"api_endpoint_name":"category_island",
"data": [
{
"island_id":1,
"island_name":"Anambas",
"categories": [
{"id":1, "category_name":"Culinary"},
{"id":2, "category_name":"Hotel"},
{"id":3, "category_name":"Culture"}
]
}
]
}
after that i create model to retrieve it :
public class ModelCategory {
#SerializedName("status_code")
public String status_code;
#SerializedName("message")
public String message;
#SerializedName("api_version")
public String api_version;
#SerializedName("api_endpoint_name")
public String api_endpoint_name;
#SerializedName("data")
public data data;
public static class data {
#SerializedName("id")
public String id;
#SerializedName("island_name")
public String island_name;
#SerializedName("categories")
public List<categories> categories;
public static class categories {
#SerializedName("ID")
public String id;
#SerializedName("category_name")
public String category_name;
}
}
}
and this is my code to retrieve json, i'm using gson:
ModelCategory model = new Gson().fromJson(models, ModelCategory.class);
ArrayList<ModelCategory.data.categories> _model = (ArrayList<ModelCategory.data.categories>) model.data.categories;
but when i run always display error in ModelCategory , error like below :
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 6 column 11 path $.data
You need to change the model. Try this -
Category.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Category {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("category_name")
#Expose
private String categoryName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
#Override
public String toString() {
return "Category [id=" + id + ", categoryName=" + categoryName + "]";
}
}
Datum.java
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Datum {
#SerializedName("island_id")
#Expose
private Integer islandId;
#SerializedName("island_name")
#Expose
private String islandName;
#SerializedName("categories")
#Expose
private List<Category> categories = new ArrayList<Category>();
public Integer getIslandId() {
return islandId;
}
public void setIslandId(Integer islandId) {
this.islandId = islandId;
}
public String getIslandName() {
return islandName;
}
public void setIslandName(String islandName) {
this.islandName = islandName;
}
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
#Override
public String toString() {
return "Datum [islandId=" + islandId + ", islandName=" + islandName
+ ", categories=" + categories + "]";
}
}
Example.java
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("status_code")
#Expose
private Integer statusCode;
#SerializedName("message")
#Expose
private String message;
#SerializedName("api_version")
#Expose
private String apiVersion;
#SerializedName("api_endpoint_name")
#Expose
private String apiEndpointName;
#SerializedName("data")
#Expose
private List<Datum> data = new ArrayList<Datum>();
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getApiVersion() {
return apiVersion;
}
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
public String getApiEndpointName() {
return apiEndpointName;
}
public void setApiEndpointName(String apiEndpointName) {
this.apiEndpointName = apiEndpointName;
}
public List<Datum> getData() {
return data;
}
public void setData(List<Datum> data) {
this.data = data;
}
#Override
public String toString() {
return "Example [statusCode=" + statusCode + ", message=" + message
+ ", apiVersion=" + apiVersion + ", apiEndpointName="
+ apiEndpointName + ", data=" + data + "]";
}
}
Now you can test it as -
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.Example;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
/**
* #param args
*/
public static void main(String[] args) {
String s = "{\"status_code\":1,\"message\":\"response ok\",\"api_version\":\"v1\",\"api_endpoint_name\":\"category_island\",\"data\":[{\"island_id\":1,\"island_name\":\"Anambas\",\"categories\":[{\"id\":1,\"category_name\":\"Culinary\"},{\"id\":2,\"category_name\":\"Hotel\"},{\"id\":3,\"category_name\":\"Culture\"}]}]}";
Example info = gson.fromJson(s, Example.class);
System.out.println(info);
}
}
Result is -
Example [statusCode=1, message=response ok, apiVersion=v1, apiEndpointName=category_island, data=[Datum [islandId=1, islandName=Anambas, categories=[Category [id=1, categoryName=Culinary], Category [id=2, categoryName=Hotel], Category [id=3, categoryName=Culture]]]]]
I defined an endpoint with the following methods:
#ApiMethod(name = "update", path = "properties/{id}", httpMethod = HttpMethod.PUT)
public void update(#Named("id") Long id, RealEstatePropertyAPI propertyAPI,
User user) {
On the client side I tried several calls but none of them populates the propertyAPI object on the server side. The instance is created with all fields set to null except the id.
var jsonId = { 'id': '11'};
var x = {"name": "Test","address": { "street": "White House"}};
gapi.client.realestate.update(jsonId, x).execute(function(resp) {
console.log('PropertyEdited');
console.log(resp);
});
Or
var jsonId = { 'id': '11'};
var x = {"name": "Test","address": { "street": "White House"}};
gapi.client.realestate.update(jsonId, {'resource' : x}).execute(function(resp) {
console.log('PropertyEdited');
console.log(resp);
});
The Java classes:
public class RealEstatePropertyAPI {
private Long id;
private String name;
private AddressAPI address;
public RealEstatePropertyAPI() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AddressAPI getAddress() {
return address;
}
public void setAddress(AddressAPI address) {
this.address = address;
}
}
public class AddressAPI {
private Long id;
private String street;
private String city;
private String state;
private String zip;
private String country;
public AddressAPI() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
I'm not actually sure about about this, but you can try to pass all the parameters within a single object, I mean wrap the parameters with brackets { }, like this:
//var jsonId = { 'id': '11'};
var x = {"name": "Test","address": { "street": "White House"}};
gapi.client.realestate.update({'id': '11', 'resource' : x}).execute(function(resp) {
console.log('PropertyEdited');
console.log(resp);
});
Because in fact in both your requests you're sending 2 objects... And I think you have to use 'resource' for the parameters in the POST data as in your second option...