You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/08/04 06:21:39 UTC
[servicecomb-java-chassis] branch master updated:
[SCB-1754]accessor problem fix: CseHttpMessageConverter response access
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new ad9516d [SCB-1754]accessor problem fix: CseHttpMessageConverter response access
ad9516d is described below
commit ad9516dfad410a4162a7180336306200f410c0c1
Author: liubao <bi...@qq.com>
AuthorDate: Mon Aug 3 14:55:43 2020 +0800
[SCB-1754]accessor problem fix: CseHttpMessageConverter response access
---
.../springmvc/reference/CseClientHttpResponse.java | 1 -
.../reference}/CseHttpMessageConverter.java | 30 +----
.../CseHttpMessageConverterExtractor.java | 31 +++++
.../CseResponseEntityResponseExtractor.java | 49 ++++++++
.../springmvc/reference/CseRestTemplate.java | 126 ++++++++++++++++++++-
.../reference/async/CseAsyncRestTemplate.java | 23 +++-
.../web/client/TestCseHttpMessageConverter.java | 52 ---------
7 files changed, 231 insertions(+), 81 deletions(-)
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpResponse.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpResponse.java
index 52092c9..a06160a 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpResponse.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpResponse.java
@@ -90,7 +90,6 @@ public class CseClientHttpResponse implements ClientHttpResponse {
@Override
public HttpStatus getStatusCode() throws IOException {
- // TODO:springmvc不允许自定义http错误码
return HttpStatus.valueOf(response.getStatusCode());
}
diff --git a/providers/provider-springmvc/src/main/java/org/springframework/web/client/CseHttpMessageConverter.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverter.java
similarity index 75%
rename from providers/provider-springmvc/src/main/java/org/springframework/web/client/CseHttpMessageConverter.java
rename to providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverter.java
index 5693f35..35c37b9 100644
--- a/providers/provider-springmvc/src/main/java/org/springframework/web/client/CseHttpMessageConverter.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverter.java
@@ -15,16 +15,13 @@
* limitations under the License.
*/
-package org.springframework.web.client;
+package org.apache.servicecomb.provider.springmvc.reference;
import java.io.IOException;
-import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
-import org.apache.servicecomb.provider.springmvc.reference.CseClientHttpRequest;
-import org.apache.servicecomb.provider.springmvc.reference.CseClientHttpResponse;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
@@ -32,26 +29,14 @@ import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.lang.Nullable;
-import org.springframework.util.ReflectionUtils;
-/**
- * 需要访问MessageBodyClientHttpResponseWrapper
- * 这是一个package级别的类,只好放在特殊的包内了
- */
public class CseHttpMessageConverter implements GenericHttpMessageConverter<Object> {
private static final List<MediaType> ALL_MEDIA_TYPE = Arrays.asList(MediaType.ALL);
- private static final Field RESPONSE_FIELD =
- ReflectionUtils.findField(MessageBodyClientHttpResponseWrapper.class, "response");
-
- static {
- RESPONSE_FIELD.setAccessible(true);
- }
-
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
- return true;
+ return false;
}
@Override
@@ -67,14 +52,11 @@ public class CseHttpMessageConverter implements GenericHttpMessageConverter<Obje
@Override
public Object read(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
- return read(inputMessage);
+ throw new IllegalStateException("not supported");
}
private Object read(HttpInputMessage inputMessage) {
- MessageBodyClientHttpResponseWrapper respWrapper = (MessageBodyClientHttpResponseWrapper) inputMessage;
- CseClientHttpResponse resp =
- (CseClientHttpResponse) ReflectionUtils.getField(RESPONSE_FIELD, respWrapper);
- return resp.getResult();
+ throw new IllegalStateException("not supported");
}
@Override
@@ -90,13 +72,13 @@ public class CseHttpMessageConverter implements GenericHttpMessageConverter<Obje
@Override
public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {
- return true;
+ return false;
}
@Override
public Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
- return read(inputMessage);
+ throw new IllegalStateException("not supported");
}
@Override
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverterExtractor.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverterExtractor.java
new file mode 100644
index 0000000..402c714
--- /dev/null
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverterExtractor.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.provider.springmvc.reference;
+
+import java.io.IOException;
+
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.ResponseExtractor;
+
+public class CseHttpMessageConverterExtractor<T> implements ResponseExtractor<T> {
+ @Override
+ @SuppressWarnings("unchecked")
+ public T extractData(ClientHttpResponse response) throws IOException {
+ return (T) ((CseClientHttpResponse) response).getResult();
+ }
+}
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseResponseEntityResponseExtractor.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseResponseEntityResponseExtractor.java
new file mode 100644
index 0000000..7c8f4ad
--- /dev/null
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseResponseEntityResponseExtractor.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.provider.springmvc.reference;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.lang.Nullable;
+import org.springframework.web.client.ResponseExtractor;
+
+public class CseResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {
+ @Nullable
+ private final CseHttpMessageConverterExtractor<T> delegate;
+
+ public CseResponseEntityResponseExtractor(@Nullable Type responseType) {
+ if (responseType != null && Void.class != responseType) {
+ this.delegate = new CseHttpMessageConverterExtractor<>();
+ } else {
+ this.delegate = null;
+ }
+ }
+
+ @Override
+ public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
+ if (this.delegate != null) {
+ T body = this.delegate.extractData(response);
+ return ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).body(body);
+ } else {
+ return ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).build();
+ }
+ }
+}
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseRestTemplate.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseRestTemplate.java
index 251182e..8f25d4e 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseRestTemplate.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseRestTemplate.java
@@ -20,10 +20,15 @@ package org.apache.servicecomb.provider.springmvc.reference;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.Arrays;
+import java.util.Map;
import org.apache.servicecomb.common.rest.RestConst;
-import org.springframework.web.client.CseHttpMessageConverter;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.lang.Nullable;
import org.springframework.web.client.RequestCallback;
+import org.springframework.web.client.ResponseExtractor;
+import org.springframework.web.client.RestClientException;
public class CseRestTemplate extends AcceptableRestTemplate {
public CseRestTemplate() {
@@ -32,6 +37,125 @@ public class CseRestTemplate extends AcceptableRestTemplate {
setUriTemplateHandler(new CseUriTemplateHandler());
}
+ // GET
+
+ @Override
+ @Nullable
+ public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
+ RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
+ }
+
+ @Override
+ @Nullable
+ public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
+ RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
+ }
+
+ @Override
+ @Nullable
+ public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException {
+ RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
+ }
+
+ // HEAD
+ // no override
+
+ // POST
+
+ @Override
+ @Nullable
+ public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
+ Object... uriVariables) throws RestClientException {
+
+ RequestCallback requestCallback = httpEntityCallback(request, responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
+ }
+
+ @Override
+ @Nullable
+ public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
+ Map<String, ?> uriVariables) throws RestClientException {
+
+ RequestCallback requestCallback = httpEntityCallback(request, responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
+ }
+
+ @Override
+ @Nullable
+ public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType)
+ throws RestClientException {
+
+ RequestCallback requestCallback = httpEntityCallback(request, responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
+ }
+
+ // PUT
+ // no override
+
+ // PATCH
+
+ @Override
+ @Nullable
+ public <T> T patchForObject(String url, @Nullable Object request, Class<T> responseType,
+ Object... uriVariables) throws RestClientException {
+
+ RequestCallback requestCallback = httpEntityCallback(request, responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);
+ }
+
+ @Override
+ @Nullable
+ public <T> T patchForObject(String url, @Nullable Object request, Class<T> responseType,
+ Map<String, ?> uriVariables) throws RestClientException {
+
+ RequestCallback requestCallback = httpEntityCallback(request, responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);
+ }
+
+ @Override
+ @Nullable
+ public <T> T patchForObject(URI url, @Nullable Object request, Class<T> responseType)
+ throws RestClientException {
+
+ RequestCallback requestCallback = httpEntityCallback(request, responseType);
+ CseHttpMessageConverterExtractor<T> responseExtractor =
+ new CseHttpMessageConverterExtractor<>();
+ return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor);
+ }
+
+ // DELETE
+ // no override
+
+ // OPTIONS
+ // no override
+
+ // exchange
+ // no override
+
+ @Override
+ public <T> ResponseExtractor<ResponseEntity<T>> responseEntityExtractor(Type responseType) {
+ return new CseResponseEntityResponseExtractor<>(responseType);
+ }
+
@Override
public <T> RequestCallback httpEntityCallback(Object requestBody) {
RequestCallback callback = super.httpEntityCallback(requestBody);
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/async/CseAsyncRestTemplate.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/async/CseAsyncRestTemplate.java
index 0f25b6e..683c1b4 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/async/CseAsyncRestTemplate.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/async/CseAsyncRestTemplate.java
@@ -20,26 +20,43 @@ package org.apache.servicecomb.provider.springmvc.reference.async;
import java.lang.reflect.Type;
import java.util.Arrays;
+import org.apache.servicecomb.provider.springmvc.reference.CseHttpMessageConverter;
+import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;
import org.apache.servicecomb.provider.springmvc.reference.CseUriTemplateHandler;
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.http.HttpEntity;
-import org.springframework.web.client.CseHttpMessageConverter;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
@SuppressWarnings("deprecation")
-// TODO : upgrade to spring 5 will having warning's , we'll fix it later
+// AsyncRestTemplate is deprecated by spring 5, using RPC with CompletableFuture instead.
+// Keep this function is only for compatibility, and maybe removed in future.
public class CseAsyncRestTemplate extends org.springframework.web.client.AsyncRestTemplate {
public CseAsyncRestTemplate() {
+ super(createSimpleClientHttpRequestFactory(), createRestTemplate());
setMessageConverters(Arrays.asList(new CseHttpMessageConverter()));
setAsyncRequestFactory(new CseAsyncClientHttpRequestFactory());
setUriTemplateHandler(new CseUriTemplateHandler());
}
+ private static SimpleClientHttpRequestFactory createSimpleClientHttpRequestFactory() {
+ SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
+ requestFactory.setTaskExecutor(new SimpleAsyncTaskExecutor());
+ return requestFactory;
+ }
+
+ private static RestTemplate createRestTemplate() {
+ return new CseRestTemplate();
+ }
+
@Override
protected <T> org.springframework.web.client.AsyncRequestCallback httpEntityCallback(HttpEntity<T> requestBody) {
return new CseAsyncRequestCallback<T>(requestBody);
}
@Override
- protected <T> org.springframework.web.client.AsyncRequestCallback httpEntityCallback(HttpEntity<T> requestBody, Type responseType) {
+ protected <T> org.springframework.web.client.AsyncRequestCallback httpEntityCallback(HttpEntity<T> requestBody,
+ Type responseType) {
return new CseAsyncRequestCallback<T>(requestBody);
}
}
\ No newline at end of file
diff --git a/providers/provider-springmvc/src/test/java/org/springframework/web/client/TestCseHttpMessageConverter.java b/providers/provider-springmvc/src/test/java/org/springframework/web/client/TestCseHttpMessageConverter.java
deleted file mode 100644
index 23ee30d..0000000
--- a/providers/provider-springmvc/src/test/java/org/springframework/web/client/TestCseHttpMessageConverter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.web.client;
-
-import java.io.IOException;
-
-import org.apache.servicecomb.provider.common.MockUtil;
-import org.apache.servicecomb.provider.springmvc.reference.CseClientHttpRequest;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.springframework.http.HttpOutputMessage;
-import org.springframework.http.converter.HttpMessageNotReadableException;
-import org.springframework.http.converter.HttpMessageNotWritableException;
-
-public class TestCseHttpMessageConverter {
-
- @Test
- public void testAll() {
- MockUtil.getInstance().mockReflectionUtils();
- MockUtil.getInstance().mockCseClientHttpRequest();
- CseHttpMessageConverter lCseHttpMessageConverter = new CseHttpMessageConverter();
- lCseHttpMessageConverter.canWrite(null, null);
- lCseHttpMessageConverter.getSupportedMediaTypes();
- try {
- lCseHttpMessageConverter.read(this.getClass(), null);
- } catch (HttpMessageNotReadableException | IOException ignored) {
- }
- try {
- HttpOutputMessage httpOutputMessage = Mockito.mock(CseClientHttpRequest.class);
- lCseHttpMessageConverter.write(null, null, httpOutputMessage);
- } catch (HttpMessageNotWritableException | IOException ignored) {
- }
-
- Assert.assertEquals(true, lCseHttpMessageConverter.canRead(null, null));
- }
-}