web-dev-qa-db-fra.com

Essayer d'essayer Spring Boot REST Lire la chaîne JSON de POST

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...

46
PacificNW_Lover

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
79
Andrea

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);

}
2
S. Pan

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.

2
Master Slave

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);

}
0
Rusli Usman