I have an angular project with a java backend.
the following is the scenario.
I create a DTO object in the Backend, and submit it to the frontend.
...
QuestionResponseDTO dto = new QuestionResponseDTO();
dto.setStart(ZonedDateTime.now());
dto.setEnd(ZonedDateTime.now());
dto.setDuration("X seconds");
dto.setResponse(new ActivityListResponseDTO(Arrays.asList("Cooking", "Eating")));
return dto;
}
in which the ActivityListResponseDTO just contains a List<String> activities.
Also note that ActivityListResponseDTO extends QuestionResponseBodyDTO.
In the frontend I send the request to the backend, and I receive the object back.
this is how the object looks like.
{"id":2,"responses":[{"id":0,"dto":{"start":"2021-06-16T09:08:28.142Z","end":"2021-06-16T09:08:28.142Z","duration":"X seconds",
"response":{
"activities":["Cooking","Eating"],
"typeName":"ActivityListResponseDTO",
"className":null},
"typeName":"QuestionResponseDTO",
"className":null}}]}
which means that the backend works fine.
The java classes I mentioned earlier have their corresponding classes in the Frontend with the exact same name. Idk what exactly happens to parse the response.
When I receive the object I check:
//angular
if (dto instanceof QuestionResponseDTO) {
console.log("this ran");
const responseBody = ((<QuestionResponseDTO>dto).response);
if(responseBody instanceof ActivityListResponseDTO) {
console.log("this ran 2");
// because backend only returns a string
const arr = (<ActivityListResponseDTO>responseBody)
.activities.map(s => ({stringContent: s}));
...
The responseBody per default has the Type QuestionResponseBodyDTO in the frontend as well. the ActivityListResponseDTO extends this in the frontend too, so it should work.
but for some reason the program doesn't go in the inner if statement, and "this ran 2" is never logged.
Is there something I am doing wrong?
The response received from the HTTP API will be a simple JSON Object.
For it to work correctly on frontend, you will have to map that object to its corresponding type on frontend.
You can use json-object-mapper library to achieve this.
Create a Typescript class named QuestionResponseDTO with all the nested object classes. I usually do this using json2ts which provides me interfaces and then I convert those interfaces to typescript classes.
Use json-object-mapper or use your own class constructors to initialize the properties
In your HTTP service, when you get the data, pipe that data to deserialize it to typescript object. http.get<QuestionResponseDTO>(url).pipe(map(data => ObjectMapper.deserialize(QuestionResponseDTO, data)));
Once this is done, you should be able to correctly use instanceof on any nested objects
Related
In my java play framework project (2.3 version) I need to call an exposed endpoint from outside also from inside my project. To be more specific, in another controller.
So in my routes I have this mapping:
POST /evaluation/budgetamout #bank.controller.EvaluationController.evaluateBudgetAmount()
The controller EvaluationController contains a methods named as evaluateBudgetAmount:
public Result evaluateBudgetAmount() {
ApiResponse response = new ApiResponse();
JsonNode jsonNode = request().body().asJson();
String result = // performe evaluations and save it into database passing jsonNode
response.addData(result);
return ok(response);
So in another controller with a specific method named as checkFinalResult I need to perform the call evaluateBudgetAmount giving a new input in the request(a new json in the post request), but I have no idea to figure out.
Surery I do not want to use the Promise to performed a new call inside my project that need to pass through from outside, to be clearer this approach is not admissible:
F.Promise<WSResponse> rProm = WS.url(pathUrl).post(info);
There is another way?
i am trying to make a client for services exposed through REST.I have multiple number of classes extending a single class.
Now when i send the request and get a response,every time i need to type cast the response for specific class.i am trying to automate this process,can this be achieved at run time?
I am thinking of using generics and reflection but unable to move forward.what i exactly want to achieve is by just mentioning a unique string or say request,i must be able to get exact same response without type casting it with that particular response class.
By using generics i succeeded in reducing some code for typecasting,still i am not satisfied as i want to completely achieve it at run time.
RequestClass request=(RequestClass)getRequest(some attributes);
output=(Responseclass)response.getResult();
Here every time i need to mention the request and response classes,i don't want to do this.
can i do something where i can map the request and response classes to a key or a string and based on it the code will fetch the request and response class and perform the operation according to it(not sure about it).
please guide me in doing this,or any other way i can do the above mentioned thing.
Thanks in advance.
Consider using one of the many Java REST libraries. Our client uses the Jersey API to handle requests and responses to our Python based RESTful server.
Jersey uses a class called ClientResponse that stores the generic response data. you can use the getEntity method to return the response as a specific type.
Here is an excerpt of my code, which only deals with strings, but you can see how it could be extended:
ClientResponse response; //a Jersey class
String responseText;
WebResource odbc = resourceCollection.path("ODBC"); //another Jersey class
try {
//we send a POST and get a response stored as generic
response = odbc.type(media)
.accept(MediaType.APPLICATION_XML,MediaType.TEXT_PLAIN)
.post(ClientResponse.class, formdata);
//we pull out the response entity as a string
responseText = response.getEntity(String.class);
} catch (UniformInterfaceException e) {
write("<UniformInterfaceException>\n");
write(" Response type was not expected\n");
write("</UniformInterfaceException>\n");
return;
} catch (ClientHandlerException e) {
write("<Error>\n");
write(" Unable to connect or connection refused\n");
write("</Error>\n");
return;
public class DynamicCasting{
DynamicCasting e1=new DynamicCasting();
private Object obj=new Object();
DynamicCasting.doSomething(obj);
public static DynamicClass doSomething(DynamicClass dynClassObject){
return dynClassObject;
}
}
The obj will be type casted to DynamicClass in this example.
I have a service A in the java server side of my application that returns a JSON object, and I need to consume that object in javascript side to call another service B.
The platform is a bit complex, having two applications based on Stripes and Spring packed under the same war and sharing a lot of code.
The solution I have so far is creating a JSP tag that access the JSON object and puts it in a variable:
#Override
public int doStartTag() throws JspException {
pageContext.setAttribute(var, SERVICE_A_JSONOBJECT, scope);
return SKIP_BODY;
}
This works well, but the jstl variable is converted to String, so in the javascript call I have to use JSON.parse.
Is there any way to improve this by passing the JSON object to javascript without being converted and then parsed?
NOTE: Since they are two apps, I would like to avoid using the session, because then I would need to duplicate the code
Currently our application uses GWT-RPC for most client-server communication. Where this breaks down is when we need to auto generate images. We generate images based on dozens of parameters so what we do is build large complex urls and via a get request retrieve the dynamically built image.
If we could find a way to serialize Java objects in gwt client code and deserialize it on the server side we could make our urls much easier to work with. Instead of
http://host/page?param1=a¶m2=b¶m3=c....
we could have
http://host/page?object=?JSON/XML/Something Magicical
and on the server just have
new MagicDeserializer.(request.getParameter("object"),AwesomeClass.class);
I do not care what the intermediate format is json/xml/whatever I just really want to be able stop keeping track of manually marshalling/unmarshalling parameters in my gwt client code as well as servlets.
Use AutoBean Framework. What you need is simple and is all here http://code.google.com/p/google-web-toolkit/wiki/AutoBean
I've seen the most success and least amount of code using this library:
https://code.google.com/p/gwtprojsonserializer/
Along with the standard toString() you should have for all Object classes, I also have what's called a toJsonString() inside of each class I want "JSONable". Note, each class must extend JsonSerializable, which comes with the library:
public String toJsonString()
{
Serializer serializer = (Serializer) GWT.create(Serializer.class);
return serializer.serializeToJson(this).toString();
}
To turn the JSON string back into an object, I put a static method inside of the same class, that recreates the class itself:
public static ClassName recreateClassViaJson(String json)
{
Serializer serializer = (Serializer) GWT.create(Serializer.class);
return (ClassName) serializer.deSerialize(json, "full.package.name.ClassName");
}
Very simple!
I know that GWT has a good RPC support. But for various purposes I need to build this on my own:
1.) How can I convert a Bean Object (on the Client Side) like;
class MyPerson {
String name;
String getName();
void setName(String name);
//..
}
with GWT into a JSON String? (Ideally only using libraries that come officially from GWT/Google).
2.) Secondly, how can I send this generated JSON String from the Client side to any Server also using any GWT Client Logik. (Ideally only using libraries that come officially from GWT/Google).
I have searched a lot, but the examples never show how to send data but only to receive JSON data.
Thank you very much!!!
Jens
There's a nifty class called AutoBeanFactory that GWT will create for you, no third-party libs required. See http://google-web-toolkit.googlecode.com/svn-history/r9219/javadoc/2.1/com/google/gwt/editor/client/AutoBeanFactory.html
Once you have your AutoBeanFactory, you can use it like this:
producing JSON from an object of type SimpleInterface
AutoBean<SimpleInterface> bean = beanFactory.create(SimpleInterface.class, simpleInterfaceInstance);
String requestData = AutoBeanCodex.encode(bean).getPayload();
useRequestBuilderToSendRequestWhereverYouWant(requestData);
parsing JSON from an object of type SimpleInterface
SimpleInterface simpleInterfaceInstance = AutoBeanCodex.decode(beanFactory, SimpleInterface.class, responseText).as();
You can use RequestBuilder to send these requests without GWT-RPC or the RF stuff.
I recommend you use RestyGWT it makes JSON rest services work just like GWT RPC services.
Take a look at GWT's AutoBean framework, which can be used to create and receive JSON payloads. The RequestBuilder type can be used to send HTTP requests to the server.
You have also another solution which is 3rd party solution, maybe a second place solution but it can be also the first place.
The 3rd party called GSON and it's a project open source on google code.
You can find it here.
I used it and it's very good and very simple.