Java Code Examples for org.springframework.web.server.ServerWebExchange#getRequest()

The following examples show how to use org.springframework.web.server.ServerWebExchange#getRequest() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CorsConfig.java    From microservice-recruit with Apache License 2.0 6 votes vote down vote up
@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);
    };
}
 
Example 2
Source File: CorsConfig.java    From spring-microservice-exam with MIT License 6 votes vote down vote up
@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);
    };
}
 
Example 3
Source File: HttpsToHttpFilter.java    From spring-microservice-exam with MIT License 6 votes vote down vote up
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    URI originalUri = exchange.getRequest().getURI();
    ServerHttpRequest request = exchange.getRequest();
    ServerHttpRequest.Builder mutate = request.mutate();
    String forwardedUri = request.getURI().toString();
    if (forwardedUri != null && forwardedUri.startsWith("https")) {
        try {
            URI mutatedUri = new URI("http",
                    originalUri.getUserInfo(),
                    originalUri.getHost(),
                    originalUri.getPort(),
                    originalUri.getPath(),
                    originalUri.getQuery(),
                    originalUri.getFragment());
            mutate.uri(mutatedUri);
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }
    ServerHttpRequest build = mutate.build();
    return chain.filter(exchange.mutate().request(build).build());
}
 
Example 4
Source File: ModifyRequestBodyGatewayFilterFactory.java    From spring-cloud-gateway with Apache License 2.0 6 votes vote down vote up
ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers,
		CachedBodyOutputMessage outputMessage) {
	return new ServerHttpRequestDecorator(exchange.getRequest()) {
		@Override
		public HttpHeaders getHeaders() {
			long contentLength = headers.getContentLength();
			HttpHeaders httpHeaders = new HttpHeaders();
			httpHeaders.putAll(headers);
			if (contentLength > 0) {
				httpHeaders.setContentLength(contentLength);
			}
			else {
				// TODO: this causes a 'HTTP/1.1 411 Length Required' // on
				// httpbin.org
				httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
			}
			return httpHeaders;
		}

		@Override
		public Flux<DataBuffer> getBody() {
			return outputMessage.getBody();
		}
	};
}
 
Example 5
Source File: GatewayApplication.java    From MyShopPlus with Apache License 2.0 6 votes vote down vote up
@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);
    };
}
 
Example 6
Source File: ConsumesRequestCondition.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * Checks if any of the contained media type expressions match the given
 * request 'Content-Type' header and returns an instance that is guaranteed
 * to contain matching expressions only. The match is performed via
 * {@link MediaType#includes(MediaType)}.
 * @param exchange the current exchange
 * @return the same instance if the condition contains no expressions;
 * or a new condition with matching expressions only;
 * or {@code null} if no expressions match.
 */
@Override
public ConsumesRequestCondition getMatchingCondition(ServerWebExchange exchange) {
	ServerHttpRequest request = exchange.getRequest();
	if (CorsUtils.isPreFlightRequest(request)) {
		return EMPTY_CONDITION;
	}
	if (isEmpty()) {
		return this;
	}
	if (!hasBody(request) && !this.bodyRequired) {
		return EMPTY_CONDITION;
	}
	List<ConsumeMediaTypeExpression> result = getMatchingExpressions(exchange);
	return !CollectionUtils.isEmpty(result) ? new ConsumesRequestCondition(result) : null;
}
 
Example 7
Source File: WebFluxSpanDecorator.java    From java-spring-web with Apache License 2.0 6 votes vote down vote up
@Override
public void onRequest(final ServerWebExchange exchange, final Span span) {
    Tags.COMPONENT.set(span, COMPONENT_NAME);
    final ServerHttpRequest request = exchange.getRequest();
    Tags.HTTP_METHOD.set(span, request.getMethodValue());
    Tags.HTTP_URL.set(span, request.getURI().toString());
    Optional.ofNullable(request.getRemoteAddress()).ifPresent(remoteAddress -> {
        Tags.PEER_HOSTNAME.set(span, remoteAddress.getHostString());
        Tags.PEER_PORT.set(span, remoteAddress.getPort());
        Optional.ofNullable(remoteAddress.getAddress()).ifPresent(
                inetAddress -> {
                    if (inetAddress instanceof Inet6Address) {
                        Tags.PEER_HOST_IPV6.set(span, inetAddress.getHostAddress());
                    } else {
                        Tags.PEER_HOST_IPV4.set(span, inetAddress.getHostAddress());
                    }
                }
        );
    });
}
 
Example 8
Source File: CorsConfig.java    From spring-cloud-sofastack-samples with Apache License 2.0 6 votes vote down vote up
@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);
    };
}
 
