
org.crazyyak.dev.jerseyclient.SimpleRestClient Maven / Gradle / Ivy
package org.crazyyak.dev.jerseyclient;
import org.crazyyak.dev.common.IoUtils;
import org.crazyyak.dev.common.StringUtils;
import org.crazyyak.dev.common.exceptions.ApiException;
import org.crazyyak.dev.common.json.JsonTranslator;
import org.crazyyak.dev.common.net.HttpStatusCode;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.uri.internal.JerseyUriBuilder;
import javax.ws.rs.client.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SimpleRestClient {
public static final Map EMPTY_QUERY = Collections.emptyMap();
private final boolean notFoundToNull;
private final JsonTranslator translator;
private final String apiUrl;
private final String userName;
private final String password;
public SimpleRestClient(JsonTranslator translator, String apiUrl) {
this(true, translator, parseUrl(apiUrl), parseUserFromUrl(apiUrl), parsePassFromUrl(apiUrl));
}
public SimpleRestClient(JsonTranslator translator, String apiUrl, String authentication) {
this(true, translator, parseUrl(apiUrl), parseUserFromAuth(authentication), parsePassFromAuth(authentication));
}
public SimpleRestClient(JsonTranslator translator, String apiUrl, String userName, String password) {
this(true, translator, parseUrl(apiUrl), userName, password);
}
public SimpleRestClient(boolean notFoundToNull, JsonTranslator translator, String apiUrl, String userName, String password) {
this.apiUrl = apiUrl;
this.userName = userName;
this.password = password;
this.translator = translator;
this.notFoundToNull = notFoundToNull;
}
public static String parseUrl(String apiUrl) {
if (StringUtils.isBlank(apiUrl)) {
return null;
}
String auth = parseAuth(apiUrl);
if (StringUtils.isBlank(auth)) {
return apiUrl;
} else if (apiUrl.toLowerCase().startsWith("http://")) {
return apiUrl.replace("http://"+auth+"@", "http://");
} else if (apiUrl.toLowerCase().startsWith("https://")) {
return apiUrl.replace("https://"+auth+"@", "https://");
} else {
String msg = String.format("Unable to parse the specified URL - does not start with \"http://\" or \"https://\".");
throw new IllegalArgumentException(msg);
}
}
public static String parseAuth(String apiUrl) {
int pos;
if (StringUtils.isBlank(apiUrl)) {
return null;
} else if (apiUrl.toLowerCase().startsWith("http://")) {
pos = 7;
} else if (apiUrl.toLowerCase().startsWith("https://")) {
pos = 8;
} else {
String msg = String.format("Unable to parse the specified URL - does not start with \"http://\" or \"https://\".");
throw new IllegalArgumentException(msg);
}
String contents = apiUrl.substring(pos);
pos = contents.indexOf("/");
if (pos < 0) pos = contents.length();
String left = contents.substring(0, pos);
pos = left.indexOf("@");
if (pos < 0) {
return null;
} else {
return left.substring(0, pos);
}
}
public static String parseUserFromUrl(String apiUrl) {
String auth = parseAuth(apiUrl);
return parseUserFromAuth(auth);
}
public static String parsePassFromUrl(String apiUrl) {
String auth = parseAuth(apiUrl);
return parsePassFromAuth(auth);
}
public static String parseUserFromAuth(String authentication) {
if (StringUtils.isBlank(authentication)) {
return null;
}
int pos = authentication.indexOf(":");
if (pos < 0) return authentication;
String name = authentication.substring(0, pos);
return StringUtils.isNotBlank(name) ? name : null;
}
public static String parsePassFromAuth(String authentication) {
if (StringUtils.isBlank(authentication)) {
return null;
}
int pos = authentication.indexOf(":");
if (pos < 0) return null;
String pass = authentication.substring(pos+1);
return StringUtils.isNotBlank(pass) ? pass : null;
}
public void post(String subUrl) {
post(null, subUrl, null);
}
public void post(String subUrl, Object entity) {
post(null, subUrl, entity);
}
public T post(Class returnType, String subUrl) {
return post(returnType, subUrl, null);
}
public T post(Class returnType, String subUrl, Object entity) {
Invocation.Builder builder = builder(subUrl, Collections.emptyMap(), MediaType.APPLICATION_JSON);
String json = (entity == null) ? null : translator.toJson(entity);
Response response = builder.post(Entity.entity(json, MediaType.APPLICATION_JSON_TYPE));
return translateResponse(returnType, response);
}
public T get(Class returnType, String subUrl, String... queryStrings) {
Map queryMap = new HashMap<>();
queryMap.putAll(toMap(queryStrings));
return get(returnType, subUrl, queryMap, "application/json");
}
public T get(Class returnType, String subUrl, Map queryMap) {
return get(returnType, subUrl, queryMap, "application/json");
}
public T get(Class returnType, String subUrl, Map queryMap, String...acceptedResponseTypes) {
Invocation.Builder builder = builder(subUrl, queryMap, acceptedResponseTypes);
Response response = builder.get(Response.class);
return translateResponse(returnType, response);
}
private T translateResponse(Class returnType, Response response) {
if (response.getStatus() == 404 && notFoundToNull) return null;
assertResponse(response.getStatus());
Object retValue;
if (returnType == null) {
// return object not expected
return null;
} else if (Response.class.equals(returnType)) {
retValue = response;
} else {
// The return type will use the string content...
String content = response.readEntity(String.class);
if (String.class.equals(returnType)) {
// A simple string - clean up after MS Windows
retValue = content.replaceAll("\r", "");
} else {
// A json object to be translated.
retValue = translator.fromJson(returnType, content);
}
}
// noinspection unchecked
return (T)retValue;
}
public byte[] getBytes(String subUrl, Map queryMap, String...acceptedResponseTypes) throws IOException {
Invocation.Builder builder = builder(subUrl, queryMap, acceptedResponseTypes);
Response response = builder.get(Response.class);
if (response.getStatus() == 404 && notFoundToNull) return null;
assertResponse(response.getStatus());
InputStream in = (InputStream)response.getEntity();
return IoUtils.toBytes(in);
}
public List getList(Class returnType, String subUrl, String...queryStrings) {
Map queryMap = new HashMap<>();
queryMap.putAll(toMap(queryStrings));
return getList(returnType, subUrl, queryMap);
}
public List getList(Class returnType, String subUrl, Map queryMap) {
Invocation.Builder builder = builder(subUrl, queryMap, "application/json");
Response response = builder.get();
if (response.getStatus() == 404 && notFoundToNull) return null;
assertResponse(response.getStatus());
String content = response.readEntity(String.class);
// A json object to be translated.
// noinspection unchecked
return translator.fromJson(List.class, content, returnType);
}
public JsonTranslator getTranslator() {
return translator;
}
public String getApiUrl() {
return apiUrl;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
protected void assertResponse(int status) {
HttpStatusCode statusCode = HttpStatusCode.findByCode(status);
if (statusCode.isOk() == false) {
String msg = String.format("Unexpected response: %s %s", status, statusCode.getReason());
throw new ApiException(statusCode, msg);
}
}
protected Map toMap(String...keyValuePairs) {
if (keyValuePairs == null) {
return new HashMap<>();
}
Map map = new HashMap<>();
for (String pair : keyValuePairs) {
int pos = (pair == null) ? -1 : pair.indexOf("=");
if (pair == null) {
map.put(null,null);
} else if (pos < 0) {
map.put(pair, null);
} else {
String key = pair.substring(0, pos);
String value = pair.substring(pos+1);
map.put(key, value);
}
}
return map;
}
protected Invocation.Builder builder(String url, Map queryMap, String...acceptedResponseTypes) {
Client client = ClientBuilder.newBuilder().build();
UriBuilder uriBuilder = new JerseyUriBuilder().uri(getApiUrl()).path(url);
for (Map.Entry queryParam : queryMap.entrySet()) {
uriBuilder.queryParam(queryParam.getKey(), queryParam.getValue());
}
WebTarget target = client.target(uriBuilder);
if (StringUtils.isNotBlank(getUserName())) {
target = target.register(HttpAuthenticationFeature.basic(getUserName(), getPassword()));
}
return target.request(acceptedResponseTypes);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy