下面列出了org.springframework.http.server.reactive.ServerHttpRequest#getMethod ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 从ServerHttpRequest 解析请求信息 .
*
* @param httpRequest {@linkplain ServerHttpRequest}
* @return request dto
*/
public static RequestDTO transform(final ServerHttpRequest httpRequest) {
final String path = httpRequest.getPath().value();
Optional<String> module = Arrays.stream(path.split("/")).filter(StringUtils::isNotBlank).findFirst();
final String rpcType = httpRequest.getHeaders().getFirst(GatewayConstant.RPC_TYPE);
final String httpMethod = httpRequest.getMethod() == null ? HttpMethodEnum.POST.getName() : httpRequest.getMethod().name();
RequestDTO request = new RequestDTO();
module.ifPresent(p -> {
request.setModule(p);
String subUrl = path.substring(p.length() + 1);
if (StringUtils.isNotBlank(httpRequest.getURI().getQuery())) {
subUrl += "?" + httpRequest.getURI().getQuery();
}
request.setSubUrl(subUrl);
});
request.setPath(path);
request.setHttpMethod(httpMethod);
request.setRpcType(rpcType);
return request;
}
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain chain) {
ServerHttpRequest request = serverWebExchange.getRequest();
ServerHttpResponse response = serverWebExchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
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(serverWebExchange);
}
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Max-Age", MAX_AGE);
headers.add("Access-Control-Allow-Headers",ALLOWED_HEADERS);
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
@Override
@SuppressWarnings("all")
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Methods", "*");
headers.add("Access-Control-Max-Age", "3600");
headers.add("Access-Control-Allow-Headers", "*");
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(exchange);
}
@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);
};
}
/**
* 跨域配置
*
* @return
*/
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);
};
}
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
headers.add("Access-Control-Allow-Credentials", "true");
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain chain) {
ServerHttpRequest request = serverWebExchange.getRequest();
ServerHttpResponse response = serverWebExchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
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(serverWebExchange);
}
/**
* 请求信息日志过滤器
*
* @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);
}
/**
* 身份验证及鉴权过滤器
*
* @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);
}
/**
* Returns {@code true} if the request is a valid CORS pre-flight one.
*/
public static boolean isPreFlightRequest(ServerHttpRequest request) {
return (request.getMethod() == HttpMethod.OPTIONS && isCorsRequest(request) &&
request.getHeaders().get(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);
}
private String formatRequest(ServerHttpRequest request) {
String rawQuery = request.getURI().getRawQuery();
String query = StringUtils.hasText(rawQuery) ? "?" + rawQuery : "";
return "HTTP " + request.getMethod() + " \"" + request.getPath() + query + "\"";
}
private Object createEntity(@Nullable Object body, Class<?> entityType, ServerHttpRequest request) {
return (RequestEntity.class.equals(entityType) ?
new RequestEntity<>(body, request.getHeaders(), request.getMethod(), request.getURI()) :
new HttpEntity<>(body, request.getHeaders()));
}
@Nullable
private HttpMethod getMethodToUse(ServerHttpRequest request, boolean isPreFlight) {
return (isPreFlight ? request.getHeaders().getAccessControlRequestMethod() : request.getMethod());
}
/**
* Read the body from a method argument with {@link HttpMessageReader}.
* @param bodyParam represents the element type for the body
* @param actualParam the actual method argument type; possibly different
* from {@code bodyParam}, e.g. for an {@code HttpEntity} argument
* @param isBodyRequired true if the body is required
* @param bindingContext the binding context to use
* @param exchange the current exchange
* @return a Mono with the value to use for the method argument
* @since 5.0.2
*/
protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParameter actualParam,
boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) {
ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParam);
ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType);
Class<?> resolvedType = bodyType.resolve();
ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType);
isBodyRequired = isBodyRequired || (adapter != null && !adapter.supportsEmpty());
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
MediaType contentType = request.getHeaders().getContentType();
MediaType mediaType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM);
Object[] hints = extractValidationHints(bodyParam);
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + (contentType != null ?
"Content-Type:" + contentType :
"No Content-Type, using " + MediaType.APPLICATION_OCTET_STREAM));
}
for (HttpMessageReader<?> reader : getMessageReaders()) {
if (reader.canRead(elementType, mediaType)) {
Map<String, Object> readHints = Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix());
if (adapter != null && adapter.isMultiValue()) {
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "0..N [" + elementType + "]");
}
Flux<?> flux = reader.read(actualType, elementType, request, response, readHints);
flux = flux.onErrorResume(ex -> Flux.error(handleReadError(bodyParam, ex)));
if (isBodyRequired) {
flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(bodyParam)));
}
if (hints != null) {
flux = flux.doOnNext(target ->
validate(target, hints, bodyParam, bindingContext, exchange));
}
return Mono.just(adapter.fromPublisher(flux));
}
else {
// Single-value (with or without reactive type wrapper)
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "0..1 [" + elementType + "]");
}
Mono<?> mono = reader.readMono(actualType, elementType, request, response, readHints);
mono = mono.onErrorResume(ex -> Mono.error(handleReadError(bodyParam, ex)));
if (isBodyRequired) {
mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
}
if (hints != null) {
mono = mono.doOnNext(target ->
validate(target, hints, bodyParam, bindingContext, exchange));
}
return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
}
}
}
// No compatible reader but body may be empty..
HttpMethod method = request.getMethod();
if (contentType == null && method != null && SUPPORTED_METHODS.contains(method)) {
Flux<DataBuffer> body = request.getBody().doOnNext(o -> {
// Body not empty, back to 415..
throw new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType);
});
if (isBodyRequired) {
body = body.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
}
return (adapter != null ? Mono.just(adapter.fromPublisher(body)) : Mono.from(body));
}
return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType));
}
@Nullable
private HttpMethod getMethodToUse(ServerHttpRequest request, boolean isPreFlight) {
return (isPreFlight ? request.getHeaders().getAccessControlRequestMethod() : request.getMethod());
}
private ServerHttpResponse prepareResponse(ServerHttpResponse response, ServerHttpRequest request) {
return (request.getMethod() == HttpMethod.HEAD ? new HttpHeadResponseDecorator(response) : response);
}
/**
*
* @param exchange
* @return
*/
@RequestMapping("/**")
public Mono<Void> proxyRequest(ServerWebExchange exchange)
{
ServerHttpRequest frontEndReq = exchange.getRequest();
ServerHttpResponse frontEndResp = exchange.getResponse();
String path = frontEndReq.getPath().pathWithinApplication().value();
HttpMethod httpMethod = frontEndReq.getMethod();
RequestBodySpec reqBodySpec = webClient.method(httpMethod).
uri(backendServiceUrlPrefix.concat(path)).
headers(httpHeaders ->
{
httpHeaders.addAll(frontEndReq.getHeaders());
httpHeaders.remove("HOST");
});
RequestHeadersSpec<?> reqHeadersSpec;
if (requireHttpBody(httpMethod)) {
reqHeadersSpec = reqBodySpec.body(BodyInserters.fromDataBuffers(frontEndReq.getBody()));
} else {
reqHeadersSpec = reqBodySpec;
}
//调用后端服务
return reqHeadersSpec.exchange().timeout(Duration.ofMillis(backendServiceTimeoutInMillis)).
onErrorResume(ex ->
{
//调用后端服务异常(超时、网络问题)时,转发到后端异常-后控制器
//此处也可不用转发,用frontEndResp.writeWith(...)直接将异常响应写回给调用方
Map<String,Object> forwardAttrs = new HashMap<>();
forwardAttrs.put(Constant.BACKEND_EXCEPTION_ATTR_NAME,ex);
return WebfluxForwardingUtil.forward(Constant.BACKEND_EXCEPTION_PATH,exchange,forwardAttrs)
.then(Mono.empty());
}).flatMap(backendResponse ->
{
//将后端服务的响应回写到前端resp
frontEndResp.setStatusCode(backendResponse.statusCode());
frontEndResp.getHeaders().putAll(backendResponse.headers().asHttpHeaders());
return frontEndResp.writeWith(backendResponse.bodyToFlux(DataBuffer.class));
}
);
}
/**
* Returns {@code true} if the request is a valid CORS pre-flight one.
* To be used in combination with {@link #isCorsRequest(ServerHttpRequest)} since
* regular CORS checks are not invoked here for performance reasons.
*/
public static boolean isPreFlightRequest(ServerHttpRequest request) {
return (request.getMethod() == HttpMethod.OPTIONS && request.getHeaders().containsKey(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD));
}