RestTemplate使用JSON发送Post请求

2023-10-31

RestTemplate使用JSON发送Post请求

本文我们说下如何使用Spring的 RestTemplate调用post请求,发送json内容。

1. 定义服务端web接口

1.1. 定义业务接口

先定义Person实体类表示post请求的数据:

public class Person {
    private Integer id;
    private String name;
 
    // standard constructor, getters, setters
}

再定义PersonService接口并实现两个方法,关联使用Person类:

public interface PersonService {
 
    public Person saveUpdatePerson(Person person);
    public Person findPersonById(Integer id);
}

这些方法的实现仅返回对象,不再具体讨论,让我们聚焦web层。

1.2. 定义业务REST API

下面我们为Person类定义简单的Rest api:

@PostMapping(value = "/createPerson", consumes = "application/json", produces = "application/json")
public Person createPerson(@RequestBody Person person) {
    return personService.saveUpdatePerson(person);
}
 
@PostMapping(value = "/updatePerson", consumes = "application/json", produces = "application/json")
public Person updatePerson(@RequestBody Person person, HttpServletResponse response) {
    response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath()
      .path("/findPerson/" + person.getId()).toUriString());
     
    return personService.saveUpdatePerson(person);
}

我们需要发送json格式post请求数据,为此,在两个方法的@PostMapping中增加consumes属性并设置值为“application/json”。类似的,设置produces属性值为“application/json”,为了告诉Spring我们希望响应数据也是json格式。

person参数前的注解@RequestBody,表明person对象和http请求体绑定。最后两个方法返回Person对象会绑定至http响应体。如果给api类增加@RestController注解,则所有api方法都带有@ResponseBody注解。

2. 使用RestTemplate

现在写几个单元测试,测试Person rest api。我们尝试使用RestTemplate发送post请求给Person api,共三个方法: postForObject, postForEntity, and postForLocation。

开始实现单元测试之前,先定义setup方法初始化单元测试方法中使用的对象:

@BeforeClass
public static void runBeforeAllTestMethods() {
    createPersonUrl = "http://localhost:8082/spring-rest/createPerson";
    updatePersonUrl = "http://localhost:8082/spring-rest/updatePerson";
 
    restTemplate = new RestTemplate();
    headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
   ObjectNode personJsonObject = objectMapper.createObjectNode();
   personJsonObject.put("id", 1);
   personJsonObject.put("name", "John");
}

除了setup方法,还要引入ObjectMapper对象转换JSON字符串为JSONNode对象:

private final ObjectMapper objectMapper = new ObjectMapper();

我们前面提到,post请求数据使用json格式。因此,在请求头中增加 Content-Type属性,值为APPLICATION_JSON 。Spring的 HttpHeaders提供不同的方法访问请求头信息。这里需要通过setContentType方法设置Content-Type 属性值为 application/json。然后给请求对象附加头信息。

2.1. 使用postForObject方法发送json

RestTemplate的postForObject 方法post对象给uri并返回新的对象。返回值自动被转换为responseType参数指定的类型,这里是字符串。

我们的需求是发送post请求至person api,创建新的Person对象并响应中包括新创建的对象。
首先,基于personJsonObject构建HttpEntity 类型的请求对象,并在请求头中指定Content-Type。然后调用postForObject 方法发送json请求体:

@Test
public void givenDataIsJson_whenDataIsPostedByPostForObject_thenResponseBodyIsNotNull()
  throws IOException {
    HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
     
    String personResultAsJsonStr = restTemplate.postForObject(createPersonUrl, request, String.class);
    JsonNode root = objectMapper.readTree(personResultAsJsonStr);
     
    assertNotNull(personResultAsJsonStr);
    assertNotNull(root);
    assertNotNull(root.path("name").asText());
}

该示例中 postForObject() 方法返回字符串响应体。我们也可以通过设置responseType参数使其返回Person类型:

Person person = restTemplate.postForObject(createPersonUrl, request, Person.class);
 
assertNotNull(person);
assertNotNull(person.getName());

实际上我们的请求处理方法(createPersonUrl 参数匹配的)产生json格式的响应体,但对postForObject 方法没有限制,通过设置responseType参数可以自动转换为响应的java类型。

