Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一次性解决?

2023-12-30

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

相关概念

您当然知道这些,但我只是将它们写为快速回顾。如果我遗漏了什么,请随意编辑。

HTTP POST 请求:

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

序列化:

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

序列化协议:

目前最流行的是 JSON 和 XML。由于 XML 标记的性质,序列化的 xml 对象的大小相对较大,因此 XML 变得越来越不流行。在此常见问题解答中,主要焦点是JSON2 https://stackoverflow.com/questions/3979649/json2-vs-jquery-json序列化。

Spring:

Spring框架及其强大的注释使得以有效的方式公开Web服务成为可能。 Spring 有很多不同的库。我们这里的重点是Spring Web MVC http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestbody.

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。

Setup

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

基本配置来自here https://stackoverflow.com/questions/3979649/json2-vs-jquery-json。转换器是 Marshalling HttpMessageConverter 和 CastorMarshaller基本配置示例 https://stackoverflow.com/questions/3979649/json2-vs-jquery-json,我已将它们替换为 MappingJackson2HttpMessageConverter 和 MappingJacksonHttpMessageConverter。

配置放在哪里

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

  • 应用程序上下文 XML: 其中之一是 sessionFactory bean、dataSource bean 等所在的应用程序上下文 XML 文件。
  • MVC 调度程序 Servlet XML: 您可以在此处拥有视图解析器 bean 并导入应用程序上下文 XML。

hadlerAdapter bean 必须位于后面的 MVC 调度程序 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 的示例控制器。

控制器

这是公开 HTTP post 请求的 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":"JohnB[email protected] /cdn-cgi/l/email-protection"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

相关帖子和问题

如果不是所有提供以下帖子和问题的人,这个常见问题解答就不可能实现(如果我遇到有用的相关帖子/问题,此列表将会扩展):

  1. 是什么correctJSON 内容类型? https://stackoverflow.com/questions/477816/what-is-the-correct-json-content-type?rq=1
  2. Spring 3.0 使用 Jackson 消息转换器进行 JSON 响应 https://stackoverflow.com/questions/2259551/spring-3-0-making-json-response-using-jackson-message-converter?rq=1
  3. 如何使用 Curl 从终端/命令行发布 JSON 数据来测试 Spring REST? https://stackoverflow.com/questions/7172784/how-to-post-json-data-with-curl-from-terminal-commandline-to-test-spring-rest
  4. 将 JSON 发布到 REST API https://stackoverflow.com/questions/10323957/posting-json-to-rest-api
  5. https://github.com/geowarin/spring-mvc-examples https://github.com/geowarin/spring-mvc-examples
  6. 如何使用curl将JSON发布到PHP https://stackoverflow.com/questions/813487/how-to-post-json-to-php-with-curl
  7. 春季休息| MappingJacksonHttpMessageConverter 生成无效的 JSON https://stackoverflow.com/questions/5613566/spring-rest-mappingjacksonhttpmessageconverter-produces-invalid-json
  8. https://github.com/eugenp/REST https://github.com/eugenp/REST
  9. Spring Web MVC - 验证单个请求参数 https://stackoverflow.com/questions/6203740/spring-web-mvc-validate-individual-request-params?rq=1
  10. 如何使用 Curl 从终端/命令行发布 JSON 数据来测试 Spring REST? https://stackoverflow.com/questions/7172784/how-to-post-json-data-with-curl-from-terminal-commandline-to-test-spring-rest?rq=1
  11. 如何从 Java Servlet 返回 JSON 对象 https://stackoverflow.com/questions/2010990/how-do-you-return-a-json-object-from-a-java-servlet?lq=1
  12. 如果 REST API 返回 JSON,那么什么 MIME 类型? https://stackoverflow.com/questions/404470/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":"JohnB[email protected] /cdn-cgi/l/email-protection"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

不同的错误场景:

在这里,我探讨了进行卷曲调用后可能会遇到的不同错误以及可能出现的问题。

场景一:

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:

在确保一切都完全正确并且您的配置和 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响应,您应该能够看到“客户端发送的请求在语法上不正确。”。

Root cause:

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

Actions:

