FeignClient和RestFull使用笔记
FeignClient和RestFull使用笔记
简介
这篇文章主要讲解FeignClient解析和RestFull的开发使用和一些简单注意事项。
FeignClient分两种介绍,一个指定请求、一个注册中心寻找;也就是如何动态url和指定url、注册中心寻找
RestFull的几种解读和差异:GetMapping、PostMapping、PutMapping、DeleteMapping、PatchMapping
实践讲解
FeignClient例子
在feiignClient之前,我们来编写如下代码
UserCenterClient 客户端调用类
package com.lgh.client;
import lombok.Data;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import java.net.URI;
@FeignClient(name = "test", url = "EMPTY")
public interface UserCenterClient {
@PostMapping("/feign/{id}/client")
public String client(URI uri, @RequestHeader(value = "token", required = true) String token,
@PathVariable("id") int id,
@RequestBody User user);
@Data
class User {
private String userId;
private String passwd;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
调用方式 TestController
package com.lgh.controller;
import com.lgh.client.UserCenterClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.net.URI;
import java.net.URISyntaxException;
@Api(tags = "测试feignClient")
@RestController
@RequestMapping("/feign")
@Slf4j
public class TestController {
@Autowired
private UserCenterClient userCenterClient;
@ApiOperation("测试springmvc和feignClient")
@PostMapping("/{id}/client")
public String client(@RequestHeader(value = "token", required = true) String token,
@PathVariable("id") int id,
@RequestBody UserCenterClient.User user) throws URISyntaxException {
return userCenterClient
.client(new URI("http://localhost:8080")
, token, id, user);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
上面地址是动态指定url来调用http://localhost:8080
服务类TestController
package com.lgh.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Api(tags = "测试feignClient")
@RestController
@RequestMapping("/feign")
@Slf4j
public class TestController {
@ApiOperation("测试springmvc和feignClient")
@PostMapping("/{id}/client")
public String client(@RequestHeader(value = "token", required = true) String token,
@PathVariable("id") int id, @RequestBody User user) {
log.info("token={},id={},user={}", token, id, user.toString());
return "OK";
}
@Data
class User {
private String userId;
private String passwd;
@Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", passwd='" + passwd + '\'' +
'}';
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
通过如上例子可以动态指定url调用服务器的地址,只要参数中存在URI即可。具体实现都在代理类中解析,分四步
feign.ReflectiveFeign#newInstance解析FeignClient
feign.Contract.BaseContract#parseAndValidateMetadata解析元数据
feign.Contract.BaseContract#parseAndValidateMetadata(java.lang.Class<?>, java.lang.reflect.Method) 解析对参数判断,设置urlIndex的值寻找target目标,如下代码
protected MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
// ……
if (parameterTypes[i] == URI.class) {
data.urlIndex(i);
}
}else if (!isHttpAnnotation && parameterTypes[i] != Request.Options.class) {
//……
}
//……
1
2
3
4
5
6
7
8
9
feign.ReflectiveFeign.BuildTemplateByResolvingArgs#create构造中判断是否有指定url
public RequestTemplate create(Object[] argv) {
//……
if (metadata.urlIndex() != null) {
int urlIndex = metadata.urlIndex();
checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
mutable.target(String.valueOf(argv[urlIndex]));
}
//……
}
1
2
3
4
5
6
7
8
9
FeignClient解析
FeignClient注解我们比较关注的是几个属性;
value或者name
这里是设置请求的应用,当url和参数的URI未设置时,这里生效即服务注册名称,FeignClient调用时从注册中心寻找轮询。
url
指定url。当参数为存在uri时,此参数生效,即FeignClient请求的目标服务地址
path 这里是请求路径,当方法参数未存在URI时,此路径生效
RestFull用法
其实RestFull每种都有自己特点,主要做的就是规约。也是spring官网对DispatcherServlet的完善补充。具体其实有get和post方法请求即可,但是为了更好归约和编程规范,便出现RestFull概念。
/**
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Sam Brannen
* @since 2.5
* @see GetMapping
* @see PostMapping
* @see PutMapping
* @see DeleteMapping
* @see PatchMapping
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
//…………
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GetMapping
从服务器获取参数时,使用get请求类型,这里获取参数不能通过RequestBody设置,因为参数在request的Param中。也就是会限制路径长度,使用时要预估参数是否超限。
PostMapping
上送提交参数,是一次性上送全部参数时使用,和PatchMapping相对应,因为PatchMapping也就是部分提交不具备幂等性,PostMapping全量表单提交,具备幂等性,这里是以post请求方式提交,是流时传输,一般来说不限制大小。
PutMapping
更新数据,也就是需要更新记录时使用此方法
DeleteMapping
删除数据,删除服务器数据时使用此方式
PatchMapping
部分更新数据,不具备幂等性是PostMapping的扩展
总结
1)FeignClient中如果要动态请求URL,则可以在方法入参中传入URI
2)FeignClient如果要设置指定的URL可以设置FeignClient属性URL
3)RestFull使用特性每种方法均有意义。get请求无法通过@RequestBody获取参数值,可通过@RequestParam指定参数值
4)PATCH和PUT方法的区别,两种均是更新操作。PUT全量,PATCH部分。PUT具备幂等意义,PATCH不具备。
————————————————
版权声明:本文为CSDN博主「soft_z1302」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/soft_z1302/article/details/114750038