Skip to content

Commit

Permalink
[ISSUE alibaba#3210] Enhanced nacos resttemplate response handler (al…
Browse files Browse the repository at this point in the history
…ibaba#3212)

* Enhanced nacos resttemplate response handler

* Enhanced nacos resttemplate response handler

* Add license

* [alibaba#3212] Modify some class name and comment

* [alibaba#3212] Modify some class name and comment

* [alibaba#3212] Modify some class name and comment

* [alibaba#3212] change the name of property

* Fix code style issue
  • Loading branch information
Maijh97 authored Jul 13, 2020
1 parent eca82bf commit 092a089
Show file tree
Hide file tree
Showing 16 changed files with 393 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,10 @@ public String toString() {
public static final int OVER_THRESHOLD = 503;

public static final int RESOURCE_NOT_FOUND = -404;

/**
* http client error code,
* ome exceptions that occurred when the use the Nacos RestTemplate and Nacos AsyncRestTemplate.
*/
public static final int HTTP_CLIENT_ERROR_CODE = -500;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.common.constant;

/**
* Response Handler Type.
*
* @author mai.jh
*/
public final class ResponseHandlerType {

public static final String STRING_TYPE = "java.lang.String";

public static final String RESTRESULT_TYPE = "com.alibaba.nacos.common.model.RestResult";

public static final String DEFAULT_BEAN_TYPE = "default_bean_handler";

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public class HttpRestResult<T> extends RestResult<T> {
public HttpRestResult() {
}

public HttpRestResult(Header header, int code, T data) {
super(code, data);
public HttpRestResult(Header header, int code, T data, String message) {
super(code, message, data);
this.header = header;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.common.http.client;

import com.alibaba.nacos.common.constant.ResponseHandlerType;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.databind.JavaType;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

/**
* For NacosRestTemplate and NacosAsyncRestTemplate, provide initialization and register of response converter.
*
* @author mai.jh
*/
public abstract class AbstractNacosRestTemplate {

private final Map<String, ResponseHandler> responseHandlerMap = new HashMap<String, ResponseHandler>();

public AbstractNacosRestTemplate() {
// init response handler
responseHandlerMap.put(ResponseHandlerType.STRING_TYPE, new StringResponseHandler());
responseHandlerMap.put(ResponseHandlerType.RESTRESULT_TYPE, new RestResultResponseHandler());
responseHandlerMap.put(ResponseHandlerType.DEFAULT_BEAN_TYPE, new BeanResponseHandler());
}

/**
* register customization Response Handler.
*
* @param responseHandler {@link ResponseHandler}
*/
public void registerResponseHandler(String responseHandlerType, ResponseHandler responseHandler) {
responseHandlerMap.put(responseHandlerType, responseHandler);
}

/**
* Select a response handler by responseType.
*
* @param responseType responseType
* @return ResponseHandler
*/
protected ResponseHandler selectResponseHandler(Type responseType) {
ResponseHandler responseHandler = null;
if (responseType == null) {
responseHandler = responseHandlerMap.get(ResponseHandlerType.STRING_TYPE);
}
if (responseHandler == null) {
JavaType javaType = JacksonUtils.constructJavaType(responseType);
String name = javaType.getRawClass().getName();
responseHandler = responseHandlerMap.get(name);
}
// When the corresponding type of response handler cannot be obtained,
// the default bean response handler is used
if (responseHandler == null) {
responseHandler = responseHandlerMap.get(ResponseHandlerType.DEFAULT_BEAN_TYPE);
}
responseHandler.setResponseType(responseType);
return responseHandler;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.common.http.client;

import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.utils.IoUtils;
import org.apache.http.HttpStatus;

import java.lang.reflect.Type;

/**
* Abstract response handler.
*
* @author mai.jh
*/
public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {

private Type responseType;

@Override
public final void setResponseType(Type responseType) {
this.responseType = responseType;
}

@Override
public final HttpRestResult<T> handle(HttpClientResponse response) throws Exception {
if (HttpStatus.SC_OK != response.getStatusCode()) {
return handleError(response);
}
return convertResult(response, this.responseType);
}

private HttpRestResult<T> handleError(HttpClientResponse response) throws Exception {
Header headers = response.getHeaders();
String message = IoUtils.toString(response.getBody(), headers.getCharset());
return new HttpRestResult<T>(headers, response.getStatusCode(), null, message);
}

/**
* Abstract convertResult method, Different types of converters for expansion.
*
* @param response http client response
* @param responseType responseType
* @return HttpRestResult
* @throws Exception ex
*/
public abstract HttpRestResult<T> convertResult(HttpClientResponse response, Type responseType) throws Exception;

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.alibaba.nacos.common.model.RequestHttpEntity;

import java.io.Closeable;
import java.lang.reflect.Type;
import java.net.URI;

/**
Expand All @@ -37,10 +36,10 @@ public interface AsyncHttpClientRequest extends Closeable {
* @param uri http url
* @param httpMethod http request method
* @param requestHttpEntity http request entity
* @param responseType http response type
* @param responseHandler http response handler
* @param callback http response callback
* @throws Exception ex
*/
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType,
final Callback<T> callback) throws Exception;
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity,
final ResponseHandler<T> responseHandler, final Callback<T> callback) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.common.http.client;

import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.utils.JacksonUtils;

import java.io.InputStream;
import java.lang.reflect.Type;

/**
* bean response handler,
* Mainly converter response type as bean type.
*
* @author mai.jh
*/
public class BeanResponseHandler<T> extends AbstractResponseHandler<T> {

@Override
public HttpRestResult<T> convertResult(HttpClientResponse response, Type responseType) throws Exception {
final Header headers = response.getHeaders();
InputStream body = response.getBody();
T extractBody = JacksonUtils.toObj(body, responseType);
return new HttpRestResult<T>(headers, response.getStatusCode(), extractBody, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@

import com.alibaba.nacos.common.http.Callback;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.handler.ResponseHandler;
import com.alibaba.nacos.common.model.RequestHttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;

/**
Expand All @@ -46,15 +44,15 @@ public DefaultAsyncHttpClientRequest(CloseableHttpAsyncClient asyncClient) {
}

@Override
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType,
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final ResponseHandler<T> responseHandler,
final Callback<T> callback) throws Exception {
HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity);
asyncClient.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse result) {
DefaultClientHttpResponse response = new DefaultClientHttpResponse(result);
try {
HttpRestResult<T> httpRestResult = ResponseHandler.responseEntityExtractor(response, responseType);
HttpRestResult<T> httpRestResult = responseHandler.handle(response);
callback.onReceive(httpRestResult);
} catch (Exception e) {
callback.onError(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@
* @see AsyncHttpClientRequest
* @see HttpClientResponse
*/
public class NacosAsyncRestTemplate {
public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {

private static final Logger LOGGER = LoggerFactory.getLogger(NacosAsyncRestTemplate.class);

private AsyncHttpClientRequest clientRequest;

public NacosAsyncRestTemplate(AsyncHttpClientRequest clientRequest) {
super();
this.clientRequest = clientRequest;
}

Expand Down Expand Up @@ -330,13 +331,15 @@ public <T> void postForm(String url, Header header, Map<String, String> paramVal

}

private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType,
@SuppressWarnings("unchecked")
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type type,
Callback<T> callback) throws Exception {
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("HTTP " + httpMethod + " " + url);
}
clientRequest.execute(uri, httpMethod, requestEntity, responseType, callback);
ResponseHandler<T> responseHandler = super.selectResponseHandler(type);
clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.HttpUtils;
import com.alibaba.nacos.common.http.handler.ResponseHandler;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.http.param.Query;
Expand All @@ -38,13 +37,14 @@
* @see HttpClientRequest
* @see HttpClientResponse
*/
public class NacosRestTemplate {
public class NacosRestTemplate extends AbstractNacosRestTemplate {

private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class);

private HttpClientRequest requestClient;

public NacosRestTemplate(HttpClientRequest requestClient) {
super();
this.requestClient = requestClient;
}

Expand Down Expand Up @@ -319,16 +319,18 @@ public <T> HttpRestResult<T> exchangeForm(String url, Header header, Map<String,
return execute(url, httpMethod, requestHttpEntity, responseType);
}

@SuppressWarnings("unchecked")
private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
Type responseType) throws Exception {
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("HTTP " + httpMethod + " " + url);
}
ResponseHandler<T> responseHandler = super.selectResponseHandler(responseType);
HttpClientResponse response = null;
try {
response = requestClient.execute(uri, httpMethod, requestEntity);
return ResponseHandler.responseEntityExtractor(response, responseType);
return responseHandler.handle(response);
} finally {
if (response != null) {
response.close();
Expand Down
Loading

0 comments on commit 092a089

Please sign in to comment.