2.2. 使用postForEntity发送json

相比于postForObject()方法, postForEntity() 返回响应体为 ResponseEntity 类型,其他两个方法功能一致。

我们的需求是发送post请求至person api,创建新的Person对象并返回ResponseEntity类型响应体。可以使用postForEntity实现该功能:

@Test
public void givenDataIsJson_whenDataIsPostedByPostForEntity_thenResponseBodyIsNotNull()
  throws IOException {
    HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
     
    ResponseEntity<String> responseEntityStr = restTemplate.
      postForEntity(createPersonUrl, request, String.class);
    JsonNode root = objectMapper.readTree(responseEntityStr.getBody());
  
    assertNotNull(responseEntityStr.getBody());
    assertNotNull(root.path("name").asText());
}

类似的,也可以设置responseType 参数转换响应体为Java类型。这里我们能够返回响应体为ResponseEntity,也能返回响应为 ResponseEntity 对象,只要设置responseType参数为 Person.class:

ResponseEntity<Person> responseEntityPerson = restTemplate.
  postForEntity(createPersonUrl, request, Person.class);
  
assertNotNull(responseEntityPerson.getBody());
assertNotNull(responseEntityPerson.getBody().getName());

2.3. 使用postForLocation发送json

与postForObject 和 postForEntity 方法类型, postForLocation 也发送post请求至特定uri并创建新的对象。唯一的差异是返回值为Location头信息。

前面updatePerson rest api在响应中设置Location 头信息:

response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath()
  .path("/findPerson/" + person.getId()).toUriString());

现在我们需要实现更新person对象后接收返回带有Location头信息的响应,使用postForLocation 方法:

@Test
public void givenDataIsJson_whenDataIsPostedByPostForLocation_thenResponseBodyIsTheLocationHeader() 
  throws JsonProcessingException {
    HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
    URI locationHeader = restTemplate.postForLocation(updatePersonUrl, request);
     
    assertNotNull(locationHeader);
}

3. 总结

本文讲解了RestTemplate 如何发送json类型的post请求,共三种方法应用与不同场景。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RestTemplate使用JSON发送Post请求 的相关文章