Example 9
Source File: AccessGatewayFilter.java    From SpringCloud with Apache License 2.0 6 votes vote down vote up
/**
 * 1.首先网关检查token是否有效,无效直接返回401,不调用签权服务
 * 2.调用签权服务器看是否对该请求有权限,有权限进入下一个filter,没有权限返回401
 *
 * @param exchange
 * @param chain
 * @return
 */
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    String authentication = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
    String method = request.getMethodValue();
    String url = request.getPath().value();
    log.debug("url:{},method:{},headers:{}", url, method, request.getHeaders());
    //不需要网关签权的url
    if (authService.ignoreAuthentication(url)) {
        return chain.filter(exchange);
    }

    //调用签权服务看用户是否有权限,若有权限进入下一个filter
    if (permissionService.permission(authentication, url, method)) {
        ServerHttpRequest.Builder builder = request.mutate();
        //TODO 转发的请求都加上服务间认证token
        builder.header(X_CLIENT_TOKEN, "TODO zhoutaoo添加服务间简单认证");
        //将jwt token中的用户信息传给服务
        builder.header(X_CLIENT_TOKEN_USER, getUserToken(authentication));
        return chain.filter(exchange.mutate().request(builder.build()).build());
    }
    return unauthorized(exchange);
}
 
Example 10
Source File: RouteEnhanceServiceImpl.java    From FEBS-Cloud with Apache License 2.0 6 votes vote down vote up
@Override
public void saveRequestLogs(ServerWebExchange exchange) {
    URI originUri = getGatewayOriginalRequestUrl(exchange);
    // /auth/user为令牌校验请求,是系统自发行为,非用户请求,故不记录
    if (!StringUtils.equalsIgnoreCase(TOKEN_CHECK_URL, originUri.getPath())) {
        URI url = getGatewayRequestUrl(exchange);
        Route route = getGatewayRoute(exchange);
        ServerHttpRequest request = exchange.getRequest();
        String ipAddress = FebsUtil.getServerHttpRequestIpAddress(request);
        if (url != null && route != null) {
            RouteLog routeLog = RouteLog.builder()
                    .ip(ipAddress)
                    .requestUri(originUri.getPath())
                    .targetServer(route.getId())
                    .targetUri(url.getPath())
                    .requestMethod(request.getMethodValue())
                    .location(AddressUtil.getCityInfo(ipAddress))
                    .build();
            routeLogService.create(routeLog).subscribe();
        }
    }
}
 
Example 11
Source File: JsonExceptionHandler.java    From open-cloud with MIT License 5 votes vote down vote up
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
    /**
     * 按照异常类型进行处理
     */
    ResultBody resultBody;
    ServerHttpRequest request = exchange.getRequest();
    if("/favicon.ico".equals(exchange.getRequest().getURI().getPath())){
        return Mono.empty();
    }
    if (ex instanceof NotFoundException) {
        resultBody = ResultBody.failed().code(ErrorCode.SERVICE_UNAVAILABLE.getCode()).msg(ErrorCode.SERVICE_UNAVAILABLE.getMessage()).httpStatus(HttpStatus.SERVICE_UNAVAILABLE.value()).path(request.getURI().getPath());
        log.error("==> 错误解析:{}", resultBody);
    } else {
        resultBody = OpenGlobalExceptionHandler.resolveException((Exception) ex, exchange.getRequest().getURI().getPath());
    }
    /**
     * 参考AbstractErrorWebExceptionHandler
     */
    if (exchange.getResponse().isCommitted()) {
        return Mono.error(ex);
    }
    exceptionHandlerResult.set(resultBody);
    ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
    return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
            .switchIfEmpty(Mono.error(ex))
            .flatMap((handler) -> handler.handle(newRequest))
            .flatMap((response) -> {
                return write(exchange, response,ex);
            });
}
 
