'How to return a marshalled JSON that has a nested property?
Fellow programmers from SO!
I am building a simple Spring Boot example just to add a Client using a RESTful API. I have written this Controller:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/cliente")
public class ClienteController {
@PostMapping("/add")
public Cliente add(@RequestParam(value = "nome", defaultValue = "") String nome,
@RequestParam(value = "logradouro", defaultValue = "") String logradouro,
@RequestParam(value = "CEP", defaultValue = "") String CEP,
@RequestParam(value = "bairro", defaultValue = "") String bairro,
@RequestParam(value = "complemento", defaultValue = "") String complemento,
@RequestParam(value = "municipio", defaultValue = "") String municipio,
@RequestParam(value = "UF", defaultValue = "") String UF)
{
return new Cliente(nome,logradouro,complemento,bairro,municipio,UF,CEP);
}
}
The Cliente
class has an attribute which is an object from another class Endereco
. Both classes are depicted below:
Cliente.java
import java.util.UUID;
public class Cliente {
private UUID id;
private String nome;
private Endereco endereco;
public Cliente(String nome,String logradouro,String complemento,
String bairro, String municipio, String UF, String CEP) {
this.id=UUID.randomUUID();
this.nome=nome;
this.endereco=new Endereco(logradouro,complemento,bairro,
municipio,UF,CEP);
}
}
Endereco.java
public class Endereco {
private String logradouro;
private String complemento;
private String bairro;
private String minicipio;
private String UF;
private String CEP;
public Endereco(String logradouro, String complemento, String bairro,
String municipio, String UF, String CEP) {
this.logradouro=logradouro;
this.complemento=complemento;
this.bairro=bairro;
this.minicipio=municipio;
this.UF=UF;
this.CEP=CEP;
}
}
Nevertheless, when I sent a POST
request to the API (it is hosted on localhost:8080
for testing purposes), the JSON
does not return the endereco
property. I supposed it should be a nested JSON
object.
I am using Python requests to send this POST
request:
import requests
url = "http://localhost:8080/api/cliente/add"
payload = {'nome': 'Fabio',
'logradouro': 'Rua dos Bobos',
'CEP': '66666-666',
'bairro': '',
'complemento': '',
'municipio': 'Belem',
'UF': 'PA'}
response = requests.request("POST", url, headers={},
data = payload, files = [])
print(response.content)
The result shown does not include the endereco
property:
b'{"id":"84956a2b-2a29-435b-a19a-ea6093ab20a1","nome":"Fabio"}'
Is there anything silly that I'm missing?
Thanks for any clue.
Solution 1:[1]
first of all, the method in your controller is not ok. the add method should accept a Cliente object with @RequestBody annotation.
and for your problem, you can use the @JsonUnwrapped which will unrapp the object either in serialization or deserialization.
in the end you will be with those classes :
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/cliente")
public class ClienteController {
@PostMapping("/add")
public Cliente add(@RequestBody Cliente cliente)
{
// do whatever you want with the sent values
}
}
import java.util.UUID;
public class Cliente {
private UUID id;
private String nome;
@JsonUnwrapped
private Endereco endereco;
public Cliente(String nome,String logradouro,String complemento,
String bairro, String municipio, String UF, String CEP) {
this.id=UUID.randomUUID();
this.nome=nome;
this.endereco=new Endereco(logradouro,complemento,bairro,
municipio,UF,CEP);
}
}
Solution 2:[2]
In Spring MVC, which I guess is your case, the annotation @RequestParam
maps query parameters, form data, and parts in multipart requests.
In your case, you are sending JSON in the request body, which is not supported by @RequestParam
.
This is the mapping of Spring annotation that handles the HTTP request header Content-Type:
@RequestParam
--> application/x-www-form-urlencoded@RequestBody
--> application/json@RequestPart
--> multipart/form-data
Having said that either the solution posted already by @Teyeb Med Malek, using DTOs that match your request body and are then converted to your model classes, or changing the body that you use in your request to be the following would work:
{
'nome': 'Fabio',
'endereco': {
'logradouro': 'Rua dos Bobos',
'CEP': '66666-666',
'bairro': '',
'complemento': '',
'municipio': 'Belem',
'UF': 'PA'
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Teyeb Med Malek |
Solution 2 |