提交 | 用户 | 时间
|
e7c126
|
1 |
package com.iailab.gateway.util; |
H |
2 |
|
|
3 |
import cn.hutool.core.net.NetUtil; |
|
4 |
import cn.hutool.core.util.ArrayUtil; |
|
5 |
import cn.hutool.core.util.NumberUtil; |
|
6 |
import cn.hutool.extra.servlet.ServletUtil; |
|
7 |
import com.iailab.framework.common.util.json.JsonUtils; |
|
8 |
import lombok.extern.slf4j.Slf4j; |
|
9 |
import org.springframework.cloud.gateway.route.Route; |
|
10 |
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; |
|
11 |
import org.springframework.core.io.buffer.DataBufferFactory; |
|
12 |
import org.springframework.http.HttpHeaders; |
|
13 |
import org.springframework.http.MediaType; |
|
14 |
import org.springframework.http.server.reactive.ServerHttpRequest; |
|
15 |
import org.springframework.http.server.reactive.ServerHttpResponse; |
|
16 |
import org.springframework.web.server.ServerWebExchange; |
|
17 |
import reactor.core.publisher.Mono; |
|
18 |
|
|
19 |
/** |
|
20 |
* Web 工具类 |
|
21 |
* |
|
22 |
* copy from iailab-common-web 的 WebFrameworkUtils 类 |
|
23 |
* |
|
24 |
* @author iailab |
|
25 |
*/ |
|
26 |
@Slf4j |
|
27 |
public class WebFrameworkUtils { |
|
28 |
|
|
29 |
private static final String HEADER_TENANT_ID = "tenant-id"; |
|
30 |
|
|
31 |
private WebFrameworkUtils() {} |
|
32 |
|
|
33 |
/** |
|
34 |
* 将 Gateway 请求中的 header,设置到 HttpHeaders 中 |
|
35 |
* |
|
36 |
* @param tenantId 租户编号 |
|
37 |
* @param httpHeaders WebClient 的请求 |
|
38 |
*/ |
|
39 |
public static void setTenantIdHeader(Long tenantId, HttpHeaders httpHeaders) { |
|
40 |
if (tenantId == null) { |
|
41 |
return; |
|
42 |
} |
|
43 |
httpHeaders.set(HEADER_TENANT_ID, String.valueOf(tenantId)); |
|
44 |
} |
|
45 |
|
|
46 |
public static Long getTenantId(ServerWebExchange exchange) { |
|
47 |
String tenantId = exchange.getRequest().getHeaders().getFirst(HEADER_TENANT_ID); |
|
48 |
return NumberUtil.isNumber(tenantId) ? Long.valueOf(tenantId) : null; |
|
49 |
} |
|
50 |
|
|
51 |
/** |
|
52 |
* 返回 JSON 字符串 |
|
53 |
* |
|
54 |
* @param exchange 响应 |
|
55 |
* @param object 对象,会序列化成 JSON 字符串 |
|
56 |
*/ |
|
57 |
@SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码 |
|
58 |
public static Mono<Void> writeJSON(ServerWebExchange exchange, Object object) { |
|
59 |
// 设置 header |
|
60 |
ServerHttpResponse response = exchange.getResponse(); |
|
61 |
response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8); |
|
62 |
// 设置 body |
|
63 |
return response.writeWith(Mono.fromSupplier(() -> { |
|
64 |
DataBufferFactory bufferFactory = response.bufferFactory(); |
|
65 |
try { |
|
66 |
return bufferFactory.wrap(JsonUtils.toJsonByte(object)); |
|
67 |
} catch (Exception ex) { |
|
68 |
ServerHttpRequest request = exchange.getRequest(); |
|
69 |
log.error("[writeJSON][uri({}/{}) 发生异常]", request.getURI(), request.getMethod(), ex); |
|
70 |
return bufferFactory.wrap(new byte[0]); |
|
71 |
} |
|
72 |
})); |
|
73 |
} |
|
74 |
|
|
75 |
/** |
|
76 |
* 获得客户端 IP |
|
77 |
* |
|
78 |
* 参考 {@link ServletUtil} 的 getClientIP 方法 |
|
79 |
* |
|
80 |
* @param exchange 请求 |
|
81 |
* @param otherHeaderNames 其它 header 名字的数组 |
|
82 |
* @return 客户端 IP |
|
83 |
*/ |
|
84 |
public static String getClientIP(ServerWebExchange exchange, String... otherHeaderNames) { |
|
85 |
String[] headers = { "X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR" }; |
|
86 |
if (ArrayUtil.isNotEmpty(otherHeaderNames)) { |
|
87 |
headers = ArrayUtil.addAll(headers, otherHeaderNames); |
|
88 |
} |
|
89 |
// 方式一,通过 header 获取 |
|
90 |
String ip; |
|
91 |
for (String header : headers) { |
|
92 |
ip = exchange.getRequest().getHeaders().getFirst(header); |
|
93 |
if (!NetUtil.isUnknown(ip)) { |
|
94 |
return NetUtil.getMultistageReverseProxyIp(ip); |
|
95 |
} |
|
96 |
} |
|
97 |
|
|
98 |
// 方式二,通过 remoteAddress 获取 |
|
99 |
if (exchange.getRequest().getRemoteAddress() == null) { |
|
100 |
return null; |
|
101 |
} |
|
102 |
ip = exchange.getRequest().getRemoteAddress().getHostString(); |
|
103 |
return NetUtil.getMultistageReverseProxyIp(ip); |
|
104 |
} |
|
105 |
|
|
106 |
/** |
|
107 |
* 获得请求匹配的 Route 路由 |
|
108 |
* |
|
109 |
* @param exchange 请求 |
|
110 |
* @return 路由 |
|
111 |
*/ |
|
112 |
public static Route getGatewayRoute(ServerWebExchange exchange) { |
|
113 |
return exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); |
|
114 |
} |
|
115 |
|
|
116 |
} |