类org.springframework.http.server.reactive.ServerHttpRequest源码实例Demo

下面列出了怎么用org.springframework.http.server.reactive.ServerHttpRequest的API类实例代码及写法,或者点击链接到github查看源代码。

@GetMapping(MONO_ENDPOINT_PATH)
@ResponseBody
Mono<String> monoEndpoint(ServerHttpRequest request) {
    HttpHeaders headers = request.getHeaders();

    if ("true".equals(headers.getFirst("throw-exception"))) {
        throw new ApiException(ERROR_THROWN_IN_MONO_ENDPOINT);
    }

    if ("true".equals(headers.getFirst("return-exception-in-mono"))) {
        return Mono.error(
            new ApiException(ERROR_RETURNED_IN_MONO_ENDPOINT_MONO)
        );
    }

    return Mono.just(MONO_RESPONSE_PAYLOAD);
}
 
@Override
protected Mono<Void> writeToInternal(ServerWebExchange exchange, Context context) {
	return this.inserter.insert(exchange.getResponse(), new BodyInserter.Context() {
		@Override
		public List<HttpMessageWriter<?>> messageWriters() {
			return context.messageWriters();
		}
		@Override
		public Optional<ServerHttpRequest> serverRequest() {
			return Optional.of(exchange.getRequest());
		}
		@Override
		public Map<String, Object> hints() {
			hints.put(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix());
			return hints;
		}
	});
}
 
源代码3 项目: light-security   文件: ReactiveUserOperator.java
/**
 * 从request中获取token
 *
 * @param request request
 * @return token
 */
private String getTokenFromRequest(ServerHttpRequest request) {
    List<String> headers = request.getHeaders()
            .get(ConstantsSecurity.AUTHORIZATION_HEADER);
    if (CollectionUtils.isEmpty(headers)) {
        throw new LightSecurityException("没有找到名为Authorization的header");
    }
    String header = headers.get(0);
    if (!header.startsWith(ConstantsSecurity.BEARER)) {
        throw new LightSecurityException("token必须以'Bearer '开头");
    }
    if (header.length() <= SEVEN) {
        throw new LightSecurityException("token非法,长度 <= 7");
    }

    return header.substring(SEVEN);
}
 
源代码4 项目: spring-analysis-note   文件: CorsUtils.java
/**
 * Check if the request is a same-origin one, based on {@code Origin}, and
 * {@code Host} headers.
 *
 * <p><strong>Note:</strong> as of 5.1 this method ignores
 * {@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the
 * client-originated address. Consider using the {@code ForwardedHeaderFilter}
 * to extract and use, or to discard such headers.
 *
 * @return {@code true} if the request is a same-origin one, {@code false} in case
 * of a cross-origin request
 * @deprecated as of 5.2, same-origin checks are performed directly by {@link #isCorsRequest}
 */
@Deprecated
public static boolean isSameOrigin(ServerHttpRequest request) {
	String origin = request.getHeaders().getOrigin();
	if (origin == null) {
		return true;
	}

	URI uri = request.getURI();
	String actualScheme = uri.getScheme();
	String actualHost = uri.getHost();
	int actualPort = getPort(uri.getScheme(), uri.getPort());
	Assert.notNull(actualScheme, "Actual request scheme must not be null");
	Assert.notNull(actualHost, "Actual request host must not be null");
	Assert.isTrue(actualPort != -1, "Actual request port must not be undefined");

	UriComponents originUrl = UriComponentsBuilder.fromOriginHeader(origin).build();
	return (actualScheme.equals(originUrl.getScheme()) &&
			actualHost.equals(originUrl.getHost()) &&
			actualPort == getPort(originUrl.getScheme(), originUrl.getPort()));
}
 
源代码5 项目: sophia_scaffolding   文件: CorsFilter.java
@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);
}
 