Example 12
Source File: TokenFilter.java    From codeway_service with GNU General Public License v3.0 5 votes vote down vote up
/**
 * 获取token字段,如果能获取到就 pass,获取不到就直接返回401错误,
 * chain.filter(exchange)之前的就是 “pre” 部分,之后的也就是then里边的是 “post” 部分
 * @param exchange
 * @param chain
 * @return
 */
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

	ServerHttpRequest request = exchange.getRequest();
	String authentication = request.getHeaders().getFirst("AUTH");
	String method = request.getMethodValue();
	String url = request.getPath().value();
	LogBack.info("url:{},method:{},headers:{}", url, method, request.getHeaders());
	//不需要网关签权的url
	if (authService.ignoreAuthentication(url) || StringUtils.startsWith(url, "/api")) {
		return chain.filter(exchange);
	}
	// 如果请求未携带token信息, 直接跳出
	if (StringUtils.isBlank(authentication) || !authentication.contains(BEARER)) {
		LogBack.error("url:{},method:{},headers:{}, 请求未携带token信息", url, method, request.getHeaders());
		return unAuthorized(exchange, StatusEnum.PARAM_ILLEGAL);
	}

	long expire = authService.getExpire(authentication);
	// 过期
	if(expire<0){
		return unAuthorized(exchange,StatusEnum.LOGIN_EXPIRED);
	}

	AuthToken authToken = authService.getAuthToken(authentication);
	String jwtToken = authToken.getAccess_token();
	//调用签权服务看用户是否有权限,若有权限进入下一个filter
	if (authService.commonAuthentication(url) || authService.hasPermission(jwtToken, url, method) ) {
		ServerHttpRequest.Builder builder = request.mutate();
		builder.header(X_CLIENT_TOKEN, "TODO 添加服务间简单认证");//TODO 转发的请求都加上服务间认证token
		//将jwt token中的用户信息传给服务
		builder.header(X_CLIENT_TOKEN_USER, authService.getJwt(jwtToken).getClaims());
		builder.header(HttpHeaders.AUTHORIZATION,BEARER+jwtToken);
		return chain.filter(exchange.mutate().request(builder.build()).build());
	}
	return unAuthorized(exchange,StatusEnum.UN_AUTHORIZED);
}
 
Example 13
Source File: PrefixPathGatewayFilterFactory.java    From spring-cloud-gateway with Apache License 2.0 5 votes vote down vote up
@Override
public GatewayFilter apply(Config config) {
	return new GatewayFilter() {
		@Override
		public Mono<Void> filter(ServerWebExchange exchange,
				GatewayFilterChain chain) {
			boolean alreadyPrefixed = exchange
					.getAttributeOrDefault(GATEWAY_ALREADY_PREFIXED_ATTR, false);
			if (alreadyPrefixed) {
				return chain.filter(exchange);
			}
			exchange.getAttributes().put(GATEWAY_ALREADY_PREFIXED_ATTR, true);

			ServerHttpRequest req = exchange.getRequest();
			addOriginalRequestUrl(exchange, req.getURI());
			String newPath = config.prefix + req.getURI().getRawPath();

			ServerHttpRequest request = req.mutate().path(newPath).build();

			exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());

			if (log.isTraceEnabled()) {
				log.trace("Prefixed URI with: " + config.prefix + " -> "
						+ request.getURI());
			}

			return chain.filter(exchange.mutate().request(request).build());
		}

		@Override
		public String toString() {
			return filterToStringCreator(PrefixPathGatewayFilterFactory.this)
					.append("prefix", config.getPrefix()).toString();
		}
	};
}
 
