joh*_*ohn 14 java oop spring resttemplate
我用RestTemplate我HttpClient作为执行URL,服务器将返回一个json字符串作为响应.客户将通过传递DataKey其中的对象来调用此库userId.
userId,我将找出我可以获取数据然后将这些机器存储在a中的机器是什么LinkedList,以便我可以按顺序执行它们.下面是我的DataClient类,它将由客户调用,他们将DataKey对象传递给getData方法.
public class DataClient implements Client {
private RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
private ExecutorService service = Executors.newFixedThreadPool(15);
public Future<DataResponse> getData(DataKey key) {
DataExecutorTask task = new DataExecutorTask(key, restTemplate);
Future<DataResponse> future = service.submit(task);
return future;
}
}
Run Code Online (Sandbox Code Playgroud)
下面是我的DataExecutorTask类:
public class DataExecutorTask implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public DataExecutorTask(DataKey key, RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.key = key;
}
@Override
public DataResponse call() {
DataResponse dataResponse = null;
ResponseEntity<String> response = null;
MappingsHolder mappings = ShardMappings.getMappings(key.getTypeOfFlow());
// given a userId, find all the hostnames
// it can also have four hostname or one hostname or six hostname as well in the list
List<String> hostnames = mappings.getListOfHostnames(key.getUserId());
for (String hostname : hostnames) {
// If host name is null or host name is in local block list, skip sending request to this host
if (ClientUtils.isEmpty(hostname) || ShardMappings.isBlockHost(hostname)) {
continue;
}
try {
String url = generateURL(hostname);
response = restTemplate.exchange(url, HttpMethod.GET, key.getEntity(), String.class);
if (response.getStatusCode() == HttpStatus.NO_CONTENT) {
dataResponse = new DataResponse(response.getBody(), DataErrorEnum.NO_CONTENT,
DataStatusEnum.SUCCESS);
} else {
dataResponse = new DataResponse(response.getBody(), DataErrorEnum.OK,
DataStatusEnum.SUCCESS);
}
break;
// below codes are duplicated looks like
} catch (HttpClientErrorException ex) {
HttpStatusCodeException httpException = (HttpStatusCodeException) ex;
DataErrorEnum error = DataErrorEnum.getErrorEnumByException(httpException);
String errorMessage = httpException.getResponseBodyAsString();
dataResponse = new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
return dataResponse;
} catch (HttpServerErrorException ex) {
HttpStatusCodeException httpException = (HttpStatusCodeException) ex;
DataErrorEnum error = DataErrorEnum.getErrorEnumByException(httpException);
String errorMessage = httpException.getResponseBodyAsString();
dataResponse = new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
return dataResponse;
} catch (RestClientException ex) {
// if it comes here, then it means some of the servers are down so adding it into block list
ShardMappings.blockHost(hostname);
}
}
if (ClientUtils.isEmpty(hostnames)) {
dataResponse = new DataResponse(null, DataErrorEnum.PERT_ERROR, DataStatusEnum.ERROR);
} else if (response == null) { // either all the servers are down or all the servers were in block list
dataResponse = new DataResponse(null, DataErrorEnum.SERVICE_UNAVAILABLE, DataStatusEnum.ERROR);
}
return dataResponse;
}
}
Run Code Online (Sandbox Code Playgroud)
我的阻止列表每1分钟从另一个后台线程继续更新.如果任何服务器关闭而没有响应,那么我需要使用这个来阻止该服务器 -
ShardMappings.blockHost(hostname);
Run Code Online (Sandbox Code Playgroud)
并检查是否有任何服务器在阻止列表中,我使用此 -
ShardMappings.isBlockHost(hostname);
Run Code Online (Sandbox Code Playgroud)
我回国SERVICE_UNAVAILABLE,如果服务器关闭或阻止列表,的基础上response == null检查,不知道它是否是一个正确的做法与否.
我在这里根本没有遵循单一责任原则.任何人都可以提供一个例子,这里使用SRP原理的最佳方法是什么.
在思考了很多之后,我能够提取下面给出的主机类,但不确定在我上面的 课程中使用它的最佳方法是什么DataExecutorTask .
public class Hosts {
private final LinkedList<String> hostsnames = new LinkedList<String>();
public Hosts(final List<String> hosts) {
checkNotNull(hosts, "hosts cannot be null");
this.hostsnames.addAll(hosts);
}
public Optional<String> getNextAvailableHostname() {
while (!hostsnames.isEmpty()) {
String firstHostname = hostsnames.removeFirst();
if (!ClientUtils.isEmpty(firstHostname) && !ShardMappings.isBlockHost(firstHostname)) {
return Optional.of(firstHostname);
}
}
return Optional.absent();
}
public boolean isEmpty() {
return hostsnames.isEmpty();
}
}
Run Code Online (Sandbox Code Playgroud)
您的担忧是有效的.首先,让我们看看原始数据执行程序的作用:
First, it is getting list of hostnames
Next, it loops through every hostnames that do the following things:
It checks whether the hostname is valid to send request.
If not valid: skip.
Else continue.
Generate the URL based on hostname
Send the request
Translate the request response to domain response
Handle exceptions
If the hostnames is empty, generate an empty response
Return response
Run Code Online (Sandbox Code Playgroud)
现在,我们可以做些什么来关注SRP?我可以看到,我们可以将这些操作分组到一些组中.我可以看到,这些操作可以分为:
HostnameValidator: checks whether the hostname is valid to send request
--------------
HostnameRequestSender: Generate the URL
Send the request
--------------
HttpToDataResponse: Translate the request response to domain response
--------------
HostnameExceptionHandler: Handle exceptions
Run Code Online (Sandbox Code Playgroud)
也就是说,一种解除操作和跟踪SRP的方法.还有其他方法,例如简化您的操作:
First, it is getting list of hostnames
If the hostnames is empty, generate an empty response
Next, it loops through every hostnames that do the following things:
It checks whether the hostname is valid to send request
If not valid: remove hostname
Else: Generate the URL based on hostname
Next, it loops through every valid hostnames that do the following things:
Send the request
Translate the request response to domain response
Handle exceptions
Return response
Run Code Online (Sandbox Code Playgroud)
然后它也可以拆分成:
HostnameValidator: checks whether the hostname is valid to send request
--------------
ValidHostnameData: Getting list of hostnames
Loops through every hostnames that do the following things:
Checks whether the hostname is valid to send request
If not valid: remove hostname
Else: Generate the URL based on hostname
--------------
HostnameRequestSender: Send the request
--------------
HttpToDataResponse: Translate the request response to domain response
--------------
HostnameExceptionHandler: Handle exceptions
Run Code Online (Sandbox Code Playgroud)
当然还有其他方法可以做到这一点.我将实现细节留空,因为有很多方法可以实现它.
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |