下面列出了怎么用org.springframework.http.client.ClientHttpResponse的API类实例代码及写法,或者点击链接到github查看源代码。
private void invokeAfterRecvResponse(ClientHttpResponse httpResponse, boolean serverFlag) throws IOException {
SpringCloudBeanRegistry beanRegistry = SpringCloudBeanRegistry.getInstance();
CompensableBeanFactory beanFactory = beanRegistry.getBeanFactory();
TransactionInterceptor transactionInterceptor = beanFactory.getTransactionInterceptor();
HttpHeaders respHeaders = httpResponse.getHeaders();
String respTransactionStr = respHeaders.getFirst(HEADER_TRANCACTION_KEY);
String respPropagationStr = respHeaders.getFirst(HEADER_PROPAGATION_KEY);
String respRecursivelyStr = respHeaders.getFirst(HEADER_RECURSIVELY_KEY);
String transactionText = StringUtils.trimToNull(respTransactionStr);
byte[] byteArray = StringUtils.isBlank(transactionText) ? null : Base64.getDecoder().decode(transactionText);
TransactionContext serverContext = byteArray == null || byteArray.length == 0 //
? null
: (TransactionContext) SerializeUtils.deserializeObject(byteArray);
TransactionResponseImpl txResp = new TransactionResponseImpl();
txResp.setTransactionContext(serverContext);
RemoteCoordinator serverCoordinator = beanRegistry.getConsumeCoordinator(respPropagationStr);
txResp.setSourceTransactionCoordinator(serverCoordinator);
txResp.setParticipantDelistFlag(serverFlag ? StringUtils.equalsIgnoreCase(respRecursivelyStr, "TRUE") : true);
transactionInterceptor.afterReceiveResponse(txResp);
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
if (omegaContext!= null && omegaContext.globalTxId() != null) {
request.getHeaders().add(GLOBAL_TX_ID_KEY, omegaContext.globalTxId());
request.getHeaders().add(LOCAL_TX_ID_KEY, omegaContext.localTxId());
LOG.debug("Added {} {} and {} {} to request header",
GLOBAL_TX_ID_KEY,
omegaContext.globalTxId(),
LOCAL_TX_ID_KEY,
omegaContext.localTxId());
} else {
LOG.debug("Cannot inject transaction ID, as the OmegaContext is null or cannot get the globalTxId.");
}
return execution.execute(request, body);
}
@Test
public void connectReceiveAndCloseWithStompFrame() throws Exception {
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND);
accessor.setDestination("/destination");
MessageHeaders headers = accessor.getMessageHeaders();
Message<byte[]> message = MessageBuilder.createMessage("body".getBytes(StandardCharsets.UTF_8), headers);
byte[] bytes = new StompEncoder().encode(message);
TextMessage textMessage = new TextMessage(bytes);
SockJsFrame frame = SockJsFrame.messageFrame(new Jackson2SockJsMessageCodec(), textMessage.getPayload());
String body = "o\n" + frame.getContent() + "\n" + "c[3000,\"Go away!\"]";
ClientHttpResponse response = response(HttpStatus.OK, body);
connect(response);
verify(this.webSocketHandler).afterConnectionEstablished(any());
verify(this.webSocketHandler).handleMessage(any(), eq(textMessage));
verify(this.webSocketHandler).afterConnectionClosed(any(), eq(new CloseStatus(3000, "Go away!")));
verifyNoMoreInteractions(this.webSocketHandler);
}
@Override
public ListenableFuture<ClientHttpResponse> intercept(HttpRequest request, byte[] body,
org.springframework.http.client.AsyncClientHttpRequestExecution execution) throws IOException {
ListenableFuture<ClientHttpResponse> future = execution.executeAsync(request, body);
future.addCallback(
resp -> {
response = resp;
this.latch.countDown();
},
ex -> {
exception = ex;
this.latch.countDown();
});
return future;
}
@Override
@Nullable
protected final T adapt(ClientHttpResponse response) throws ExecutionException {
try {
if (!getErrorHandler().hasError(response)) {
logResponseStatus(this.method, this.url, response);
}
else {
handleResponseError(this.method, this.url, response);
}
return convertResponse(response);
}
catch (Throwable ex) {
throw new ExecutionException(ex);
}
finally {
response.close();
}
}
@Test
public void interceptNeverRetry() throws Throwable {
HttpRequest request = mock(HttpRequest.class);
when(request.getURI()).thenReturn(new URI("http://foo"));
ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {},
HttpStatus.OK);
ServiceInstance serviceInstance = mock(ServiceInstance.class);
when(this.client.choose(eq("foo"))).thenReturn(serviceInstance);
when(this.client.execute(eq("foo"), eq(serviceInstance),
any(LoadBalancerRequest.class))).thenReturn(clientHttpResponse);
when(this.lbRequestFactory.createRequest(any(), any(), any()))
.thenReturn(mock(LoadBalancerRequest.class));
this.lbProperties.setEnabled(true);
RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(
this.client, this.lbProperties, this.lbRequestFactory,
this.loadBalancedRetryFactory);
byte[] body = new byte[] {};
ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class);
interceptor.intercept(request, body, execution);
verify(this.lbRequestFactory).createRequest(request, body, execution);
}
@Test
public void interceptSuccess() throws Throwable {
HttpRequest request = mock(HttpRequest.class);
when(request.getURI()).thenReturn(new URI("http://foo"));
ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {},
HttpStatus.OK);
LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class);
ServiceInstance serviceInstance = mock(ServiceInstance.class);
when(this.client.choose(eq("foo"))).thenReturn(serviceInstance);
when(this.client.execute(eq("foo"), eq(serviceInstance),
any(LoadBalancerRequest.class))).thenReturn(clientHttpResponse);
when(this.lbRequestFactory.createRequest(any(), any(), any()))
.thenReturn(mock(LoadBalancerRequest.class));
this.lbProperties.setEnabled(true);
RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(
this.client, this.lbProperties, this.lbRequestFactory,
new MyLoadBalancedRetryFactory(policy));
byte[] body = new byte[] {};
ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class);
ClientHttpResponse rsp = interceptor.intercept(request, body, execution);
then(rsp).isEqualTo(clientHttpResponse);
verify(this.lbRequestFactory).createRequest(request, body, execution);
}
private org.springframework.mock.http.client.MockAsyncClientHttpRequest createRequestInternal(
URI uri, HttpMethod method) {
Assert.notNull(uri, "'uri' must not be null");
Assert.notNull(method, "'httpMethod' must not be null");
return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, uri) {
@Override
protected ClientHttpResponse executeInternal() throws IOException {
ClientHttpResponse response = expectationManager.validateRequest(this);
setResponse(response);
return response;
}
};
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void handleError(ClientHttpResponse response) throws IOException {
MediaType mediaType = response.getHeaders().getContentType();
RestError error = null;
for(HttpMessageConverter converter : converters) {
if(converter.canRead(JaxbRestError.class, mediaType)) {
try {
error = (RestError)converter.read(JaxbRestError.class, response);
} catch(Exception e) {
error = new JaxbRestError();
((JaxbRestError)error).setStatus(response.getRawStatusCode());
}
break;
}
}
throw new DCTMRestErrorException(response.getHeaders(), response.getStatusCode(), error);
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
if (omegaContext != null && omegaContext.globalTxId() != null) {
request.getHeaders().add(GLOBAL_TX_ID_KEY, omegaContext.globalTxId());
request.getHeaders().add(LOCAL_TX_ID_KEY, omegaContext.localTxId());
request.getHeaders().add(GLOBAL_TX_CATEGORY_KEY, omegaContext.category());
LOG.debug("Added {} {} and {} {} to request header",
GLOBAL_TX_ID_KEY,
omegaContext.globalTxId(),
LOCAL_TX_ID_KEY,
omegaContext.localTxId(),
GLOBAL_TX_CATEGORY_KEY,
omegaContext.category());
}
return execution.execute(request, body);
}
/**
* @param tagAndNamingStrategy The span tag and naming strategy to use - cannot be null. If you really want no
* tag and naming strategy, then pass in {@link NoOpHttpTagStrategy#getDefaultInstance()}.
* @param tagAndNamingAdapter The tag and naming adapter to use - cannot be null. If you really want no tag and
* naming adapter, then pass in {@link NoOpHttpTagAdapter#getDefaultInstance()}.
* @return A new {@link RestTemplate} instance with a {@link WingtipsClientHttpRequestInterceptor}
* already added, and with the subspan option and tag/naming strategy and adapter set to the given arguments.
*/
public static RestTemplate createTracingEnabledRestTemplate(
boolean surroundCallsWithSubspan,
HttpTagAndSpanNamingStrategy<HttpRequest, ClientHttpResponse> tagAndNamingStrategy,
HttpTagAndSpanNamingAdapter<HttpRequest, ClientHttpResponse> tagAndNamingAdapter
) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(
new WingtipsClientHttpRequestInterceptor(
surroundCallsWithSubspan,
tagAndNamingStrategy,
tagAndNamingAdapter
)
);
return restTemplate;
}
/**
* Constructor that lets you choose whether downstream calls will be surrounded with a subspan and supply the relevant tag strategy
* for the subspan.
*
* @param surroundCallsWithSubspan pass in true to have downstream calls surrounded with a new span, false to only
* propagate the current span's info downstream (no subspan).
* @param tagAndNamingStrategy The span tag and naming strategy to use - cannot be null. If you really want no
* tag and naming strategy, then pass in {@link NoOpHttpTagStrategy#getDefaultInstance()}.
* @param tagAndNamingAdapter The tag and naming adapter to use - cannot be null. If you really want no tag and
* naming adapter, then pass in {@link NoOpHttpTagAdapter#getDefaultInstance()}.
*/
public WingtipsClientHttpRequestInterceptor(
boolean surroundCallsWithSubspan,
HttpTagAndSpanNamingStrategy<HttpRequest, ClientHttpResponse> tagAndNamingStrategy,
HttpTagAndSpanNamingAdapter<HttpRequest, ClientHttpResponse> tagAndNamingAdapter
) {
if (tagAndNamingStrategy == null) {
throw new IllegalArgumentException(
"tagAndNamingStrategy cannot be null - if you really want no strategy, use NoOpHttpTagStrategy"
);
}
if (tagAndNamingAdapter == null) {
throw new IllegalArgumentException(
"tagAndNamingAdapter cannot be null - if you really want no adapter, use NoOpHttpTagAdapter"
);
}
this.surroundCallsWithSubspan = surroundCallsWithSubspan;
this.tagAndNamingStrategy = tagAndNamingStrategy;
this.tagAndNamingAdapter = tagAndNamingAdapter;
}
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes,
ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
DTMContext dtmContext = DTMContext.getDTMContext();
long gid = dtmContext.getGlobalTxId();
HttpHeaders headers = httpRequest.getHeaders();
if (gid != -1) {
DtmContextDTO dtmContextDTO = DtmContextDTO.fromDtmContext(dtmContext);
headers.add(DtmConstants.DTM_CONTEXT, Json.encode(dtmContextDTO));
}
return clientHttpRequestExecution.execute(httpRequest, bytes);
}
/**
* Execute the given method on the provided URI.
* <p>The {@link ClientHttpRequest} is processed using the {@link RequestCallback};
* the response with the {@link ResponseExtractor}.
* @param url the fully-expanded URL to connect to
* @param method the HTTP method to execute (GET, POST, etc.)
* @param requestCallback object that prepares the request (can be {@code null})
* @param responseExtractor object that extracts the return value from the response (can be {@code null})
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
*/
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "'url' must not be null");
Assert.notNull(method, "'method' must not be null");
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
else {
return null;
}
}
catch (IOException ex) {
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + url + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
Assert.notEmpty(token, "token cannot be empty");
HttpHeaders headers = request.getHeaders();
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
return execution.execute(request, body);
}
/**
* レスポンス情報をログ出力します。
* @param response HTTPレスポンス
* @throws IOException I/O例外
*/
protected void dumpResponse(ClientHttpResponse response) throws IOException {
if (L.isDebugEnabled()) {
StringBuilder sb = new StringBuilder();
sb.append("Response").append(LS);
sb.append(RESPONSE_PREFIX).append(response.getStatusCode().toString() + " " + response.getStatusText())
.append(LS);
dumpHttpHeader(sb, RESPONSE_PREFIX, response.getHeaders());
L.debug(sb.toString());
}
}
public CloneHttpResponse(ClientHttpResponse response) {
this.response = response;
try {
bodyString = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
responseStream = new ByteArrayInputStream(bodyString.getBytes(StandardCharsets.UTF_8.name()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
if (body.length > 0) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
HexDump.dump(body, 0, baos, 0);
logger.info("Sending to [{}]: \n{}", request.getURI(), baos.toString(Charsets.UTF_8.name()).trim());
} else {
logger.info("Sending empty body to [{}]!", request.getURI());
}
return execution.execute(request, body);
}
@Override
public ClientHttpResponse intercept(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution) throws IOException {
ClientHttpResponse response = execution.execute(request, body);
String responseBody = toString((ByteArrayInputStream) response.getBody());
logger.info("Config server received request " +
request.getMethodValue() + " " + request.getURI() +
" and responded:\n" + responseBody);
return response;
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
System.out.println("route:"+route);
System.out.println("exception:"+cause.getMessage());
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "ok";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("Sorry, the service is unavailable now.".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
private void executeWildcard(final ClientHttpResponse response, final MessageReader reader) throws Exception {
if (wildcard == null) {
throw new NoWildcardException();
}
wildcard.execute(response, reader);
}
@Override
public ListenableFuture<ClientHttpResponse> executeAsync() {
this.setPath(findUriPath(this.getURI()));
this.setRequestMeta(createRequestMeta(this.getMethod().name(), this.getURI()));
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(this.getURI().getRawSchemeSpecificPart());
this.setQueryParams(queryStringDecoder.parameters());
Map<String, Object> swaggerArguments = this.collectArguments();
return this.invoke(swaggerArguments);
}
public ResponseExtractorFuture(HttpMethod method, URI url,
ListenableFuture<ClientHttpResponse> clientHttpResponseFuture,
@Nullable ResponseExtractor<T> responseExtractor) {
super(clientHttpResponseFuture);
this.method = method;
this.url = url;
this.responseExtractor = responseExtractor;
}
@Override
public ClientHttpResponse fallbackResponse() {
return new ClientHttpResponse() {
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("{\"status\":\"200\"}".getBytes());
}
@Override
public String getStatusText() throws IOException {
return "OK";
}
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public void close() {
}
};
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
//标记不同的异常为不同的http状态值
if (cause instanceof HystrixTimeoutException) {
return response(HttpStatus.GATEWAY_TIMEOUT);
} else {
//可继续添加自定义异常类
return response(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public void doWithRequest(final org.springframework.http.client.AsyncClientHttpRequest request)
throws IOException {
this.adaptee.doWithRequest(new ClientHttpRequest() {
@Override
public ClientHttpResponse execute() throws IOException {
throw new UnsupportedOperationException("execute not supported");
}
@Override
public OutputStream getBody() throws IOException {
return request.getBody();
}
@Override
@Nullable
public HttpMethod getMethod() {
return request.getMethod();
}
@Override
public String getMethodValue() {
return request.getMethodValue();
}
@Override
public URI getURI() {
return request.getURI();
}
@Override
public HttpHeaders getHeaders() {
return request.getHeaders();
}
});
}
@Override
public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
String responseAsString = toString(response.getBody());
log.error("URL: {}, HttpMethod: {}, ResponseBody: {}", url, method, responseAsString);
throw new CustomException(responseAsString);
}
@Override
public CompletableFuture<ClientHttpResponse> call(final Route route) {
final RequestExecution execution =
plugins.aroundAsync(
plugins.aroundDispatch(
plugins.aroundSerialization(
plugins.aroundNetwork(
network))));
return throwingFunction(execution::execute).apply(arguments.withRoute(route));
}
public OAuth2RestTemplate smartlingRestTemplate() {
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(smartling(), new DefaultOAuth2ClientContext());
RestTemplateUtils restTemplateUtils = new RestTemplateUtils();
restTemplateUtils.enableFeature(oAuth2RestTemplate, DeserializationFeature.UNWRAP_ROOT_VALUE);
AccessTokenProviderChain accessTokenProviderChain = new AccessTokenProviderChain(Arrays.asList(
new SmartlingAuthorizationCodeAccessTokenProvider())
);
oAuth2RestTemplate.setAccessTokenProvider(accessTokenProviderChain);
DefaultUriTemplateHandler defaultUriTemplateHandler = new DefaultUriTemplateHandler();
defaultUriTemplateHandler.setBaseUrl(baseUri);
oAuth2RestTemplate.setUriTemplateHandler(defaultUriTemplateHandler);
oAuth2RestTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
try {
super.handleError(response);
} catch (HttpClientErrorException e) {
if (resttemplateLogger.isDebugEnabled()) {
resttemplateLogger.debug(e.getResponseBodyAsString());
}
throw e;
}
}
});
return oAuth2RestTemplate;
}
@Override
public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) {
return new MockClientHttpRequest(httpMethod, uri) {
@Override
public ClientHttpResponse executeInternal() throws IOException {
return getClientHttpResponse(httpMethod, uri, getHeaders(), getBodyAsBytes());
}
};
}