源代码6 项目: spring-analysis-note   文件: CorsUtilsTests.java
@SuppressWarnings("deprecation")
private void testWithForwardedHeader(String serverName, int port,
		String forwardedHeader, String originHeader) {

	String url = "http://" + serverName;
	if (port != -1) {
		url = url + ":" + port;
	}

	MockServerHttpRequest.BaseBuilder<?> builder = get(url)
			.header("Forwarded", forwardedHeader)
			.header(HttpHeaders.ORIGIN, originHeader);

	ServerHttpRequest request = adaptFromForwardedHeaders(builder);
	assertTrue(CorsUtils.isSameOrigin(request));
}
 
@Override
protected Mono<Void> writeToInternal(ServerWebExchange exchange, Context context) {
	return this.inserter.insert(exchange.getResponse(), new BodyInserter.Context() {
		@Override
		public List<HttpMessageWriter<?>> messageWriters() {
			return context.messageWriters();
		}
		@Override
		public Optional<ServerHttpRequest> serverRequest() {
			return Optional.of(exchange.getRequest());
		}
		@Override
		public Map<String, Object> hints() {
			hints.put(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix());
			return hints;
		}
	});
}
 
源代码8 项目: java-spring-web   文件: TracingWebFilter.java
/**
 * It checks whether a request should be traced or not.
 *
 * @return whether request should be traced or not
 */
protected boolean shouldBeTraced(final ServerHttpRequest request) {
    final PathContainer pathWithinApplication = request.getPath().pathWithinApplication();
    // skip URLs matching skip pattern
    // e.g. pattern is defined as '/health|/status' then URL 'http://localhost:5000/context/health' won't be traced
    if (skipPattern != null) {
        final String url = pathWithinApplication.value();
        if (skipPattern.matcher(url).matches()) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Not tracing request " + request + " because it matches skip pattern: " + skipPattern);
            }
            return false;
        }
    }
    if (!urlPatterns.isEmpty() && urlPatterns.stream().noneMatch(urlPattern -> urlPattern.matches(pathWithinApplication))) {
        if (LOG.isTraceEnabled()) {
            LOG.trace("Not tracing request " + request + " because it does not match any URL pattern: " + urlPatterns);
        }
        return false;
    }
    return true;
}
 
源代码9 项目: java-specialagent   文件: TracingWebFilter.java
@Override
public Mono<Void> filter(final ServerWebExchange exchange, final WebFilterChain chain) {
  final ServerHttpRequest request = exchange.getRequest();

  if (!shouldBeTraced(request)) {
    return chain.filter(exchange);
  }

  if (exchange.getAttribute(SERVER_SPAN_CONTEXT) != null) {
    if (LOG.isTraceEnabled()) {
      LOG.trace("Not tracing request " + request + " because it is already being traced");
    }
    return chain.filter(exchange);
  }

  return new TracingOperator(chain.filter(exchange), exchange, tracer, spanDecorators);
}
 
@GetMapping(FLUX_ENDPOINT_PATH)
@ResponseBody
Flux<String> fluxEndpoint(ServerHttpRequest request) {
    HttpHeaders headers = request.getHeaders();

    if ("true".equals(headers.getFirst("throw-exception"))) {
        sleepThread(SLEEP_TIME_MILLIS);
        throw new RuntimeException("Error thrown in fluxEndpoint(), outside Flux");
    }

    if ("true".equals(headers.getFirst("return-exception-in-flux"))) {
        return Flux.just("foo")
                   .delayElements(Duration.ofMillis(SLEEP_TIME_MILLIS))
                   .map(d -> {
                       throw new RuntimeException("Error thrown in fluxEndpoint(), inside Flux");
                   });
    }

    long delayPerElementMillis = SLEEP_TIME_MILLIS / FLUX_ENDPOINT_PAYLOAD.size();
    return Flux.fromIterable(FLUX_ENDPOINT_PAYLOAD).delayElements(Duration.ofMillis(delayPerElementMillis));
}
 
源代码11 项目: Moss   文件: InstancesProxyController.java
@RequestMapping(path = REQUEST_MAPPING_PATH, method = {RequestMethod.GET, RequestMethod.HEAD, RequestMethod.POST, RequestMethod.PUT, RequestMethod.PATCH, RequestMethod.DELETE, RequestMethod.OPTIONS})
public Mono<Void> endpointProxy(@PathVariable("instanceId") String instanceId,
                                ServerHttpRequest request,
                                ServerHttpResponse response) {
    String endpointLocalPath = getEndpointLocalPath(request.getPath().pathWithinApplication().value());
    URI uri = UriComponentsBuilder.fromPath(endpointLocalPath)
                                  .query(request.getURI().getRawQuery())
                                  .build(true)
                                  .toUri();

    return super.forward(instanceId, uri, request.getMethod(), request.getHeaders(),
        () -> BodyInserters.fromDataBuffers(request.getBody())).flatMap(clientResponse -> {
        response.setStatusCode(clientResponse.statusCode());
        response.getHeaders().addAll(filterHeaders(clientResponse.headers().asHttpHeaders()));
        return response.writeAndFlushWith(clientResponse.body(BodyExtractors.toDataBuffers()).window(1));
    });
}
 
@Test
public void resolveParts() {
	ServerHttpRequest request = generateMultipartRequest();
	ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class);
	MultiValueMap<String, Part> parts = this.reader.readMono(elementType, request, emptyMap()).block();
	assertEquals(2, parts.size());

	assertTrue(parts.containsKey("fooPart"));
	Part part = parts.getFirst("fooPart");
	assertTrue(part instanceof FilePart);
	assertEquals("fooPart", part.name());
	assertEquals("foo.txt", ((FilePart) part).filename());
	DataBuffer buffer = DataBufferUtils.join(part.content()).block();
	assertEquals(12, buffer.readableByteCount());
	byte[] byteContent = new byte[12];
	buffer.read(byteContent);
	assertEquals("Lorem Ipsum.", new String(byteContent));

	assertTrue(parts.containsKey("barPart"));
	part = parts.getFirst("barPart");
	assertTrue(part instanceof FormFieldPart);
	assertEquals("barPart", part.name());
	assertEquals("bar", ((FormFieldPart) part).value());
}
 
源代码13 项目: soul   文件: CrossFilter.java
@Override
@SuppressWarnings("all")
public Mono<Void> filter(final ServerWebExchange exchange, final WebFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    if (CorsUtils.isCorsRequest(request)) {
        ServerHttpResponse response = exchange.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);
        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(exchange);
}
 
源代码14 项目: smaker   文件: PasswordDecoderFilter.java
@Override
public GatewayFilter apply(Object config) {
	return (exchange, chain) -> {
		ServerHttpRequest request = exchange.getRequest();

		// 不是登录请求,直接向下执行
		if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
			return chain.filter(exchange);
		}

		URI uri = exchange.getRequest().getURI();
		String queryParam = uri.getRawQuery();
		Map<String, String> paramMap = HttpUtil.decodeParamMap(queryParam, CharsetUtil.UTF_8);

		String password = paramMap.get(PASSWORD);
		if (StrUtil.isNotBlank(password)) {
			try {
				password = decryptAES(password, encodeKey);
			} catch (Exception e) {
				log.error("密码解密失败:{}", password);
				return Mono.error(e);
			}
			paramMap.put(PASSWORD, password.trim());
		}

		URI newUri = UriComponentsBuilder.fromUri(uri)
			.replaceQuery(HttpUtil.toParams(paramMap))
			.build(true)
			.toUri();

		ServerHttpRequest newRequest = exchange.getRequest().mutate().uri(newUri).build();
		return chain.filter(exchange.mutate().request(newRequest).build());
	};
}
 
源代码15 项目: zuihou-admin-cloud   文件: AccessFilter.java
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {
    if (ObjectUtil.isEmpty(value)) {
        return;
    }
    String valueStr = value.toString();
    String valueEncode = URLUtil.encode(valueStr);
    mutate.header(name, valueEncode);
}
 
@Test // SPR-17525
public void shouldNotDoubleEncode() throws Exception {
	HttpHeaders headers = new HttpHeaders();
	headers.add("Forwarded", "host=84.198.58.199;proto=https");

	ServerHttpRequest request = MockServerHttpRequest
			.method(HttpMethod.GET, new URI("https://example.com/a%20b?q=a%2Bb"))
			.headers(headers)
			.build();

	request = this.requestMutator.apply(request);

	assertEquals(new URI("https://84.198.58.199/a%20b?q=a%2Bb"), request.getURI());
	assertForwardedHeadersRemoved(request);
}
 
private HttpErrorInfo createHttpErrorInfo(HttpStatus httpStatus, ServerHttpRequest request, Exception ex) {
    final String path = request.getPath().pathWithinApplication().value();
    final String message = ex.getMessage();

    LOG.debug("Returning HTTP status: {} for path: {}, message: {}", httpStatus, path, message);
    return new HttpErrorInfo(httpStatus, path, message);
}
 
public ServerHttpRequest doFilter(ServerHttpRequest request) {
    ServerHttpRequest req = request;

    String authorization = request.getHeaders().getFirst("Authorization");
    String requestURI = request.getURI().getPath();
    // test if request url is permit all , then remove authorization from header
    LOGGER.info(String.format("Enhance request URI : %s.", requestURI));

    if (StringUtils.isNotEmpty(authorization)) {
        if (isJwtBearerToken(authorization)) {
            try {
                authorization = StringUtils.substringBetween(authorization, ".");
                String decoded = new String(Base64.decodeBase64(authorization));

                Map properties = new ObjectMapper().readValue(decoded, Map.class);

                String userId = (String) properties.get(USER_ID_IN_HEADER);

                req = request.mutate()
                        .header(USER_ID_IN_HEADER, userId)
                        .build();
            } catch (Exception e) {
                LOGGER.error("Failed to customize header for the request, but still release it as the it would be regarded without any user details.", e);
            }
        }
    } else {
        LOGGER.info("Regard this request as anonymous request, so set anonymous user_id  in the header.");
        req = request.mutate()
                .header(USER_ID_IN_HEADER, ANONYMOUS_USER_ID)
                .build();
    }

    return req;

}
 
@SuppressWarnings("unchecked")
private void mockUrlParams(/*@Mock*/ ServerHttpRequest request, Map<String, String> paramMap) {
    MultiValueMap<String, String> urlParams = mock(MultiValueMap.class);
    when(request.getQueryParams()).thenReturn(urlParams);
    for (Map.Entry<String, String> e : paramMap.entrySet()) {
        when(urlParams.getFirst(e.getKey())).thenReturn(e.getValue());
    }
}
 
源代码20 项目: gateway   文件: LogFilter.java
/**
 * 请求信息日志过滤器
 *
 * @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);
}
 
@Nullable
private static String getForwardedPrefix(ServerHttpRequest request) {
	HttpHeaders headers = request.getHeaders();
	String prefix = headers.getFirst("X-Forwarded-Prefix");
	if (prefix != null) {
		int endIndex = prefix.length();
		while (endIndex > 1 && prefix.charAt(endIndex - 1) == '/') {
			endIndex--;
		}
		prefix = (endIndex != prefix.length() ? prefix.substring(0, endIndex) : prefix);
	}
	return prefix;
}
 
private void mockClientHostAddress(/*@Mock*/ ServerHttpRequest request, String address) {
    InetSocketAddress socketAddress = mock(InetSocketAddress.class);
    when(request.getRemoteAddress()).thenReturn(socketAddress);
    InetAddress inetAddress = mock(InetAddress.class);
    when(inetAddress.getHostAddress()).thenReturn(address);
    when(socketAddress.getAddress()).thenReturn(inetAddress);
}
 
