简体   繁体   中英

Posting JSON to Controller returns 400 Bad Request

I am developing RESTful services. I am not able to POST JSON data to controller.

I am using the following dependencies:

  • Spring : 3.2.3.RELEASE
  • Jackson : 1.9.6

I also tried:

  • Spring 3.2.3.RELEASE w/ Jackson 1.9.9
  • Spring 3.1.1.RELEASE w/ Jackson 1.9.9

as suggested here POSTing JSON to Spring MVC Controller Returns 400 Bad Request

I made entries of MessageConverters also,

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

Controller

@Controller
@RequestMapping(value="/todo", consumes="application/json", produces="application/json")
//@RequestMapping(value="/todo", consumes="text/plain", produces="application/json")
public class TodoRestService {
   Logger logger = LoggerFactory.getLogger(TodoService.class);
   @Autowired
   private TodoService todoService;

   @RequestMapping(value="/{id}", method= RequestMethod.GET)
   @ResponseBody public Todo find(@PathVariable("id") Long id) {
     Todo todo = todoService.find(id);
     return todo;
   }

   @RequestMapping(method=RequestMethod.POST)
   @ResponseBody public Todo create(@RequestBody Todo todo) {
   //public Todo create(@RequestBody String todo) {
   //public Todo create(@RequestParam("todo") String todo) {
     System.out.println(todo);
     todoService.create(newTodo);
     return newTodo;
  }
}

POJO

public class TODO {
  private String firstName;
  private String lastName;

  //getter setters
} 

I am using postman to POST the JSON

I have set Content-Type as application/json

form data ----- name = todo value = {"firstName":"nilam","lastName":"naik"}

method = POST

I am getting 400 Bad Request.

But If I changed data type of parameter annotated with @RequestBody from TODO to String then
I am getting something like,

------WebKitFormBoundaryu6banLlTPiPudsBB
Content-Disposition: form-data; name="todo"

{"firstName":"nilam","lastName":"naik"}
------WebKitFormBoundaryu6banLlTPiPudsBB--

I also have Jackson on my classpath.

If I changed attribute consumes from application/json to text/plain and

@RequestBody String todo then I get,

{"firstName":"nilam","lastName":"naik"}

But I don't want to manually convert the String to Java Object. But I don't understand why @RequestBody is not able to convert my JSON data to Java Object.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"      
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-      v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.orci</groupId>
    <artifactId>OrciMavenTutorial</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>OrciMavenTutorial Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <!-- <org.springframework.version>3.2.3.RELEASE</org.springframework.version> -->
        <org.springframework.version>3.1.1.RELEASE</org.springframework.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId> 
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId> 
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-entitymanager</artifactId>
             <version>4.2.2.Final</version>
        </dependency>

        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <version>3.0.1</version>
             <scope>provided</scope>
        </dependency>

        <dependency>
             <groupId>org.apache.derby</groupId>
             <artifactId>derbyclient</artifactId>
             <version>10.5.3.0_1</version>
        </dependency>

        <dependency>
              <groupId>org.apache.derby</groupId>
              <artifactId>derby</artifactId>
              <version>10.5.3.0_1</version>
        </dependency>

        <dependency>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-api</artifactId>
              <version>1.7.7</version>
        </dependency>

        <dependency>
              <groupId>org.codehaus.jackson</groupId>
              <artifactId>jackson-core-asl</artifactId>
              <!-- <version>1.9.6</version> -->
              <!-- <version>1.4.2</version> -->
              <!-- <version>1.9.9</version> -->
              <version>1.9.7</version>
        </dependency>

       <dependency>
             <groupId>org.codehaus.jackson</groupId>
             <artifactId>jackson-mapper-asl</artifactId>
             <!-- <version>1.9.6</version> -->
             <!-- <version>1.4.2</version> -->
             <!-- <version>1.9.9</version> -->
             <version>1.9.7</version>
       </dependency>
 </dependencies>
 <build>
     <finalName>OrciMavenTutorial</finalName> 
 </build>

Please someone help me.

From the explanation you have given one thing is clear, You are using POSTMAN wrongly.

You can not send a @RequestBody annotated object in a form-data . Forms are handled using @ModelAttribute or @RequestParam (Multiple of this).

If you want to post a JSON to an Controller end point you must do like the following image;

在此处输入图片说明

You must select POST obviously and must set a header Content-Type as application/json , finally you must select raw from the tabs and select JSON from the dropdown.

If you follow this your Controller method must work with Todo object as @RequestBody annotation and no need to use String and manually convert to object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM