J'utilise Spring Boot (dernière version, 1.3.6 ) et je veux créer un point de terminaison REST qui accepte un tas d'arguments et un objet JSON. Quelque chose comme:
curl -X POST http://localhost:8080/endpoint \
-d arg1=hello \
-d arg2=world \
-d json='{"name":"john", "lastNane":"doe"}'
Dans le contrôleur Spring, je fais actuellement:
public SomeResponseObject endpoint(
@RequestParam(value="arg1", required=true) String arg1,
@RequestParam(value="arg2", required=true) String arg2,
@RequestParam(value="json", required=true) Person person) {
...
}
L'argument json
n'est pas sérialisé dans un objet Person. J'ai un
400 error: the parameter json is not present.
Évidemment, je peux faire l'argument json
en tant que chaîne et analyser la charge utile à l'intérieur de la méthode du contrôleur, mais ce genre de méthode défie le point d'utiliser Spring MVC.
Tout fonctionne si j'utilise @RequestBody
, mais je perds alors la possibilité de POST arguments séparés en dehors du corps JSON.
Existe-t-il un moyen dans Spring MVC de "mélanger" normal POST et objets JSON?
Oui, il est possible d'envoyer à la fois les paramètres et le corps avec une méthode de publication: Exemple côté serveur:
@RequestMapping(value ="test", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Person updatePerson(@RequestParam("arg1") String arg1,
@RequestParam("arg2") String arg2,
@RequestBody Person input) throws IOException {
System.out.println(arg1);
System.out.println(arg2);
input.setName("NewName");
return input;
}
et sur votre client:
curl -H "Content-Type:application/json; charset=utf-8"
-X POST
'http://localhost:8080/smartface/api/email/test?arg1=ffdfa&arg2=test2'
-d '{"name":"me","lastName":"me last"}'
Prendre plaisir
Vous pouvez le faire en enregistrant un Converter
de String
à votre type de paramètre à l'aide d'un ObjectMapper
câblé automatiquement:
import org.springframework.core.convert.converter.Converter;
@Component
public class PersonConverter implements Converter<String, Person> {
private final ObjectMapper objectMapper;
public PersonConverter (ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public Date convert(String source) {
try {
return objectMapper.readValue(source, Person.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
vous pouvez utiliser RequestEntity.
public Person getPerson(RequestEntity<Person> requestEntity) {
return requestEntity.getBody();
}