Example 14
Source File: DefaultCorsProcessor.java    From java-technology-stack with MIT License 5 votes vote down vote up
@Override
public boolean process(@Nullable CorsConfiguration config, ServerWebExchange exchange) {

	ServerHttpRequest request = exchange.getRequest();
	ServerHttpResponse response = exchange.getResponse();

	if (!CorsUtils.isCorsRequest(request)) {
		return true;
	}

	if (responseHasCors(response)) {
		logger.trace("Skip: response already contains \"Access-Control-Allow-Origin\"");
		return true;
	}

	if (CorsUtils.isSameOrigin(request)) {
		logger.trace("Skip: request is from same origin");
		return true;
	}

	boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
	if (config == null) {
		if (preFlightRequest) {
			rejectRequest(response);
			return false;
		}
		else {
			return true;
		}
	}

	return handleInternal(exchange, config, preFlightRequest);
}
 
Example 15
Source File: TomcatRequestUpgradeStrategy.java    From spring-analysis-note with MIT License 5 votes vote down vote up
@Override
public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
		@Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory){

	ServerHttpRequest request = exchange.getRequest();
	ServerHttpResponse response = exchange.getResponse();

	HttpServletRequest servletRequest = getHttpServletRequest(request);
	HttpServletResponse servletResponse = getHttpServletResponse(response);

	HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
	DataBufferFactory bufferFactory = response.bufferFactory();

	Endpoint endpoint = new StandardWebSocketHandlerAdapter(
			handler, session -> new TomcatWebSocketSession(session, handshakeInfo, bufferFactory));

	String requestURI = servletRequest.getRequestURI();
	DefaultServerEndpointConfig config = new DefaultServerEndpointConfig(requestURI, endpoint);
	config.setSubprotocols(subProtocol != null ?
			Collections.singletonList(subProtocol) : Collections.emptyList());

	try {
		WsServerContainer container = getContainer(servletRequest);
		container.doUpgrade(servletRequest, servletResponse, config, Collections.emptyMap());
	}
	catch (ServletException | IOException ex) {
		return Mono.error(ex);
	}

	return Mono.empty();
}
 
Example 16
Source File: IndexRewriteFilter.java    From tutorials with MIT License 5 votes vote down vote up
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
    ServerHttpRequest request = serverWebExchange.getRequest();
    if (request.getURI()
        .getPath()
        .equals("/")) {
        return webFilterChain.filter(serverWebExchange.mutate()
            .request(builder -> builder.method(request.getMethod())
                .contextPath(request.getPath()
                    .toString())
                .path("/test"))
            .build());
    }
    return webFilterChain.filter(serverWebExchange);
}
 
Example 17
Source File: PathMatcherServerWebExchangeMatcher.java    From spring-security-reactive with Apache License 2.0 5 votes vote down vote up
@Override
public MatchResult matches(ServerWebExchange exchange) {
	ServerHttpRequest request = exchange.getRequest();
	if(this.method != null && !this.method.equals(request.getMethod())) {
		return MatchResult.notMatch();
	}
	String path = helper.getLookupPathForRequest(exchange);
	boolean match = pathMatcher.match(pattern, path);
	if(!match) {
		return MatchResult.notMatch();
	}
	Map<String,String> pathVariables = pathMatcher.extractUriTemplateVariables(pattern, path);
	Map<String,Object> variables = new HashMap<>(pathVariables);
	return MatchResult.match(variables);
}
 