@Test // SPR-17525
public void shouldNotDoubleEncode() throws Exception {
	HttpHeaders headers = new HttpHeaders();
	headers.add("Forwarded", "host=84.198.58.199;proto=https");

	ServerHttpRequest request = MockServerHttpRequest
			.method(HttpMethod.GET, new URI("http://example.com/a%20b?q=a%2Bb"))
			.headers(headers)
			.build();

	request = this.requestMutator.apply(request);

	assertEquals(new URI("https://84.198.58.199/a%20b?q=a%2Bb"), request.getURI());
	assertForwardedHeadersRemoved(request);
}
 
@Test
public void xForwardedPrefixTrailingSlash() throws Exception {
	HttpHeaders headers = new HttpHeaders();
	headers.add("X-Forwarded-Prefix", "/prefix////");
	ServerHttpRequest request = this.requestMutator.apply(getRequest(headers));

	assertEquals(new URI("http://example.com/prefix/path"), request.getURI());
	assertEquals("/prefix/path", request.getPath().value());
	assertForwardedHeadersRemoved(request);
}
 
源代码25 项目: tutorials   文件: IndexRewriteFilter.java
@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);
}
 
@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 Mono<Void> writeTo(ClientHttpRequest request, ExchangeStrategies strategies) {
	HttpHeaders requestHeaders = request.getHeaders();
	if (!this.headers.isEmpty()) {
		this.headers.entrySet().stream()
				.filter(entry -> !requestHeaders.containsKey(entry.getKey()))
				.forEach(entry -> requestHeaders
						.put(entry.getKey(), entry.getValue()));
	}

	MultiValueMap<String, HttpCookie> requestCookies = request.getCookies();
	if (!this.cookies.isEmpty()) {
		this.cookies.forEach((name, values) -> values.forEach(value -> {
			HttpCookie cookie = new HttpCookie(name, value);
			requestCookies.add(name, cookie);
		}));
	}

	return this.body.insert(request, new BodyInserter.Context() {
		@Override
		public List<HttpMessageWriter<?>> messageWriters() {
			return strategies.messageWriters();
		}
		@Override
		public Optional<ServerHttpRequest> serverRequest() {
			return Optional.empty();
		}
		@Override
		public Map<String, Object> hints() {
			return Hints.from(Hints.LOG_PREFIX_HINT, logPrefix());
		}
	});
}
 
源代码28 项目: black-shop   文件: CorsConfig.java
@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);
	};
}
 
private HandshakeInfo createHandshakeInfo(ServerWebExchange exchange, ServerHttpRequest request,
		@Nullable String protocol, Map<String, Object> attributes) {

	URI uri = request.getURI();
	// Copy request headers, as they might be pooled and recycled by
	// the server implementation once the handshake HTTP exchange is done.
	HttpHeaders headers = new HttpHeaders();
	headers.addAll(request.getHeaders());
	Mono<Principal> principal = exchange.getPrincipal();
	String logPrefix = exchange.getLogPrefix();
	InetSocketAddress remoteAddress = request.getRemoteAddress();
	return new HandshakeInfo(uri, headers, principal, protocol, remoteAddress, attributes, logPrefix);
}
 
@GetMapping(path = RESPONSE_STATUS_EX_FOR_SPECIFIC_STATUS_CODE_ENDPOINT)
@ResponseBody
public String responseStatusExForSpecificStatusCodeEndpoint(ServerHttpRequest request) {
    int desiredStatusCode = Integer.parseInt(
        request.getHeaders().getFirst("desired-status-code")
    );
    throw new ResponseStatusException(
        HttpStatus.resolve(desiredStatusCode),
        "Synthetic ResponseStatusException with specific desired status code: " + desiredStatusCode
    );
}
 
 类所在包
 同包方法