Before going into details, I know there has been lots of conversations and related questions on Stackoverflow. All of them kind of help me in different ways so I thought I put my findings all together as a single organized FAQ to summarize my findings.

相关概念

Surely you know about these but I just write them as a quick review. Feel free to edit in case I am missing something.

HTTP POST请求:

A post request is used when you are willing to send an object to a web service or a your server side application.

序列化:

是将对象从web浏览器传送到服务器端应用程序的过程.可以使用jQuery Ajax调用或Curl post请求.

序列化协议:

现在最流行的是JSON和XML.XML正变得越来越不受欢迎,因为由于XML标记的性质,序列化的XML对象在大小上相对较大.在本常见问题解答中,主要焦点是JSON2序列化.

春天:

Spring框架及其强大的注释使得以高效的方式公开Web服务成为可能.Spring有很多不同的图书馆.我们在这里关注的是Spring web MVC.

Curl vs JQuery:

这些是您可以用来在客户端发出post请求的工具.即使您计划使用jQueryAjax调用,我建议您出于调试目的使用Curl,因为它在发出post请求后为您提供了详细的响应.

@RequestBody vs@RequestParam/@PathVariable vs@ModelAttribute:

In cases where you have a web service that is not depending on your Java EE model, @RequestBody must be used. If you are using the model and your JSON object is added to the model, you can access the object through @ModelAttribute. Only for cases where your request is either a GET request or a GET and POST request combination you will need to use @RequestParam/@PathVariable.

@RequestBody vs @ResposeBody:

从名称可以看出,它就这么简单,如果在服务器端方法处理请求后向客户端发送响应,则只需要@ResponseBody.

RequestMappingHandlerAdapter vs AnnotationMethodHandlerAdapter:

RequestMappingHandlerAdapter是Spring框架的新映射处理程序,从Spring3.1开始取代了AnnotationMethodHandlerAdapter.如果您的现有配置仍在AnnotationMethodHandlerAdapter中,您可能会发现这篇文章很有用.我的帖子中提供的配置将让您了解如何设置RequestMappingHandlerAdapter.

设置

您需要设置一个消息转换器.这就是在服务器端将序列化的JSON消息体转换为本地java对象的方式.

here开始的基本配置.basic configuration sample中的转换器是MarshallingHttpMessageConverter和CastorMarshaller,我将它们替换为MappingJackson2HttpMessageConverter和MappingJacksonHttpMessageConverter.

配置放在哪里

The way my project is set up, I have two config files:

  • 应用程序上下文XML: 其中之一是您的sessionFactory bean、DataSource bean等所在的应用程序上下文XML文件.
  • MVC Dispatcher Servlet XML: This is where you have your view resolver bean and import your application context XML.

hadlerAdapter bean has to be located in the later that is the MVC Dispatcher XML file.

<bean name="handlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
            <ref bean="jsonConverter"/>

        </list>

    </property>
    <property name="requireSession" value="false"/>

</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json"/>
</bean>

You can have multiple message convertors. here, I have created a normal JSON as well as a JSON 2 message convertor. Both Ref and normal bean format in the XML file have been used (personally I prefer the ref tag as its neater).

睡觉接口

下面是一个示例控制器,它公开了睡觉接口.

The controller

这就是HTTP post请求的睡觉接口公开的地方.

