对于担心添加大量组件会使应用程序设置复杂的人来说,我可能会考虑使用一个快速而简单的纯Java解决方案。
这里有一个有趣的东西,我使用Spring的RestTemplate想出来的。如果您熟悉拦截器、切面和其他可以包装方法调用的内容,您可以将这些原则应用于所有不同的RestTemplate REST调用。请参见RestTemplate javadoc。
import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.*;
import org.springframework.web.util.UriTemplate;
import org.springframework.web.util.UriUtils;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
public class Stuff {
Collection<String> serverList;
ServerLookup serverLookup;
interface ServerLookup {
Iterator<String> getValidServerListIterator();
void markUnreachableServer(String url);
}
@Test
public void testNormalRestTemplate() throws Exception {
RestTemplate restTemplate = new RestTemplate();
Iterator<String> serverIterator = serverLookup.getValidServerListIterator();
while (serverIterator.hasNext()) {
String server = serverIterator.next();
try {
Object obj = restTemplate.getForObject(server + "/objectIdentifier/511", Object.class);
break;
} catch (ResourceAccessException e) {
serverLookup.markUnreachableServer(server);
}
}
}
@Test
public void testMyRestTemplate() {
RestTemplate rt = new MyRestTemplate();
Object obj = rt.getForObject("/objectIdentifier/511", Object.class);
rt.delete("/objectIdentifier/511");
}
class MyRestTemplate extends RestTemplate {
@Override
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {
Iterator<String> serverIterator = serverLookup.getValidServerListIterator();
while (serverIterator.hasNext()) {
String server = serverIterator.next();
String fullUrl = server + url;
UriTemplate uriTemplate = new HttpUrlTemplate(fullUrl);
URI expanded = uriTemplate.expand(urlVariables);
try {
return doExecute(expanded, method, requestCallback, responseExtractor);
} catch (ResourceAccessException e) {
serverLookup.markUnreachableServer(server);
}
}
throw new RuntimeException("Unable to reach any servers in the server list for " + url);
}
@Override
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor, Map<String, ?> urlVariables) throws RestClientException {
Iterator<String> serverIterator = serverLookup.getValidServerListIterator();
while (serverIterator.hasNext()) {
String server = serverIterator.next();
String fullUrl = server + url;
UriTemplate uriTemplate = new HttpUrlTemplate(fullUrl);
URI expanded = uriTemplate.expand(urlVariables);
try {
return doExecute(expanded, method, requestCallback, responseExtractor);
} catch (ResourceAccessException e) {
serverLookup.markUnreachableServer(server);
}
}
throw new RuntimeException("Unable to reach any servers in the server list for " + url);
}
class HttpUrlTemplate extends UriTemplate {
public HttpUrlTemplate(String uriTemplate) {
super(uriTemplate);
}
@Override
protected URI encodeUri(String uri) {
try {
String encoded = UriUtils.encodeHttpUrl(uri, "UTF-8");
return new URI(encoded);
}
catch (UnsupportedEncodingException ex) {
throw new IllegalStateException(ex);
}
catch (URISyntaxException ex) {
throw new IllegalArgumentException("Could not create HTTP URL from [" + uri + "]: " + ex, ex);
}
}
}
}
}