Example 18
Source File: GatewayExceptionHandler.java    From spring-microservice-exam with MIT License 4 votes vote down vote up
/**
   * 处理逻辑
   *
   * @param exchange exchange
   * @param ex       ex
   * @return Mono
   */
  @Override
  public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
      String msg = "Internal Server Error";
      // 返回给前端用的状态码
      int keyCode = ApiMsg.KEY_UNKNOWN;
      int msgCode = ApiMsg.ERROR;
      if (ex instanceof NotFoundException) {
      	// 服务不可用
	keyCode = ApiMsg.KEY_SERVICE;
	msgCode = ApiMsg.UNAVAILABLE;
      } else if (ex instanceof ResponseStatusException) {
          ResponseStatusException responseStatusException = (ResponseStatusException) ex;
          msg = responseStatusException.getMessage();
	// 服务响应错误
	keyCode = ApiMsg.KEY_SERVICE;
	msgCode = ApiMsg.ERROR;
      } else if (ex instanceof InvalidValidateCodeException) {
          msg = ex.getMessage();
          // 验证码错误
	keyCode = ApiMsg.KEY_VALIDATE_CODE;
} else if (ex instanceof ValidateCodeExpiredException) {
          msg = ex.getMessage();
          // 验证码过期
	keyCode = ApiMsg.KEY_VALIDATE_CODE;
	msgCode = ApiMsg.EXPIRED;
      } else if (ex instanceof InvalidAccessTokenException) {
          msg = ex.getMessage();
          // token非法
	keyCode = ApiMsg.KEY_TOKEN;
	msgCode = ApiMsg.INVALID;
      }
      // 封装响应体
      ResponseBean<String> responseBean = new ResponseBean<>(msg, keyCode, msgCode);
      // 错误记录
      ServerHttpRequest request = exchange.getRequest();
      log.error("GatewayExceptionHandler: {}, error: {}", request.getPath(), ex.getMessage());
      if (exchange.getResponse().isCommitted())
          return Mono.error(ex);
      exceptionHandlerResult.set(responseBean);
      ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
      return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
              .switchIfEmpty(Mono.error(ex))
              .flatMap((handler) -> handler.handle(newRequest))
              .flatMap((response) -> write(exchange, response));
  }
 
Example 19
Source File: AbstractMessageReaderArgumentResolver.java    From java-technology-stack with MIT License 4 votes vote down vote up
/**
 * 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));
}
 
Example 20
Source File: ExceptionHandle.java    From microservice-recruit with Apache License 2.0 4 votes vote down vote up
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
    /**
     * 按照异常类型进行处理
     */
    HttpStatus httpStatus;
    String body;
    if (ex instanceof MyException) {
        httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
        body = JSONObject.toJSONString(ResponseMessage.error(((MyException) ex).getCode(), ex.getMessage()));
    } else if (ex instanceof NotFoundException) {
        httpStatus = HttpStatus.NOT_FOUND;
        body = JSONObject.toJSONString(ResponseMessage.error(404, ex.getMessage()));
    } else if (ex instanceof ResponseStatusException) {
        ResponseStatusException responseStatusException = (ResponseStatusException) ex;
        httpStatus = responseStatusException.getStatus();
        body = JSONObject.toJSONString(ResponseMessage.error(500, ex.getMessage()));
    } else {
        httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
        body = JSONObject.toJSONString(ResponseMessage.error(500, ex.getMessage()));
    }
    /**
     * 封装响应体,此body可修改为自己的jsonBody
     */
    Map<String, Object> result = new HashMap<>(2, 1);
    result.put("httpStatus", httpStatus);
    result.put("body", body);
    /**
     * 错误记录
     */
    ServerHttpRequest request = exchange.getRequest();
    log.error("[全局异常处理]异常请求路径:{},记录异常信息:{}", request.getPath().pathWithinApplication().value(), ex.getMessage());
    ex.printStackTrace();
    /**
     * 参考AbstractErrorWebExceptionHandler
     */
    if (exchange.getResponse().isCommitted()) {
        return Mono.error(ex);
    }
    exceptionHandlerResult.set(result);
    ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
    return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
            .switchIfEmpty(Mono.error(ex))
            .flatMap((handler) -> handler.handle(newRequest))
            .flatMap((response) -> write(exchange, response));

}