@Component
@Controller
@RequestMapping("/api/user")
public class UserController {
@RequestMapping(value = "/add", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String insertUser(@RequestBody final User user) {
    System.out.println(user.toString());
    userService.insertUser(user);
    String userAdded = "User-> {" + user.toString() + "} is added";
    System.out.println(userAdded);
        return userAdded;
    }
}

Java对象

@JsonAutoDetect
public class User {

private int id;
private String username;
private String name;
private String lastName;
private String email;

public int getId() {
    return externalId;
}

public void setId(final int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(final String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(final String email) {
    this.email = email;
}
public String getUsername() {
    return username;
}

public void setUsername(final String username) {
    this.username = username;
}

public String getLastName() {
    return lastName;
}

public void setLastName(final String lastName) {
    this.lastName = lastName;
}

@Override
public String toString() {
    return this.getName() + " | " + this.getLastName()  + " | " + this.getEmail()
            + " | " + this.getUsername()  + " | " + this.getId()  + " | ";
    }

}

CURL Post call

curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

Related posts and questions

This FAQ was not possible if it wasn't for all the people who provided the following posts and questions (this list will expand if I come across useful related posts/questions):

  1. What is the correct JSON content type?
  2. Spring 3.0 making JSON response using jackson message converter
  3. How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  4. Posting JSON to 睡觉接口
  5. https://github.com/geowarin/spring-mvc-examples
  6. How to post JSON to PHP with curl
  7. Spring REST | MappingJacksonHttpMessageConverter produces invalid JSON
  8. https://github.com/eugenp/REST
  9. Spring Web MVC - validate individual request params
  10. How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  11. How do you return a JSON object from a Java Servlet
  12. What MIME type if JSON is being returned by a 睡觉接口?

推荐答案

CURL Post call

curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

Different Error Scenarios:

在这里,我将探讨您在进行curl 呼叫后可能遇到的不同错误,以及可能出现的错误.

场景一:

HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 949
Date: Tue, 04 Jun 2013 02:59:35 GMT

这意味着您提供的URL中不存在REST API.

Root cause:
  • 你的请求可能有输入错误(相信我,这是可能发生的)!
  • 可能是您的弹簧配置不正确.如果是这样的话,它需要进一步挖掘到底出了什么问题,但是在开始更复杂的调查之前,我已经提供了一些您需要做的初步操作.
Actions:

After you have made sure that everything is done perfectly right and nothing is wrong with your Configuration nor you URL: - Run a maven clean. - Undeploy your web app or simply delete it. - Redeploy the web app - Make sure to use only one version of Spring in your maven/gradle

场景二:

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 968
Date: Tue, 04 Jun 2013 03:08:05 GMT
Connection: close

这背后的唯一原因是您的请求格式不正确.如果您判断了详细的cURL响应,您应该能够看到"客户端发送的请求在语法上不正确".

Root cause:

Either your JSON format is not right or you are missing a mandatory parameter for the JAVA object.

Actions:

确保提供的JSON对象格式正确,参数数量正确.可为null的属性不是强制性的,但必须为所有不可为null的属性提供数据.记住Spring使用Java反射将JSON文件转换为Java对象是非常重要的,这意味着什么?这意味着变量名和方法名区分大小写.如果JSON文件发送变量"userName",那么Java对象中匹配的变量也必须命名为"userName".如果你有能手和二传手,他们也必须遵循同样的规则.getUserName和setUserName匹配我们前面的示例.

Senario Three:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT
Root cause:

您的web服务不支持Json媒体类型.这可能是因为注释未指定媒体类型,或者您未在Curl post命令中指定媒体类型.

Actions:

判断消息转换器是否正确设置,并确保web服务注释与上述示例匹配.如果没有问题,请确保在Curl post请求中指定内容类型.

The json media type is not supported by your web service.

Senario N(!):

HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
Content-Type: application/json;charset=UTF-8 
Transfer-Encoding: chunked 
Date: Tue, 04 Jun 2013 03:06:16 GMT 

恭喜用户实际被发送到您的服务器端睡觉接口.

For further details on how to set up your spring checkout the spring mvc guide.

Related posts and questions

This FAQ was not possible if it wasn't for all the people who provided the following posts and questions (this list will expand if I come across useful related posts/questions):

  1. What is the correct JSON content type?
  2. Spring 3.0 making JSON response using jackson message converter
  3. How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  4. Posting JSON to REST API
  5. https://github.com/geowarin/spring-mvc-examples
  6. How to post JSON to PHP with curl
  7. Spring REST | MappingJacksonHttpMessageConverter produces invalid JSON
  8. https://github.com/eugenp/REST
  9. Spring Web MVC - validate individual request params
  10. How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  11. How do you return a JSON object from a Java Servlet
  12. What MIME type if JSON is being returned by a REST API?

Json相关问答推荐

您可以使用Jolt对JSON执行OR条件吗

从Razor Pages的AJAX Json呈现DataTables问题.Net GET

如何在使用GO时检测JSON中不需要的字段?

无法从JSON解析ZonedDateTime,但可以使用格式化程序很好地解析

使用Kotlin限制序列化类属性的允许整数值

如何在VB6中将字符串转换或解码为可读格式?

在 python 中循环 JSON 数组

Delphi 11.3无法从变体创建/添加JSON

在这种情况下我如何实现 UnmarshalJSON 并且只为一个接口字段定义特殊行为?

Vue 3如何将参数作为json发送到axios get

Flutter:在本地文件 json 中搜索特殊的阿拉伯字符

如何在生产环境中更改 Flutter 应用程序中的数据模型?

如何使用 Swift 从 NSURLSession 获取 cookie?

Java的JSON字符串整洁/格式化程序

将 PHP 结果数组转换为 JSON

在视图中将 .Net 对象转换为 JSON 对象

Json.NET 是否缓存类型的序列化信息?

在 JSON.NET 中序列化派生类时的字段顺序

将 json 转换为 C# 数组?

Microsoft.Net.Http 与 Microsoft.AspNet.WebApi.Client