J'utilise la dernière version de Spring Boot pour lire un exemple de code JSON via un service Web reposant ...
Voici mon pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.Apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0
http://maven.Apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>myservice</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
<properties>
<Java.version>1.7</Java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
<dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
Voici mon code de service Web:
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/myservice")
public class BaseService {
@RequestMapping(value="/process", method = RequestMethod.POST)
public void process(@RequestBody String payload) throws Exception {
System.out.println(payload);
}
}
Quand je l'appelle en utilisant la commande suivante:
curl -H "Accept: application/json" -H "Content-type: application/json"
-X POST -d '{"name":"value"}' http://localhost:8080/myservice/process
Je reçois ce message d'erreur:
{"timestamp":1427515733546,"status":400,
"error":"Bad Request",
"exception":
"org.springframework.http.converter.HttpMessageNotReadableException","
message":
"Could not read JSON: Can not deserialize instance of Java.lang.String
out of START_OBJECT token\n at
[Source: Java.io.PushbackInputStream@8252f; line: 1, column: 1];
nested exception is com.fasterxml.jackson.databind.JsonMappingException:
Can not deserialize instance of Java.lang.String out of START_OBJECT token\n
at [Source: Java.io.PushbackInputStream@8252f; line: 1, column: 1]",
"path":"/myservice/process"
La seule chose que j'essaie de faire est de transmettre un JSON valide (sous forme de chaîne via curl) et de voir si le contenu de chaîne entre la méthode de traitement sous la forme {"nom": "valeur"}
Qu'est-ce que je fais peut-être mal?
Merci de prendre du temps pour lire ceci...
Je pense que le moyen le plus simple et pratique de consommer du JSON consiste à utiliser une classe Java semblable à votre JSON: https://stackoverflow.com/a/6019761
Mais si vous ne pouvez pas utiliser une classe Java, vous pouvez utiliser l'une de ces deux solutions.
Solution 1: vous pouvez le faire en recevant un Map<String, Object>
de votre contrôleur:
@RequestMapping(
value = "/process",
method = RequestMethod.POST)
public void process(@RequestBody Map<String, Object> payload)
throws Exception {
System.out.println(payload);
}
En utilisant votre demande:
curl -H "Accept: application/json" -H "Content-type: application/json" \
-X POST -d '{"name":"value"}' http://localhost:8080/myservice/process
Solution 2: sinon vous pouvez obtenir la charge utile POST sous la forme d'une String
:
@RequestMapping(
value = "/process",
method = RequestMethod.POST,
consumes = "text/plain")
public void process(@RequestBody String payload) throws Exception {
System.out.println(payload);
}
Ensuite, analysez la chaîne comme vous le souhaitez. Notez que vous devez spécifier consumes = "text/plain"
sur votre contrôleur . Dans ce cas, vous devez modifier votre demande avec Content-type: text/plain
:
curl -H "Accept: application/json" -H "Content-type: text/plain" -X POST \
-d '{"name":"value"}' http://localhost:8080/myservice/process
Pour ajouter à la solution d'Andrea, si vous transmettez un tableau de JSON par exemple
[
{"name":"value"},
{"name":"value2"}
]
Ensuite, vous devrez configurer le contrôleur de démarrage Spring comme suit:
@RequestMapping(
value = "/process",
method = RequestMethod.POST)
public void process(@RequestBody Map<String, Object>[] payload)
throws Exception {
System.out.println(payload);
}
Le problème apparaît lors de l'analyse du JSON à partir du corps de la requête, ce qui est typique pour un JSON non valide. Si vous utilisez curl sur Windows, essayez d’échapper à json comme -d "{"name":"value"}"
ou même -d "{"""name""":"value"""}"
.
D'autre part, vous pouvez omettre l'en-tête de type de contenu, auquel cas le message "whetewer" envoyé sera converti en votre argument String.
Ce qui suit pourrait vous aider à travailler avec un éventail de cartes
@RequestMapping(value = "/process", method = RequestMethod.POST, headers = "Accept=application/json")
public void setLead(@RequestBody Collection<? extends Map<String, Object>> payload) throws Exception {
List<Map<String,Object>> maps = new ArrayList<Map<String,Object>>();
maps.addAll(payload);
}