确保以正确的格式和正确数量的参数提供 JSON 对象。可空属性不是强制性的,但您必须为所有不可空属性提供数据。记住 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
Root cause:

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

Actions:

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

您的 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 指南。

相关帖子和问题

如果不是所有提供以下帖子和问题的人,这个常见问题解答就不可能实现(如果我遇到有用的相关帖子/问题,此列表将会扩展):

  1. 是什么correctJSON 内容类型? https://stackoverflow.com/questions/477816/what-is-the-correct-json-content-type?rq=1
  2. Spring 3.0 使用 Jackson 消息转换器进行 JSON 响应 https://stackoverflow.com/questions/2259551/spring-3-0-making-json-response-using-jackson-message-converter?rq=1
  3. 如何使用 Curl 从终端/命令行发布 JSON 数据来测试 Spring REST? https://stackoverflow.com/questions/7172784/how-to-post-json-data-with-curl-from-terminal-commandline-to-test-spring-rest
  4. 将 JSON 发布到 REST API https://stackoverflow.com/questions/10323957/posting-json-to-rest-api
  5. https://github.com/geowarin/spring-mvc-examples https://github.com/geowarin/spring-mvc-examples
  6. 如何使用curl将JSON发布到PHP https://stackoverflow.com/questions/813487/how-to-post-json-to-php-with-curl
  7. 春季休息| MappingJacksonHttpMessageConverter 生成无效的 JSON https://stackoverflow.com/questions/5613566/spring-rest-mappingjacksonhttpmessageconverter-produces-invalid-json
  8. https://github.com/eugenp/REST https://github.com/eugenp/REST
  9. Spring Web MVC - 验证单个请求参数 https://stackoverflow.com/questions/6203740/spring-web-mvc-validate-individual-request-params?rq=1
  10. 如何使用 Curl 从终端/命令行发布 JSON 数据来测试 Spring REST? https://stackoverflow.com/questions/7172784/how-to-post-json-data-with-curl-from-terminal-commandline-to-test-spring-rest?rq=1
  11. 如何从 Java Servlet 返回 JSON 对象 https://stackoverflow.com/questions/2010990/how-do-you-return-a-json-object-from-a-java-servlet?lq=1
  12. 如果 REST API 返回 JSON,那么什么 MIME 类型? https://stackoverflow.com/questions/404470/what-mime-type-if-json-is-being-returned-by-a-rest-api
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一次性解决? 的相关文章

