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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package cn.ibizlab.util.service;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 自定义feigen客户端配置
*
* @author
*/
@Service
public class RemoteService {
/**
* FeignClientFactoryBean
*/
@Autowired
protected FeignContext feignContext;
/**
* FeignClient 默认LoadBalancerFeignClient
*/
@Autowired
private Client feignClient;
private static final Map<String, Object> FEIGN_CLIENTS = new ConcurrentHashMap<>();
/**
* 定义远程通用接口
*/
public interface RemoteFeignClient {
@RequestMapping(method = RequestMethod.POST, value = "/{path}")
JSONObject post( @PathVariable("path") String path, @RequestHeader("Authorization") String token, @RequestBody Map param);
@RequestMapping(method = RequestMethod.GET, value = "/{path}")
JSONObject request( @PathVariable("path") String path, @RequestHeader("Authorization") String token, Map param);
@RequestMapping(method = RequestMethod.GET, value = "/{path}")
JSONObject get( @PathVariable("path") String path, @RequestHeader("Authorization") String token);
@RequestMapping(method = RequestMethod.PUT, value = "/{path}")
JSONObject put( @PathVariable("path") String path, @RequestHeader("Authorization") String token,@RequestBody Map param);
@RequestMapping(method = RequestMethod.DELETE, value = "/{path}")
JSONObject delete(@PathVariable("path") String path, @RequestHeader("Authorization") String token);
}
/**
* @param serverId
* @return
*/
public RemoteFeignClient getClient(String serverId) {
return this.create(RemoteFeignClient.class, serverId);
}
/**
* 设置编码解码器为FastJson
*
* @param clazz
* @param serviceId
* @param <T>
* @return
*/
private synchronized <T> T create(Class<T> clazz, String serviceId) {
Object object = FEIGN_CLIENTS.get(serviceId);
if (Objects.isNull(object)) {
object = Feign.builder()
//decoder指定对象解码方式
.decoder(this.feignDecoder())
.encoder(this.feignEncoder())
.client(feignClient)
//options方法指定连接超时时长及响应超时时长
.options(new Request.Options(5000, 50000))
//retryer方法指定重试策略
//.retryer(new Retryer.Default(5000, 5000, 3))
.contract(feignContext.getInstance(serviceId, Contract.class))
//target方法绑定接口与服务端地址。返回类型为绑定的接口类型。
.target(clazz, "http://"+serviceId);
FEIGN_CLIENTS.put(serviceId, object);
}
return (T) object;
}
private Decoder feignDecoder() {
return new SpringDecoder(feignHttpMessageConverter());
}
private Encoder feignEncoder() {
return new SpringEncoder(feignHttpMessageConverter());
}
private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(new ObjectMapper());
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jsonConverter);
return () -> httpMessageConverters;
}
}