java - Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一劳永逸?

标签 java json spring curl html-post

在详细介绍之前,我知道在 Stackoverflow 上有很多对话和相关问题。所有这些都以不同的方式帮助我,所以我想我把我的发现放在一起作为一个单一的有组织的常见问题解答来总结我的发现。

相关概念

你肯定知道这些,但我只是把它们写成一个快速回顾。如果我遗漏了什么,请随意编辑。

HTTP POST 请求:

当您愿意将对象发送到 Web 服务或服务器端应用程序时,将使用 post 请求。

序列化:

是将对象从 Web 浏览器获取到服务器端应用程序的过程。可以使用 jQuery Ajax 调用或 Curl 发布请求。

序列化协议(protocol):

目前最流行的是 JSON 和 XML。由于 XML 标记的性质,序列化 xml 对象的大小相对较大,因此 XML 变得越来越不流行。在此常见问题解答中,主要焦点是 JSON2连载。

Spring :

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

curl 与 JQuery:

这些是您可以用来在客户端发出发布请求的工具。即使您打算使用 JQuery ajax 调用,我建议您将 Curl 用于调试目的,因为它会在发出 post 请求后为您提供详细的响应。

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

如果您的 Web 服务不依赖于您的 Java EE 模型,则必须使用 @RequestBody。如果您正在使用模型并且您的 JSON 对象已添加到模型中,则您可以通过 @ModelAttribute 访问该对象。仅当您的请求是 GET 请求或 GET 和 POST 请求组合时,您才需要使用@RequestParam/@PathVariable。

@RequestBody 与 @ResposeBody:

正如您从名称中看到的那样简单,如果您在服务器端方法处理请求后向客户端发送响应,则只需要@ResponseBody。

RequestMappingHandlerAdapter 与 AnnotationMethodHandlerAdapter:

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

设置

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

来自 here 的基本配置.转换器是 basic configuration sample 中的 MarshallingHttpMessageConverter 和 CastorMarshaller。 ,我已经将它们替换为 MappingJackson2HttpMessageConverter 和 MappingJacksonHttpMessageConverter。

把配置放在哪里

我的项目设置方式,我有两个配置文件:

  • 应用程序上下文 XML:
    其中之一是 sessionFactory bean、dataSource bean 等所在的应用程序上下文 XML 文件。
  • MVC 调度程序 Servlet XML:
    这是您拥有 View 解析器 bean 并导入应用程序上下文 XML 的地方。

  • hadlerAdapter bean 必须位于 MVC Dispatcher XML 文件中。
    <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>
    

    您可以有多个消息转换器。在这里,我创建了一个普通的 JSON 和一个 JSON 2 消息转换器。 XML 文件中的 Ref 和普通 bean 格式都已使用(我个人更喜欢 ref 标记,因为它更整洁)。

    REST API

    这是一个公开 REST API 的示例 Controller 。

    Controller

    这是用于公开 HTTP 发布请求的 REST API 的地方。
    @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 发布调用
    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
    

    相关帖子和问题

    如果不是所有提供以下帖子和问题的人都无法使用此常见问题解答(如果我遇到有用的相关帖子/问题,此列表将扩大):
  • What is the correct JSON content type?
  • Spring 3.0 making JSON response using jackson message converter
  • How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  • Posting JSON to REST API
  • https://github.com/geowarin/spring-mvc-examples
  • How to post JSON to PHP with curl
  • Spring REST | MappingJacksonHttpMessageConverter produces invalid JSON
  • https://github.com/eugenp/REST
  • Spring Web MVC - validate individual request params
  • How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  • How do you return a JSON object from a Java Servlet
  • What MIME type if JSON is being returned by a REST API?
  • 最佳答案

    CURL 发布调用

    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
    

    不同的错误场景:

    在这里,我探讨了在进行 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。

    根本原因:
  • 您的请求中可能有错字(相信我会发生这种情况)!
  • 可能是您的 Spring 配置不正确。如果是这种情况,则需要进一步深入研究到底出了什么问题,但我已经提供了一些您在开始更复杂的调查之前需要执行的初始操作。

  • 行动:

    在您确保一切都做得非常正确并且您的配置和 URL 都没有问题之后:
    - 运行 Maven 清洁。
    - 取消部署您的网络应用程序或干脆删除它。
    - 重新部署网络应用
    - 确保在你的 maven/gradle 中只使用一个版本的 Spring

    场景二:
    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 响应,您应该能够看到“客户端发送的请求在语法上不正确。”。

    根本原因:

    您的 JSON 格式不正确,或者您缺少 JAVA 对象的必需参数。

    行动:

    确保以正确的格式和正确数量的参数提供 JSON 对象。 Nullable 属性不是强制性的,但您必须为所有 NotNullable 属性提供数据。记住 Spring 使用 Java 反射将您的 JSON 文件转换为 Java 对象非常重要,这是什么意思?这意味着变量和方法名称是 CasE SensItiVe。如果您的 JSON 文件发送变量“userName”,那么您的 Java 对象中的匹配变量也必须命名为“userName”。如果您有 getter 和 setter,它们也必须遵循相同的规则。 getUserName 和 setUserName 以匹配我们之前的示例。

    场景三:
    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
    

    根本原因:

    您的 Web 服务不支持 Json 媒体类型。这可能是由于您的注释未指定媒体类型或您未在 Curl post 命令中指定媒体类型。

    行动:

    检查您的消息转换器设置是否正确,并确保 Web 服务注释与上面的示例相匹配。如果这些都没有问题,请确保在 Curl 发布请求中指定内容类型。

    您的 Web 服务不支持 json 媒体类型。

    场景 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 
    

    恭喜用户实际上发送到您的服务器端 REST API。

    有关如何设置 spring 的更多详细信息,请查看 spring mvc 指南。

    相关帖子和问题

    如果不是所有提供以下帖子和问题的人都无法使用此常见问题解答(如果我遇到有用的相关帖子/问题,此列表将扩大):
  • What is the correct JSON content type?
  • Spring 3.0 making JSON response using jackson message converter
  • How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  • Posting JSON to REST API
  • https://github.com/geowarin/spring-mvc-examples
  • How to post JSON to PHP with curl
  • Spring REST | MappingJacksonHttpMessageConverter produces invalid JSON
  • https://github.com/eugenp/REST
  • Spring Web MVC - validate individual request params
  • How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
  • How do you return a JSON object from a Java Servlet
  • What MIME type if JSON is being returned by a REST API?
  • 关于java - Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一劳永逸?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16909742/

    相关文章:

    .net - WCF 数据服务是否返回无效的 JSON?

    java - 如何将 JFlex 词法分析器与 JavaCC 解析器一起使用?

    java - 使 Jersey bean 验证注释变得通用

    javascript - 从文件中读取 json 数据得到空白响应

    java - Hibernate EntityManager 未被注入(inject) - NullPointer

    java - Hibernate validator 不起作用

    java - JAXRS/Spring/CXF 端点配置中的合约详细信息——命名空间、PublishedUrl 等

    java - ImmutableSortedMap - 映射中的重复键

    java - PHP SoapClient 与 Java 服务器

    python - 在 Python 中接受 json 图像文件