I have API which returns JSON in this format:
{
"response": {
"GeoObjectCollection": {
"featureMember": [
{
"GeoObject": {
"Point": {
"pos": "37.611347 55.760241"
}
}
},
{
"GeoObject": {
"Point": {
"pos": "37.593965 55.771575"
}
}
}
]
}
}
}
I want to convert this JSON object to the DTO model in Spring Boot App. How can I do that?
I need to create classes like response, GeoObjectCollection, GeoObject etc, or it's all made easier?
My app structure contains services, model, controllers.
Related
In my play framework application, I have registered APIs in route file as:
POST /api/rmt-create-request controllers.Api.CreateRMTRequestForm
On action of controller, I am using following code to access formData submitted with form submit as :
public Result CreateRMTRequestForm()
{
Map<String, String[]> params = request().body().asMultipartFormData().asFormUrlEncoded();
Its working fine as API when I submit the form with forntend application.
I am trying to create APIs documentation with swagger.ui in which within swagger.json file I have written following JSON data.
"paths": {"/api/rmt-create-request": {
"post": {
"tags": [
"RMT APIs"
],
"description" : "Return newly created request data",
"operationId": "create-new-rmt-request",
"consumes": ["application/x-www-form-urlencoded"],
"parameters": [
{
"name": "rootNodeName",
"in": "formData",
"description": "Root node class name for item",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/rmt-request-data"
}
}
}
},
"default": {
"$ref": "#/components/responses/default"
}
}
}
},
While inspecting RequestHeader data, its not showing content-Type property with value 'multipart/form-data' as well as formData are not attached, which makes controller to throw null exception.
Can anyone help whats missing in swagger.json file ?
You are mixing OpenAPI 2.0 and 3.0 syntax.
In OpenAPI 3.0, request body (including form data) is defined using the requestBody keyword instead of in: formData parameters.
Also, OAS3 does not use consumes. The media types consumed by the operation are specified inside the requestBody.
"paths": {
"/api/rmt-create-request": {
"post": {
"tags": [
"RMT APIs"
],
"description": "Return newly created request data",
"operationId": "create-new-rmt-request",
"requestBody": {
"content": {
"multipart/form-data": { // or "application/x-www-form-urlencoded" - depending on what you need
"schema": {
"type": "object",
"properties": {
"rootNodeName": {
"type": "string",
"description": "Root node class name for item"
}
}
}
}
}
}
}
}
}
More information: Describing Request Body
I have dynamic json format from rest API like this :
{
"data": {
"response_code": "success",
"value": {
"Table": [
{
"id": 5,
"username": "blahblah",
"password": "blahblah",
"role": 2,
"email": "blah#tes.com",
"tanggal_buat": "2019-01-01T00:00:00"
}
]
}
},
"meta": {
"http_status": 200
}
}
Object "value" has an object array name "Table". Table can contain value from my database dynamically depend on my query. So, Sometimes the json format will change for example :
{
"data": {
"response_code": "success",
"value": {
"Table": [
{
"id_product": 44,
"product": "blahblah",
"lot": "blahblah",
"qty": 2,
}
]
}
},
"meta": {
"http_status": 200
}
}
How to accept the json value and assign to gson directly with different subclass of "Table"
I try it in retrofit and using kotlin
override fun onResponse(call: Call<MainResp>, response: Response<MainResp>) {
mainResponse : MainResp = response.body()
}
Assuming that you have the following class among others (using sth like http://www.jsonschema2pojo.org/):
class Value {
List<Table> tables;
}
The "Table" class here cannot be completely random!
You'll need to define the possible types of "Table" e.g. Table1, Table2... TableN.
Now you can update Value class with a generic type T instead of Table and write your custom type adapter:
class Value {
List<T> tables;
}
One of the tutorials on how to write your own type adapter is here.
In the Spring Data JPA documentation it explains how to generate links using PagedResourcesAssembler. The documentation makes reference to a toResources() method but as far as I can see that method does not exist. I have successfully generated links for the collection of resources but I can't figure out how to generate links for the sub resources.
Here is my controller:
public HttpEntity<PagedResources<Party>> search(#RequestBody PartySearchRequest request,
Pageable pageable, PagedResourcesAssembler<Party> assembler ) {
Map<String,String> searchFilters = RequestValidator.validateContractSearchFilters(request);
Page<Party> parties = repository.findByFirstNameOrLastName(searchFilters.get("firstName"), searchFilters.get("lastName"), pageable);
return new ResponseEntity(assembler.toResource(parties), HttpStatus.OK);
}
This produces the following JSON:
{
"_embedded": {
"partyList": [
{
"firstNm": "John",
"lastNm": "Doe",
},
{
"firstNm": "Bob",
"lastNm": "Smith",
}
],
}
]
},
"_links": {
"first": {
"href": "http://localhost:8080/v1/party/search?page=0&size=2"
},
"self": {
"href": "http://localhost:8080/v1/party/search?page=0&size=2"
},
"next": {
"href": "http://localhost:8080/v1/party/search?page=1&size=2"
},
"last": {
"href": "http://localhost:8080/v1/party/search?page=7&size=2"
}
},
"page": {
"size": 2,
"totalElements": 16,
"totalPages": 8,
"number": 0
}
}
As you can see I get links for the entire parties search but not for the individual party objects. (I think my question is similar to this question: How to add HATEOAS links in a sub resource) but I wasn't quite sure so I posted my own.
Any help would be greatly appreciated! Thank you!
You need a reference to your class that extends ResourceAssemblerSupport.
This should work, changing myResourceAssembler to whatever your class is:
In your controller:
private final MyResourceAssembler myResourceAssembler;
public MyController(MyResourceAssembler myResourceAssembler) {
this.myResourceAssembler = myResourceAssembler;
}
public HttpEntity<PagedResources<Party>> search(#RequestBody PartySearchRequest request,
Pageable pageable, PagedResourcesAssembler<Party> assembler ) {
Map<String,String> searchFilters = RequestValidator.validateContractSearchFilters(request);
Page<Party> parties = repository.findByFirstNameOrLastName(searchFilters.get("firstName"), searchFilters.get("lastName"), pageable);
Link selfLink = linkTo(methodOn(this.getClass().view(pageable, null)).withSelfRel();
return new ResponseEntity(assembler.toResource(parties, myResourceAssembler, selfLink), HttpStatus.OK);
}
And, if you don't want the selfLink:
return new ResponseEntity(assembler.toResource(parties, myResourceAssembler), HttpStatus.OK);
References
ResourceAssemblerSupport
PagedResourcesAssembler
I have a REST controller that returns a list of products like so:
Current output
[
{
"id":1,
"name":"Money market"
},
{
"id":2,
"name":"Certificate of Deposit"
},
{
"id":3,
"name":"Personal Savings"
}
]
In order to get things working with our JS grid library, I need the modify the response to look like:
Desired output
{ "data" :
[
{
"id":1,
"name":"Money market"
},
{
"id":2,
"name":"Certificate of Deposit"
},
{
"id":3,
"name":"Personal Savings"
}
]
}
Controller
#RequestMapping(value = "/api/products", method = RequestMethod.GET)
public ResponseEntity<?> getAllProducts() {
List<Product> result = productService.findAll();
return ResponseEntity.ok(result);
}
Is there an easy way to modify the JSON response using native Spring libraries?
You can put result object into a Map with key "data" and value as result.
map.put("data", result);
Then return the map object from the rest method.
return ResponseEntity.ok(map);
Using org.json library:
JSONObject json = new JSONObject();
json.put("data", result);
The put methods add or replace values in an object.
I am having a problem when I want to be able to map a single Object but also an Array of those object with com.fasterxml.jackson.annotation
Please see below example keep in mind that this is a response payload and it is not under my control:
{
"GetSomeUserInfoDetails": {
"ItemListOfUser": {
"itemList": {
"item": [
{
"name": "Stack overflow",
"adress": "ola"
},
{
"name": "Google",
"adress": "man"
}
]
}
}
}
}
The jsontopojo is generating the classes that I can use for this response. The problem occurs when there is only one item int itemList user i get the following response:
{
"GetSomeUserInfoDetails": {
"WorkItem": {
"itemList": {
"item": {
"name": "Stack overflow",
"adress": "ola"
}
}
}
}
}
When you generate the classes now you will see a different class structure. Is there a way how we can solve this with Jackson?