Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to use Spring Boot REST to Read JSON String from POST

Am using the latest version of Spring Boot to read in a sample JSON via Restful Web Service...

Here's my 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> 

Here's my web service code:

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

When I invoke it using the following command:

curl -H "Accept: application/json" -H "Content-type: application/json"  -X POST -d '{"name":"value"}' http://localhost:8080/myservice/process 

I get this error message:

{"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" 

The only thing I am trying to do is pass in some valid JSON (as a string via curl) and to see if the String payload enters the process method as {"name":"value"}

What am I possibly doing wrong?

Thank you for taking the time to read this...

like image 979
PacificNW_Lover Avatar asked Mar 28 '15 04:03

PacificNW_Lover


People also ask

How consume JSON from RESTful web service in spring boot?

Create a simple Spring Boot web application and write a controller class files which is used to redirects into the HTML file to consumes the RESTful web services. We need to add the Spring Boot starter Thymeleaf and Web dependency in our build configuration file. For Maven users, add the below dependencies in your pom.

Can we send JSON object in post request in REST API?

To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.

How do I read a JSON file as a string?

We use the readAllBytes() method of the Files class to read bytes data of the JSON files as a string. We store the returned result of the readAllBytes()and get()methods into a variable and return it to the main() method. In the main() method, we simply print the returned result of the convertFileIntoString()


1 Answers

I think the simplest/handy way to consuming JSON is using a Java class that resembles your JSON: https://stackoverflow.com/a/6019761

But if you can't use a Java class you can use one of these two solutions.

Solution 1: you can do it receiving a Map<String, Object> from your controller:

@RequestMapping(     value = "/process",      method = RequestMethod.POST) public void process(@RequestBody Map<String, Object> payload)      throws Exception {    System.out.println(payload);  } 

Using your request:

curl -H "Accept: application/json" -H "Content-type: application/json" \ -X POST -d '{"name":"value"}' http://localhost:8080/myservice/process 

Solution 2: otherwise you can get the POST payload as a String:

@RequestMapping(     value = "/process",      method = RequestMethod.POST,     consumes = "text/plain") public void process(@RequestBody String payload) throws Exception {    System.out.println(payload);  } 

Then parse the string as you want. Note that must be specified consumes = "text/plain" on your controller. In this case you must change your request with Content-type: text/plain:

curl -H "Accept: application/json" -H "Content-type: text/plain" -X POST \ -d '{"name":"value"}' http://localhost:8080/myservice/process 
like image 56
Andrea Avatar answered Oct 06 '22 01:10

Andrea