随机推荐

  • 台阶--Nim游戏(博弈论)

    问题 现在 有一个 nn 级台阶的楼梯 每级台阶上都有若干个石子 其中第 ii 级台阶上有 aiai 个石子 i 1i 1 两位玩家轮流操作 每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中 不能不拿 已经拿到地面上的石子不能再拿
  • 子网掩码是什么,IP段的24是什么写法

    背景 关于设置 IP 网段 我们常见到的 192 168 1 0 24 是什么意思 24是什么意思 这里的 192 168 1 0 的末尾0是 一定是0吗 跟 192 168 1 5 24 所表示的网段是一样的吗 解答 24 这种写法 24
  • QGC调试px4飞控问题总结

    注 本文主要讨论本人遇到的问题 由于各操作步骤已有不少文章说明具体操作方法 本文不再赘述 1 如果使用碳纤维机架 要在电源板背面增加绝缘层以防短路 如果自行焊接导线 应当检查是否短路 2 传感器校准时尽量不要放到桌子上调 这是因为桌子可能不
  • pytorch 初始化

    初始化权值
  • 蓝桥杯:试题F:青蛙过河问题

    试题描述 小青蛙住在一条河边 它想到河对岸的学校去学习 小青蛙打算经过河里 的石头跳到对岸 河里的石头排成了一条直线 小青蛙每次跳跃必须落在一块石头或者岸上 不过 每块石头有一个高度 每次小青蛙从一块石头起跳 这块石头的高度就 会下降 1
  • vue项目 设置scrollTop不起作用 总结

    今天在开发中 遇到这样一个情景 一个页面中有三个模块 每个模块对应一个标题 每个模块内容都很长 所以需要点击当前模块对应的标题滚动到模块所在位置 我想的方案是获取到每个模块距离文档顶部的距离 然后将值赋给对应要滚动的元素 步骤如下 首先给每
  • 【每日运维】RockyLinux8.6升级OpenSSH9.4p1

    为什么需要升级openssh呢 因为很多项目进行漏扫结果都会涉及到这个服务器核心组件 一想到以前升级openssh带来的各种依赖性问题就头疼 不管是什么发行版 升级这个东西真的很烦 这次发现可能还会有好一点的通用一点的升级方法 所以有个这个
  • angular调用接口方式_如何在Angular优雅编写HTTP请求

    引言 基本上当下的应用都会分为前端与后端 当然这种前端定义不在限于桌面浏览器 手机 APP等设备 一个良好的后端会通过一套所有前端都通用的 RESTful API 序列接口作为前后端之间的通信 这其中对于身份认证都不可能再依赖传统的Sess
  • 微信小程序面试题

    1 请谈谈wxml与标准的html的异同 标签名字有点不一样 多了一些 wx if 这样的属性以及 这样的表达式 开发工具限制 WXML仅能在微信小程序开发工具中预览 而HTML可以在浏览器内预览 组件封装不同 WXML对组件进行了重新封装
  • 今年做什么副业好?2021年做什么副业挣钱?2021年适合做的副业

    这两年我明白了一个道理 就是人无远虑必有近忧 所以2021我建议大家最好有一个副业 因为有了副业 即使我们没了工作也会有一定的生活保障 2021年适合做的副业有哪些 2021年做什么副业挣钱呢 第一类 体力类 1 餐饮兼职 虽然收入比较低
  • JAVA数据脱敏

    为了保护用户隐私 需要对敏感信息进行脱敏处理 如 姓名 电话号码 身份证 基于jackson 通过自定义注解的方式实现数据脱敏 添加依赖 spring web spring boot starter web已经集成了jackson相关包 不
  • Windows 环境下,nginx 配置文件上传大小

    问题描述 今天将刚刚和前端对接的文件上传功能 部署到公司的测试环境 提示如下错误信息 413 Request Entity Too Large 解决方法如下 1 打开nginx配置文件 nginx conf 路径一般是 E nginx 1
  • 《数据库系统概论》课程之实验五流六

    前序 数据库系统概论 课程之实验五 通过嵌入式SQL访问数据库 1实验目的 熟悉通过嵌入式SQL 主语言为C语言 编程访问数据库 实验以C语言为例作说明 实作可以选择任意语言实现本实验 2实验平台和实验工具 在KingbaseES数据库管理
  • oracle 如何修改表空间,ORACLE修改表空间方法

    1 使用imp exp 先导出源库 再建立新库把表空间建立好 而后再导入 听说这样能够 前提是新的库里面不能有与源库相同名字的表空间 有待验证 2 使用脚本进行修改 据目前所了解 正长状况下须要修改表的空间和表的索引的空间 若是涉及到BOL
  • 【OJ比赛日历】快周末了,不来一场比赛吗? #09.09-09.15 #15场

    CompHub 1 实时聚合多平台的数据类 Kaggle 天池 和OJ类 Leetcode 牛客 比赛 本账号会推送最新的比赛消息 欢迎关注 以下信息仅供参考 以比赛官网为准 目录 2023 09 09 周六 5场比赛 2023 09 10
  • 常用宏定义运算

    define DLT x y x gt y x y y x define MIN x y x gt y y x define MAX x y x gt y x y define EQU x y DLT x y
  • 更改 Python 的 pip install 默认使用的pip库以及默认安装路径

    时间 2018 10 07 题目 更改 Python 的 pip install 默认使用的pip库以及默认安装路径 目录 一 更改 Python 的 pip install 默认使用的pip库 二 更改 Python 的 pip inst
  • OJ# 384 敲七

    题目描述 有 N 个人在玩一种 敲7 游戏 游戏的规则是这样的 第 x 个人从 t 开始报数 然后按顺序报数 当某人报的数是 7 的倍数或数字中含有 7 时 便被淘汰 剩下的人继续报数 直到只剩下一个人 现求最终剩下的人编号 输入 一行三个
  • 示例:Scala读取xml文件

    test xml内容如下
  • RestTemplate使用JSON发送Post请求

    RestTemplate使用JSON发送Post请求 本文我们说下如何使用Spring的 RestTemplate调用post请求 发送json内容 1 定义服务端web接口 1 1 定义业务接口 先定义Person实体类表示post请求的