# Spring Boot API 的 x-www-form-urlencoded 提交

**URL:** <https://www.isharkfly.com/t/spring-boot-api-x-www-form-urlencoded/13225>\
**Category:** 程序语言\
**Tags:** java, spring\
**Created:** [January 27, 2021, 3:51pm UTC](https://www.isharkfly.com/t/spring-boot-api-x-www-form-urlencoded/13225 "2021-01-27T15:51:53Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![lucas](https://www.isharkfly.com/user_avatar/www.isharkfly.com/lucas/32/20805_2.png) [@lucas](https://www.isharkfly.com/u/lucas)\
**Post date:** [January 27, 2021, 3:51pm UTC](https://www.isharkfly.com/t/spring-boot-api-x-www-form-urlencoded/13225/1 "2021-01-27T15:51:53Z")

</div>

在使用 Sprint Boot 提交 x-www-form-urlencoded 的时候，我们首先需要知道 x-www-form-urlencoded 这个是什么东西。

## application/x-www-form-urlencoded

这应该是最常见的 POST 提交数据的方式了。浏览器的原生 表单，如果不设置 `enctype` 属性，那么最终就会以 application/x-www-form-urlencoded 方式提交数据。

就是浏览器将会将表单中的内容转换为 URL 的方式提交到后台进行处理。转换的方式其实就是使用 K=V 对的方式。

不同的 K=V 之间是用 & 进行分隔。

例如下面的示例：

```auto
POST /test HTTP/1.1
Host: foo.example
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

field1=value1&field2=value2

```

你可以在你的 API 后面直接加上上面的字符串，然后 POST 请求过去，在上面的字符串和 URL 之间需要添加一个 ？ 号。

转换流程是：

假设你有一个表单，在表单中获取的值为：

field1=value1  
field2=value2

你需要提交的 URL 为 [api.example.com/re/request](http://api.example.com/re/request) 这样的话。

如果你使用了 application/x-www-form-urlencoded 提交的话，浏览器首先将表单中的数据转换为：field1=value1&field2=value2，请注意中间是使用 & 分隔的。

然后提交到地址：[api.example.com/re/request?field1=value1&field2=value2，上面显示的是完整的](http://api.example.com/re/request?field1=value1&field2=value2%EF%BC%8C%E4%B8%8A%E9%9D%A2%E6%98%BE%E7%A4%BA%E7%9A%84%E6%98%AF%E5%AE%8C%E6%95%B4%E7%9A%84) URL。

这种提交方式是表单的 **默认提交** 方式，同时提交的字符将会进行编码，如果你提交中文字符的话，你可能会看到 %UER，这样的表达，这是因为对中文字符进行了编码而已。

## POSTMAN 设置

在使用这种提交之前，你可以在 POSTMAN 设置。

![application-01](https://www.isharkfly.com/images/transparent.png)

需要在 POSTMAN 中选择提交方式，并且在下面的参数部分设置需要的参数然后单击发送提交即可。

## Spring Boot Controller

在 Spring Boot Controller 中需要设置使用 MultiValueMap。

在查看源代码后，你会知道 MultiValueMap 是扩展 Map 的接口，然后用于存储多值的。

![application-02](https://www.isharkfly.com/images/transparent.png)

一个 Controller 的代码如下：

```auto
    @PostMapping("/soldm")
    public ResponseEntity<?> searchUsers(@RequestBody MultiValueMap< String, String > values) {

        logger.debug("K=V Map - {}" , values);

        REListing reListing= listingService.getREListingById();

        return new ResponseEntity<REListing>(reListing, HttpStatus.OK);
    }

```

在 RequestBody 设置 MultiValueMap 后，你就可以获得 POST 提交的数据了。

![application-03](https://www.isharkfly.com/images/transparent.png)

## 测试运行

测试运行后查看日志：

```auto
2021-01-27 10:52:38.782 DEBUG 25176 --- [nio-8080-exec-4] c.o.e.s.controller.RealEstateController : K=V Map - {field1=[value1], field2=[value1]}

```

![application-04](https://www.isharkfly.com/images/transparent.png)

从这里，你可以 debug 上传的数据和 MAP 中是否设置了正确的参数。