随机推荐

  • 下载 Excel 文件

    我之前曾问过这个问题 但在启动文件下载时仍然遇到困难 var fileName ExcelData xlsx var file new FileInfo fileName using var package new OfficeOpenXm
  • 撤销权限 android.permission.CAMERA

    我收到错误revoked permission android permission CAMERA 我在清单上使用了相机权限 private void dispatchTakePictureIntent int actionCode Int
  • 程序崩溃,但调试诊断说这是第一次机会异常,对吗?

    也许这是正常情况 但我很困惑 我正在从 Visual Studio 运行我的 C 调试应用程序 DebugDiag 设置为自动附加到进程 我有一条规则从该 应用程序收集故障转储 并且该规则定义未配置的第一次机会异常的操作应为 无 但是当应用
  • 如何将 EL 变量传递给 JavaScript

    我有一个变量 bean name 我如何将它传递给 JavaScript 变量 我试过了var name bean name and var name bean name 但它不起作用 我的想法是将其放入隐藏输入中 就像隐藏中一样
  • Phonegap iOS:将图像下载到照片库

    是否可以下载文件 图像 并将其保存在照片库中 我知道这一点download http docs phonegap com en 2 3 0 cordova file file md html FileTransfer download方法
  • 获取整数的第 n 位

    我得到一个大整数a 和一个 相对较小的 整数n 最快的获取方式是什么n二进制表示的第 th 位 从右起 a使用原生Python 将位移到最后一个位置 屏蔽其他所有内容 bit a gt gt n 1 这假设这些位以通常的方式索引 即最低有效
  • 如何在 asp.net MVC 中压缩内容?

    如何压缩 asp net mvc 应用程序发送的输出 这是我使用的 截至目前 using System IO Compression public class CompressAttribute ActionFilterAttribute
  • 从 kpcs7 (.p7b) 文件中提取私钥和证书

    我有一个 p7b 文件 如何提取密钥和证书 我尝试过 openssl 但无法获得确切的命令 选项 Thanks PKCS 7 文件不包含私钥 至于证书 您尚未指定您使用的平台以及您的问题与编程有何关系
  • 在 Windows 上安装更新时 Electron 自动更新失败

    我有一个电子应用程序 它使用electron builder用于构建 打包和发布应用程序 我有以下自动更新代码 autoUpdater logger log autoUpdater logger transports file level
  • VBScript 打开一个对话框来选择文件路径

    目前我正在使用 vbscript 打开一个文件 如下所示 strFile C Users test file txt Set objFile objFSO OpenTextFile strFile 我想更改此设置 以便用户可以选择 导航到文
  • WPF:忽略覆盖/装饰器上的鼠标单击,但处理 MouseEnter 事件

    我真正想要的是忽略鼠标的 IsHitTestVisible 版本click事件但仍然捕获鼠标进入和离开 events 背景 每当焦点控件下方都会弹出信息叠加层 这是一项要求 因此我无权删除此行为 这是使用包含矩形形状且填充有图像画笔的装饰器
  • c# 将非常大的位图保存为 jpeg(或任何其他压缩格式)

    我目前正在处理非常大的图像 这些图像基本上是通过将许多较小的图像拼接在一起生成的 例如全景图或照片马赛克软件 为了避免内存不足的异常 内存中只有如何排列较小图像的 地图 我编写了一些代码 使用 BinaryWriter 和 LockBits
  • 如何使固定元素的内容仅在超过视口高度时才可滚动?

    我有一个div定位fixed位于网页的左侧 包含菜单和导航链接 它没有从 css 设置高度 内容决定高度 宽度是固定的 问题是如果内容太多的话div会大于窗口的高度 并且部分内容将不可见 滚动窗口没有帮助 因为位置是fixed和div不会滚
  • 如何从VB脚本确定Windows版本? [复制]

    这个问题在这里已经有答案了 可能的重复 用于查找 Windows 版本名称和服务包的 vbscript https stackoverflow com questions 4317794 a vbscript to find windows
  • 现有文件上的 java.io.FileNotFoundException

    当我尝试打开文件时出现此错误 java io FileNotFoundException D Portable 20Programs Android 20Development workspace3 XXX desktop bin Worl
  • Play 的 API 上找不到 JPA.getJPAConfig 方法

    我正在使用最新版本的 Play v 1 2 3 我的系统需要从一个数据库读取数据并将其保存到另一个数据库 我在 Play 文档中发现有一个名为 play db JPA getJPAConfig 的方法来完成这项工作 我需要在源数据库中进行本
  • 基于第三列的 pandas 数据框颜色的 Seaborn 散点图

    我有一个 pandas 数据框 其中包含 组名 结果 和 温度 列 我绘制了一个 Seaborn 群图 其中 x groupname 和 y result 它显示了分成组的结果数据 我还想做的是使用颜色图根据标记的温度对标记进行着色 例如最
  • 如何更改 VS Code 中特定单词的颜色?

    有没有办法用自定义颜色为特定单词着色 我正在查看 editor tokenColorCustomizations 但似乎没有任何暗示 我想轻松地从其他代码中辨别出一段特定的代码 例如自定义方法 例如在 javascript 中 您经常使用
  • 使用 scikit Pipeline 测试模型,但仅预处理数据一次

    假设我有一个数据管道 它进行预处理并在最后有一个估计器 现在 如果我只想在管道的最后一步更改估计器 模型 我该如何做而不再次预处理相同的数据 下面是一个代码示例 pipe make pipeline ColumnSelector colum
  • Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一次性解决?

    在详细介绍之前 我知道 Stackoverflow 上已经有很多对话和相关问题 他们都以不同的方式帮助我 所以我想我将我的发现全部放在一起作为一个有组织的常见问题解答来总结我的发现 相关概念 您当然知道这些 但我只是将它们写为快速回顾 如果