下面列出了org.springframework.http.server.reactive.ServerHttpRequest#getHeaders ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@GetMapping(FLUX_ENDPOINT_PATH)
@ResponseBody
Flux<String> fluxEndpoint(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
if ("true".equals(headers.getFirst("throw-exception"))) {
throw new ApiException(ERROR_THROWN_IN_FLUX_ENDPOINT);
}
if ("true".equals(headers.getFirst("return-exception-in-flux"))) {
return Flux.error(
new ApiException(ERROR_RETURNED_IN_FLUX_ENDPOINT_FLUX)
);
}
return Flux.fromIterable(FLUX_RESPONSE_PAYLOAD);
}
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (!CorsUtils.isCorsRequest(request)) {
return chain.filter(ctx);
}
HttpHeaders requestHeaders = request.getHeaders();
ServerHttpResponse response = ctx.getResponse();
HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
if (requestMethod != null) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
}
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL);
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
return chain.filter(ctx);
};
}
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
HttpHeaders requestHeaders = request.getHeaders();
ServerHttpResponse response = ctx.getResponse();
HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
if (requestMethod != null) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
}
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain){
ServerHttpRequest request = exchange.getRequest();
GatewayContext gatewayContext = new GatewayContext();
HttpHeaders headers = request.getHeaders();
gatewayContext.setRequestHeaders(headers);
gatewayContext.getAllRequestData().addAll(request.getQueryParams());
/*
* save gateway context into exchange
*/
exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT,gatewayContext);
MediaType contentType = headers.getContentType();
if(headers.getContentLength()>0){
if(MediaType.APPLICATION_JSON.equals(contentType) || MediaType.APPLICATION_JSON_UTF8.equals(contentType)){
return readBody(exchange, chain,gatewayContext);
}
if(MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)){
return readFormData(exchange, chain,gatewayContext);
}
}
log.debug("[GatewayContext]ContentType:{},Gateway context is set with {}",contentType, gatewayContext);
return chain.filter(exchange);
}
@Override
protected Mono<Boolean> doFilter(final ServerWebExchange exchange, final WebFilterChain chain) {
final ServerHttpRequest request = exchange.getRequest();
final HttpHeaders headers = request.getHeaders();
final String upgrade = headers.getFirst("Upgrade");
if (StringUtils.isNoneBlank(upgrade) && RpcTypeEnum.WEB_SOCKET.getName().equals(upgrade)) {
return Mono.just(verify(request.getQueryParams()));
}
return Mono.just(true);
}
/**
* 请求信息日志过滤器
*
* @param exchange ServerWebExchange
* @param chain GatewayFilterChain
* @return Mono
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
HttpMethod method = request.getMethod();
RequestPath path = request.getPath();
String source = getIp(headers);
if (source == null || source.isEmpty()) {
source = request.getRemoteAddress().getAddress().getHostAddress();
}
String requestId = Util.uuid();
String fingerprint = Util.md5(source + headers.getFirst("user-agent"));
LogDto log = new LogDto();
log.setRequestId(requestId);
log.setSource(source);
log.setMethod(method.name());
log.setUrl(path.value());
log.setHeaders(headers.toSingleValueMap());
request.mutate().header("requestId", requestId).build();
request.mutate().header("fingerprint", fingerprint).build();
// 读取请求参数
MultiValueMap<String, String> params = request.getQueryParams();
log.setParams(params.isEmpty() ? null : params.toSingleValueMap());
// 如请求方法为GET或Body为空或Body不是Json,则打印日志后结束
long length = headers.getContentLength();
MediaType contentType = headers.getContentType();
if (length <= 0 || !contentType.equalsTypeAndSubtype(MediaType.APPLICATION_JSON)) {
logger.info("请求参数: {}", log.toString());
return chain.filter(exchange);
}
return readBody(exchange, chain, log);
}
/**
* attention:简单跨域就是GET,HEAD和POST请求,但是POST请求的"Content-Type"只能是application/x-www-form-urlencoded, multipart/form-data 或 text/plain
* 反之,就是非简单跨域,此跨域有一个预检机制,说直白点,就是会发两次请求,一次OPTIONS请求,一次真正的请求
*/
@Bean
public WebFilter corsFilter() {
return (ctx, chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (!CorsUtils.isCorsRequest(request)) {
return chain.filter(ctx);
}
HttpHeaders requestHeaders = request.getHeaders();
ServerHttpResponse response = ctx.getResponse();
HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
if (requestMethod != null) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
}
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL);
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
return chain.filter(ctx);
};
}
@Override
public Mono<Void> handleRequest(ServerWebExchange exchange, WebSocketHandler handler) {
ServerHttpRequest request = exchange.getRequest();
HttpMethod method = request.getMethod();
HttpHeaders headers = request.getHeaders();
if (HttpMethod.GET != method) {
return Mono.error(new MethodNotAllowedException(
request.getMethodValue(), Collections.singleton(HttpMethod.GET)));
}
if (!"WebSocket".equalsIgnoreCase(headers.getUpgrade())) {
return handleBadRequest(exchange, "Invalid 'Upgrade' header: " + headers);
}
List<String> connectionValue = headers.getConnection();
if (!connectionValue.contains("Upgrade") && !connectionValue.contains("upgrade")) {
return handleBadRequest(exchange, "Invalid 'Connection' header: " + headers);
}
String key = headers.getFirst(SEC_WEBSOCKET_KEY);
if (key == null) {
return handleBadRequest(exchange, "Missing \"Sec-WebSocket-Key\" header");
}
String protocol = selectProtocol(headers, handler);
return initAttributes(exchange).flatMap(attributes ->
this.upgradeStrategy.upgrade(exchange, handler, protocol,
() -> createHandshakeInfo(exchange, request, protocol, attributes))
);
}
/**
* Whether the request has any Forwarded headers.
* @param request the request
*/
protected boolean hasForwardedHeaders(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
for (String headerName : FORWARDED_HEADER_NAMES) {
if (headers.containsKey(headerName)) {
return true;
}
}
return false;
}
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
HttpHeaders requestHeaders = request.getHeaders();
ServerHttpResponse response = ctx.getResponse();
HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
requestHeaders.getAccessControlRequestHeaders());
if (requestMethod != null) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
}
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
@Override
public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
final ServerHttpRequest request = exchange.getRequest();
final HttpHeaders headers = request.getHeaders();
final String upgrade = headers.getFirst("Upgrade");
SoulContext soulContext;
if (StringUtils.isBlank(upgrade) || !"websocket".equals(upgrade)) {
soulContext = builder.build(exchange);
} else {
final MultiValueMap<String, String> queryParams = request.getQueryParams();
soulContext = transformMap(queryParams);
}
exchange.getAttributes().put(Constants.CONTEXT, soulContext);
return chain.execute(exchange);
}
@Override
public void onRequest(final ServerWebExchange exchange, final Span span) {
final ServerHttpRequest request = exchange.getRequest();
final HttpHeaders headers = request.getHeaders();
Optional.ofNullable(headers.getFirst("Prefer"))
.ifPresent(prefer -> span.setTag(PREFER, prefer));
}
@Override
public void onRequest(final ServerWebExchange exchange, final Span span) {
final ServerHttpRequest request = exchange.getRequest();
final HttpHeaders headers = request.getHeaders();
Stream.of("HTTP-Method-Override", "X-HTTP-Method-Override")
.map(headers::getFirst)
.filter(Objects::nonNull)
.findFirst()
.ifPresent(override ->
span.setTag(HTTP_METHOD_OVERRIDE, override));
}
@Override
public Mono<Void> handleRequest(ServerWebExchange exchange, WebSocketHandler handler) {
ServerHttpRequest request = exchange.getRequest();
HttpMethod method = request.getMethod();
HttpHeaders headers = request.getHeaders();
if (HttpMethod.GET != method) {
return Mono.error(new MethodNotAllowedException(
request.getMethodValue(), Collections.singleton(HttpMethod.GET)));
}
if (!"WebSocket".equalsIgnoreCase(headers.getUpgrade())) {
return handleBadRequest(exchange, "Invalid 'Upgrade' header: " + headers);
}
List<String> connectionValue = headers.getConnection();
if (!connectionValue.contains("Upgrade") && !connectionValue.contains("upgrade")) {
return handleBadRequest(exchange, "Invalid 'Connection' header: " + headers);
}
String key = headers.getFirst(SEC_WEBSOCKET_KEY);
if (key == null) {
return handleBadRequest(exchange, "Missing \"Sec-WebSocket-Key\" header");
}
String protocol = selectProtocol(headers, handler);
return initAttributes(exchange).flatMap(attributes ->
this.upgradeStrategy.upgrade(exchange, handler, protocol,
() -> createHandshakeInfo(exchange, request, protocol, attributes))
);
}
/**
* 全局过滤教研token,生产环境可以用数据库
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
String token = headers.getFirst(AUTHORIZE_TOKEN);
String uid = headers.getFirst(AUTHORIZE_UID);
if (token == null) {
token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
}
if (uid == null) {
uid = request.getQueryParams().getFirst(AUTHORIZE_UID);
}
ServerHttpResponse response = exchange.getResponse();
if (StringUtils.isEmpty(token) || StringUtils.isEmpty(uid)) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
String authToken = stringRedisTemplate.opsForValue().get(uid);
if (authToken == null || !authToken.equals(token)) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
return chain.filter(exchange);
}
/**
* Whether the request has any Forwarded headers.
* @param request the request
*/
protected boolean hasForwardedHeaders(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
for (String headerName : FORWARDED_HEADER_NAMES) {
if (headers.containsKey(headerName)) {
return true;
}
}
return false;
}
protected String getHeader(String headerName, ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String token = StrUtil.EMPTY;
if (headers == null || headers.isEmpty()) {
return token;
}
token = headers.getFirst(headerName);
if (StringUtils.isNotBlank(token)) {
return token;
}
return request.getQueryParams().getFirst(headerName);
}
@Override
public GatewayFilter apply(RequestHeaderSizeGatewayFilterFactory.Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
Long headerSizeInBytes = 0L;
for (Map.Entry<String, List<String>> headerEntry : headers.entrySet()) {
List<String> values = headerEntry.getValue();
for (String value : values) {
headerSizeInBytes += Long.valueOf(value.getBytes().length);
}
}
if (headerSizeInBytes > config.getMaxSize().toBytes()) {
exchange.getResponse()
.setStatusCode(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE);
exchange.getResponse().getHeaders().add("errorMessage",
getErrorMessage(headerSizeInBytes, config.getMaxSize()));
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public String toString() {
return filterToStringCreator(RequestHeaderSizeGatewayFilterFactory.this)
.append("max", config.getMaxSize()).toString();
}
};
}
/**
* 身份验证及鉴权过滤器
*
* @param exchange ServerWebExchange
* @param chain GatewayFilterChain
* @return Mono
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpMethod method = request.getMethod();
String path = request.getPath().value();
InterfaceDto config = getConfig(method, path);
if (config == null) {
reply = ReplyHelper.fail("请求的URL不存在");
return initResponse(exchange);
}
// 验证及鉴权
String key = method + ":" + path;
HttpHeaders headers = request.getHeaders();
String fingerprint = headers.getFirst("fingerprint");
Boolean isLogResult = config.getLogResult();
exchange.getAttributes().put("logResult", isLogResult == null ? false : isLogResult);
if (!config.getVerify()) {
return isLimited(config, fingerprint, key) ? initResponse(exchange) : chain.filter(exchange);
}
String token = headers.getFirst("Authorization");
boolean isVerified = verify(token, fingerprint, config.getAuthCode());
if (!isVerified || isLimited(config, fingerprint, key)) {
return initResponse(exchange);
}
// 验证提交数据临时Token
if (config.getNeedToken()) {
String redisKey = "SubmitToken:" + Util.md5(loginInfo.getUserId() + ":" + key);
String submitToken = headers.getFirst("SubmitToken");
String id = Redis.get(redisKey);
if (id == null || id.isEmpty() || !id.equals(submitToken)) {
reply = ReplyHelper.fail("SubmitToken不存在");
return initResponse(exchange);
} else {
Redis.deleteKey(redisKey);
}
}
request.mutate().header("loginInfo", loginInfo.toString()).build();
return chain.filter(exchange);
}
private List<String> getHeadersToUse(ServerHttpRequest request, boolean isPreFlight) {
HttpHeaders headers = request.getHeaders();
return (isPreFlight ? headers.getAccessControlRequestHeaders() : new ArrayList<>(headers.keySet()));
}