Using the Spring WebClient I am calling a Rest API that gives me a response as a JSON, following is a structure of the response -
{
"vehicles":[
{ "name":"veh1", "type":"car", "age": 5 },
{ "name":"veh2", "type":"speedboat", "age":12},
.....
]
"metadata": {
"token":"abcd",
"days":120
}
}
I am a newbie to reactive programming, I have written the following code, which works fine ..
Mono<VehicleResponse> = webclient.get()
.uri("/legacy/vehicles")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.empty())
.onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.empty())
.bodyToMono(VehicleResponse.class);
But, actually what I am interested in is, only the vehicles array (don't want the metadata information.) Is it possible to obtain / read only the vehicles (array) as a Flux of Vehicle ?
I am using Node.js for AWS Lambda + API Gateway APIs.
I have multiple Lambda functions and each giving different response formats as it integrated multiple third party SDKs like Stripe/DynamoDB and all.
Is there any way to get common response for all the functions like below?
{
"success" : true,
"data" : { RESPONSEFROMLAMBDA },
"messages" : null,
"code" : 200,
"description" : "OK"
}
The third-party services your Lambda functions are using shouldn't have any bearing on the response format. You just need to update all the API Gateway endpoints to use a mapping template with this format.
Situation : I am modifying a friend's web application project . It uses spring MVC and java ,JQgrid and GSON .
Project has a Student.java model class ,StudentDaoImpl.java DAO class and a buisness class containing listStudentData() service that returns a list of Student objects , and project is using jqGrid jquery plugin to display student data in view.jsp.
View.jsp once loaded makes the following ajax request to retrieve student data :
function initiate() {
$.ajax({
type : 'GET',
dataType : "json",
url : 'listStudentData',
success : function (data)
{
$("#tabel").jqGrid({
data: data,
colNames: ["name" ,"id"],
datatype: "local",
colModel:[{
name : 'studentName',
index : 'studentName',
width : '290px'
}, {
name : 'studentId',
index : 'studentId',
width : '220px'
}]
rowNum:25,
viewrecords: true,
pager: "#div",
scrollOffset: 0,
emptyrecords:"No records",
height: 'auto',
caption: "student data",
grouping: false,
groupingView : {},
});
}
});
}
Controller handling this response :
#RequestMapping(value = "/listStudentData", method = RequestMethod.GET)
public #ResponseBody
String listStudentData() {
final List<Student> list = studentBusiness.listStudentData();
return gson.toJson(list);
}
My json response from this controller is as follows :
[{"studentName":"x" , "StudentId" : "x#gmail.com" },{"studentName":"Y" , "StudentId" : "Y#gmail.com"}]
And code is working fine and giving correct output!
Problem : Now i was going through documentation of jqgrid (http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data)
there it is clearly stated that json format expected by jqgrid is as follows :
{
"total": "xxx",
"page": "yyy",
"records": "zzz",
"rows" : [
{"id" :"1", "cell" :["cell11", "cell12", "cell13"]},
{"id" :"2", "cell":["cell21", "cell22", "cell23"]}
]
}
and json format generated by gson library that is sent as response is different than this format then how it is working correctly ? I searched the project for a custom JsonReader but couldn'tfind any . Am i missing something if not then how is this code working ?
See the gson reference for gson.toJson(obj)
public String toJson(Object src)
This method serializes the specified object into its equivalent Json representation. This method should be used when the specified object is not a generic type. This method uses Object.getClass() to get the type for the specified object, but the getClass() loses the generic type information because of the Type Erasure feature of Java. See the official document Gson
Parameters: src - the object for which Json representation is to be
created setting for Gson Returns: Json representation of src.
Check this Demo which uses the same data as your json to create jQgrid.
Your json-response is a json array. Therefore, I guess that the section 'Array Data' of the manual applies. You tell it to accept an array by using datatype: "local" (which is, as stated by the manual, the same as datatype: "clientSide")
With colName you already provide the correct information how to interpret the array.
You could try this by changing the value of datatype and see, whether the array response is still used correctly.
Jackson allows Polymorphic Deserialization: http://wiki.fasterxml.com/JacksonPolymorphicDeserialization
Specifically, I am trying to use Global default typing with:
objectMapper.enableDefaultTyping();
Documentation specifies that request
..is included, using default inclusion mechanism (additional wrapper
array in JSON).
but I do not understand what exactly that means. I am not sure how to actually form the JSON request that specifies the subtype being sent. I tried the following three requests with no success so far:
{
"com.package.MySubType" : {
"name": "someName"
}
}
[
"com.package.MySubType",
{
"name": "someName"
}
]
{
"#type" : "MySubType",
"name": "someName"
}
I am checking for instance type using instanceof and it always fails.
Found my answer here: https://groups.google.com/forum/#!topic/jackson-user/nhZAn4TSHG4
[ "com.foobar.MyType", { "property1" : 2, "property2" : "foo" } }
Altho I decided to go the property route on the end because it seems more logical.
Is there a standardized way to store classes in JSON, and then converting them back into classes again from a string? For example, I might have an array of objects of type Questions. I'd like to serialize this to JSON and send it to (for example) a JavaScript page, which would convert the JSON string back into objects. But it should then be able to convert the Questions into objects of type Question, using the constructor I already have:
function Question(id, title, description){
}
Is there a standardized way to do this? I have a few ideas on how to do it, but reinventing the wheel and so on.
Edit:
To clarify what I mean by classes: Several languages can use classes (JAVA, PHP, C#) and they will often communicate with JavaScript through JSON. On the server side, data is stored in instances of classes, but when you serialize them, this is lost. Once deserialized, you end up with an object structure that do not indicate what type of objects you have. JavaScript supports prototypal OOP, and you can create objects from constructors which will become typeof that constructor, for example Question above. The idea I had would be to have classes implement a JSONType interface, with two functions:
public interface JSONType{
public String jsonEncode();//Returns serialized JSON string
public static JSONType jsonDecode(String json);
}
For example, the Question class would implement JSONType, so when I serialize my array, it would call jsonEncode for each element in that array (it detects that it implements JSONType). The result would be something like this:
[{typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"},
{typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"},
{typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"}]
The javascript code would then see the typeof attribute, and would look for a Question function, and would then call a static function on the Question object, similar to the interface above (yes, I realize there is a XSS security hole here). The jsonDecode object would return an object of type Question, and would recursively decode the JSON values (eg, there could be a comment value which is an array of Comments).
You'll have to create your own serializer which detects Question (and other classes) and serializes them as constructor calls instead of JSON object notation. Note that you'll need a way to map an object to a constructor call. (Which properties come from which parameters?)
Everyone else: By classes he means functions used as constructors; I assume that he's trying to preserve the prototype.
Have you looked at JSON.NET? It can serialize/de-serialize .NET objects to JS and vice-versa. It is a mature project and I highly recommend it.
Also, if you could change the definition of your 'Question' function to take one object with properties instead of taking separate arguments, you can do something like this:
Working Demo
function Question(args)
{
this.id = args.id;
this.text = args.text;
}
Question.prototype.alertText = function() { alert(this.text); };
$(document).ready(
function()
{
var objectList =
{
'list' : [
{ 'id' : 1, 'text' : 'text one' }
,{ 'id' : 2, 'text' : 'text two' }
,{ 'id' : 3, 'text' : 'text three'}
],
'type' : 'Question'
};
var functionName = objectList['type'];
var constructor = window[functionName];
if(typeof constructor !== 'function')
{
alert('Could not find a function named ' + functionName);
return;
}
var list = objectList['list'];
$.each(list,
function()
{
var question = new constructor(this);
question.alertText();
}
);
}
);
On a side note, please prefix your .NET Interfaces with 'I' e.g. it should be IJsonType and not JsonType.
typeof is a keyword so specify the property name in quotes if you want to use it.
It's highly dangerous, but eval can process any text and execute it.
http://www.w3schools.com/jsref/jsref_eval.asp
But DON'T use it. May do something like pass over the params you want to pass into the constructor as a JSON object and call the constructor with it...
function Question({"id" : "val", "title", "mytitle", "description" : "my desc"}){
...
}
This might be useful.
http://nanodeath.github.com/HydrateJS/
https://github.com/nanodeath/HydrateJS
Use hydrate.stringify to serialize the object and hydrate.parse to deserialize.
Assuming you are using a Javascript client and a REST api backend and you are looking to define the rules for encoding a Method as JSON, you should probably consider using graphQL.
You could also look at my draft Specificaton for JSON-ND - that may give you simple representation: eg
Where the server publishes this specification:
{
"Question:POST(id:integer, title:string, description:string):string" :
"https://my.question.com:999/question"
}
Or perhaps a little less "C" style
{ "QuestionParam:Interface"[
"id:integer",
"title:string",
"description:string"
],
"Question:POST(QuestionParam[0,]):string" :
"https://my.question.com:999/question"
}
This means you can POST the following to https://my.question.com:999/question
{
"questions:Question": [
{id:0, title:"Some Question 1", description:"blah blah blah"},
{id:1, title:"Some Question 2", description:"blah blah blah"},
{id:2, title:"Some Question 3", description:"blah blah blah"}
]
}
And the server would respond with something like:
[
"answer 1",
"answer 2",
"answer 3",
]
You might even define a better return type say "Answer"
{
"Answer:Interface"[
"id:integer",
"answer:string"
],
"Question:POST(id:integer, title:string, description:string):Answer" :
"https://my.question.com:999/question:URI"
}
And the server would return:
{ "answers:Answer" :[
{"id":0, "answer":"Answer 1"},
{"id":1, "answer":"Answer 2"},
{"id":2, "answer":"Answer 3"}
]
}
on the client side, implement a JSON-ND interpreter similar to the example:
, include a Fetch call and you could use something like:
var questions = {
"questions:Question": [
{id:0, title:"Some Question 1", description:"blah blah blah"},
{id:1, title:"Some Question 2", description:"blah blah blah"},
{id:2, title:"Some Question 3", description:"blah blah blah"}
]
}
var answers = JSON_ND_Stringify(questions) ; //of course use an async call here