本文共 8219 字,大约阅读时间需要 27 分钟。
这个和get没有啥区别,就简单介绍
/** * 测试一个参数 * * @return */ @PostMapping("/post") public String test01(@RequestParam String name) { return name; } /** * 测试Map * * @return */ @PostMapping("/post/map") public String test02(@RequestParam Mapmap) { return map.toString(); }
/** * 测试一个参数 * * @return */ @RequestLine("POST /feign/provider/post?name={name}") String invokeTest01(@Param(value = "name") String name); /** * 测试map * * @return */ @RequestLine("POST /feign/provider/post/map") String invokeTest02(@QueryMap Mapmap);
@Testpublic void test01() { String response = client.invokeTest01("wade"); System.out.println(response);}@Testpublic void test02() { Mapmap = new HashMap<>(); map.put("name", "wade"); map.put("age", 28); String response = client.invokeTest02(map); System.out.println(response);}
[PostControllerClient#invokeTest01] ---> POST http://localhost:8001/feign/provider/post?name=wade HTTP/1.1[PostControllerClient#invokeTest01] ---> END HTTP (0-byte body)[PostControllerClient#invokeTest01] <--- HTTP/1.1 200 (163ms)[PostControllerClient#invokeTest01] connection: keep-alive[PostControllerClient#invokeTest01] content-length: 4[PostControllerClient#invokeTest01] content-type: text/plain;charset=UTF-8[PostControllerClient#invokeTest01] date: Sat, 20 Mar 2021 11:22:09 GMT[PostControllerClient#invokeTest01] keep-alive: timeout=60[PostControllerClient#invokeTest01] [PostControllerClient#invokeTest01] wade[PostControllerClient#invokeTest01] <--- END HTTP (4-byte body)wade[PostControllerClient#invokeTest02] ---> POST http://localhost:8001/feign/provider/post/map?name=wade&age=28 HTTP/1.1[PostControllerClient#invokeTest02] ---> END HTTP (0-byte body)[PostControllerClient#invokeTest02] <--- HTTP/1.1 200 (3057ms)[PostControllerClient#invokeTest02] connection: keep-alive[PostControllerClient#invokeTest02] content-length: 19[PostControllerClient#invokeTest02] content-type: text/plain;charset=UTF-8[PostControllerClient#invokeTest02] date: Sat, 20 Mar 2021 11:20:05 GMT[PostControllerClient#invokeTest02] keep-alive: timeout=60[PostControllerClient#invokeTest02] [PostControllerClient#invokeTest02] { name=wade, age=28}[PostControllerClient#invokeTest02] <--- END HTTP (19-byte body){ name=wade, age=28}
先说明一下,不引入其他依赖,feign不支持表单提交。这里先演示json数据提交
/** * 测试Body:json */@PostMapping("/post/body")public String test03(@RequestBody User user) { return user.toString();}
package study.wyy.feign.model;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONPObject;import lombok.Data;import lombok.ToString;import java.io.Serializable;/** * @author: wyaoyao * @date: 2020-12-17 13:17 * @description: */@Data@ToStringpublic class User implements Serializable { private String name; /** * 年龄 */ private Integer age;}
/** * 测试josn * * @return */@RequestLine("POST /feign/provider/post/body")@Body("{body}")@Headers({ "content-type:application/json"})String invokeTest03(@Param("body") User user);
@Testpublic void test03() { User user = new User(); user.setAge(13); user.setName("Wade"); String response = client.invokeTest03(user); System.out.println(response);}
测试报错
[PostControllerClient#invokeTest03] Content-Length: 23[PostControllerClient#invokeTest03] content-type: application/json[PostControllerClient#invokeTest03] [PostControllerClient#invokeTest03] User(name=Wade, age=13) # 请求数据[PostControllerClient#invokeTest03] ---> END HTTP (23-byte body)[PostControllerClient#invokeTest03] <--- HTTP/1.1 400 (59ms)[PostControllerClient#invokeTest03] connection: close[PostControllerClient#invokeTest03] content-type: application/json[PostControllerClient#invokeTest03] date: Sat, 20 Mar 2021 13:13:37 GMT[PostControllerClient#invokeTest03] transfer-encoding: chunked[PostControllerClient#invokeTest03] [PostControllerClient#invokeTest03] { "timestamp":"2021-03-20T13:13:37.062+0000","status":400,"error":"Bad Request","message":"JSON parse error: Unrecognized token 'User': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'User': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (PushbackInputStream); line: 1, column: 6]","path":"/feign/provider/post/body"}[PostControllerClient#invokeTest03] <--- END HTTP (495-byte body)feign.FeignException$BadRequest: status 400 reading PostControllerClient#invokeTest03(User)
报了400的错误,JSON parse error;
日志中打印的请求数据是:User(name=Wade, age=13),默认调用的是User的toString方法,但是发现这样数据就不是个json数据了
既然知道了原因了,最简单的解决方法就是重写user的toString方法,返回json格式的数据
@Overridepublic String toString() { String s = JSON.toJSONString(this); return s;}
再测试,发现没有问题:
[PostControllerClient#invokeTest03] ---> POST http://localhost:8001/feign/provider/post/body HTTP/1.1[PostControllerClient#invokeTest03] Content-Length: 24[PostControllerClient#invokeTest03] content-type: application/json[PostControllerClient#invokeTest03] [PostControllerClient#invokeTest03] { "age":13,"name":"Wade"} # 此时请求数据就是json格式数据[PostControllerClient#invokeTest03] ---> END HTTP (24-byte body)[PostControllerClient#invokeTest03] <--- HTTP/1.1 200 (37ms)[PostControllerClient#invokeTest03] connection: keep-alive[PostControllerClient#invokeTest03] content-length: 23[PostControllerClient#invokeTest03] content-type: text/plain;charset=UTF-8[PostControllerClient#invokeTest03] date: Sat, 20 Mar 2021 13:18:55 GMT[PostControllerClient#invokeTest03] keep-alive: timeout=60[PostControllerClient#invokeTest03] [PostControllerClient#invokeTest03] User(name=Wade, age=13)[PostControllerClient#invokeTest03] <--- END HTTP (23-byte body)User(name=Wade, age=13)
该注解作用于方法上,其定义了一个类似于UriTemplate和HeaderTemplate的Template。其中的表达式也使用了@Param注解中的值进行解析。
Body template遵循以下规则:
无法解析的表达式将会被省略
必须设置Content-Type请求头参数
测试:必须设置Content-Type请求头参数,去掉设置header的代码
@RequestLine("POST /feign/provider/post/body")@Body("{body}")String invokeTest03(@Param("body") User user);
在测试,发现出现415错误
feign.FeignException$UnsupportedMediaType: status 415 reading PostControllerClient#invokeTest03(User)
@Target({ METHOD, TYPE})@Retention(RUNTIME)public @interface Headers { String[] value();}
能标注在类上和方法上。用于传请求头,使用起来比较简单,形如这样即可:
@Headers({ "Accept:*/*", "Accept-Language:zh-cn"})
唯一注意的一点:k-v使用的是冒号连接,而不是=。
@PostMapping("/post/bodyAndUrl")public String test04(@RequestParam Mapmap,@RequestBody User user) { return map.toString();}
@RequestLine("POST /feign/provider/post/bodyAndUrl")@Body("{body}")@Headers({ "content-type:application/json"})String invokeTest04(@QueryMap Mapmap,@Param("body") User user);
@Testpublic void test04() { User user = new User(); user.setAge(13); user.setName("Wade"); Mapmap = new HashMap<>(); map.put("name", "kobe"); map.put("age", 28); String response = client.invokeTest04(map,user); System.out.println(response);}
在服务提供者的controller 中打个断点
当然观察feign的日志输出,也可以看到数据正确封装
[PostControllerClient#invokeTest04] ---> POST http://localhost:8001/feign/provider/post/bodyAndUrl?name=kobe&age=28 HTTP/1.1 # url上正确带有参数[PostControllerClient#invokeTest04] Content-Length: 24[PostControllerClient#invokeTest04] content-type: application/json[PostControllerClient#invokeTest04] [PostControllerClient#invokeTest04] { "age":13,"name":"Wade"} # 请求体中也是带有了json格式的数据[PostControllerClient#invokeTest04] ---> END HTTP (24-byte body)[PostControllerClient#invokeTest04] <--- HTTP/1.1 200 (34ms)[PostControllerClient#invokeTest04] connection: keep-alive[PostControllerClient#invokeTest04] content-length: 19[PostControllerClient#invokeTest04] content-type: text/plain;charset=UTF-8[PostControllerClient#invokeTest04] date: Sat, 20 Mar 2021 13:29:35 GMT[PostControllerClient#invokeTest04] keep-alive: timeout=60[PostControllerClient#invokeTest04] [PostControllerClient#invokeTest04] { name=kobe, age=28}[PostControllerClient#invokeTest04] <--- END HTTP (19-byte body){ name=kobe, age=28}
转载地址:http://oprv.baihongyu.com/