
net.anthavio.httl.HttlRequestBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hatatitla Show documentation
Show all versions of hatatitla Show documentation
Compact but tweakable REST client library you have been dreaming of
The newest version!
package net.anthavio.httl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import net.anthavio.httl.HttlRequest.Method;
import net.anthavio.httl.HttlResponseExtractor.ExtractedResponse;
import net.anthavio.httl.HttlSender.Multival;
import net.anthavio.httl.util.Cutils;
import net.anthavio.httl.util.GenericType;
import net.anthavio.httl.util.HttlUtil;
import net.anthavio.httl.util.HttpDateUtil;
/**
* Equivalent of Jersey/JAX-RS-2.0 RequestBuilder
*
* @author martin.vanek
*
*/
public abstract class HttlRequestBuilder> {
protected final HttlSender sender;
protected final Method method;
protected final String urlPath;
protected final Multival headers;
protected final Multival parameters;
protected final HttlParameterSetter paramSetter;
protected Integer readTimeoutMillis;
public HttlRequestBuilder(HttlSender sender, Method method, String urlPath) {
if (sender == null) {
throw new IllegalArgumentException("sender is null");
}
this.sender = sender;
this.headers = new Multival();
this.parameters = new Multival();
if (method == null) {
throw new IllegalArgumentException("method is null");
}
this.method = method;
if (Cutils.isEmpty(urlPath)) {
throw new IllegalArgumentException("url path is blank");
}
this.urlPath = urlPath;
this.paramSetter = sender.getConfig().getParamSetter();
}
public HttlSender getSender() {
return sender;
}
public Method getMethod() {
return method;
}
public Multival getHeaders() {
return headers;
}
public Multival getParameters() {
return parameters;
}
public X timeout(int value, TimeUnit unit) {
this.readTimeoutMillis = (int) unit.toMillis(value);
return getX();
}
// headers section...
/**
* Set Headers replacing all existing
*/
public X setHeaders(Map headers) {
this.headers.clear();
addHeaders(headers);
return getX();
}
/**
* Add Headers
*/
public X addHeaders(Map headers) {
Set keySet = headers.keySet();
for (String key : keySet) {
Object object = headers.get(key);
if (object instanceof Collection) {
this.headers.add(key, (Collection) object);
} else {
this.headers.add(key, String.valueOf(object));
}
}
return getX();
}
/**
* Set Header with single value
* If Header already exists, old value(s) will be replaced
*/
public X setHeader(String name, String value) {
this.headers.set(name, value);
return getX();
}
public X setHeader(String name, Date value) {
this.headers.set(name, HttpDateUtil.formatDate(value));
return getX();
}
/**
* Set Header with multiple values
* If Header already exists, old value(s) will be replaced
*/
public X setHeader(String name, String... values) {
this.headers.set(name, values);
return getX();
}
public X setHeader(String name, Collection values) {
this.headers.set(name, values);
return getX();
}
/**
* Formats the given date according to the RFC 1123 pattern.
*/
public X header(String name, Date value) {
this.headers.add(name, HttpDateUtil.formatDate(value));
return getX();
}
/**
* Add Header with multiple values
*/
public X header(String name, String... values) {
this.headers.add(name, values);
return getX();
}
public X header(String name, Collection values) {
this.headers.add(name, values);
return getX();
}
/**
* Add Request Header
*/
public X header(String name, String value) {
headers.add(name, value);
return getX();
}
// parameters section...
public X param(String name, int value) {
paramSetter.handle(parameters, false, name, value);
return getX();
}
public X param(String name, String value) {
paramSetter.handle(parameters, false, name, value);
return getX();
}
public X param(String name, Date value) {
paramSetter.handle(parameters, false, name, value);
return getX();
}
public X param(String name, Date value, String format) {
if (value != null) {
String formated = new SimpleDateFormat(format).format(value);
paramSetter.handle(parameters, false, name, formated);
} else {
paramSetter.handle(parameters, false, name, null);
}
return getX();
}
/**
* Set parameters frm Map
*/
public X params(Map map) {
if (map != null) {
Set keySet = map.keySet();
for (String name : keySet) {
Object value = map.get(name);
paramSetter.handle(parameters, false, name, value);
}
}
return getX();
}
/**
* Set/Add parameter with single value.
*/
public X param(boolean reset, String name, Object value) {
paramSetter.handle(parameters, reset, name, value);
return getX();
}
/**
* Add parameter with single value.
*/
public X param(String name, Object value) {
return param(false, name, value);
}
/**
* Add parameter with multiple values.
*/
public X param(String name, Collection> values) {
return param(false, name, values);
}
public X param(boolean reset, String name, Collection> values) {
paramSetter.handle(parameters, reset, name, values);
return getX();
}
public X param(boolean reset, String name, Object... values) {
paramSetter.handle(parameters, reset, name, values);
return getX();
}
/**
* Add parameter with multiple values.
*/
public X param(String name, Object... values) {
paramSetter.handle(parameters, false, name, values);
return getX();
}
/**
* Add Matrix Url Parameter
*
* Matrix - http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-matrix-variables
*/
public X matrix(String name, Object value) {
return matrix(false, name, value);
}
/**
* Matrix parameter is allways part of URL.
*/
public X matrix(boolean reset, String name, Object value) {
if (name.charAt(0) != ';') {
name = ";" + name;
}
paramSetter.handle(parameters, reset, name, value);
return getX();
}
/**
* Path parameter is allways part of url
*/
public X pathParam(String name, Object value) {
if (name.charAt(0) != '{') {
name = "{" + name + "}";
}
if (urlPath.indexOf(name) == -1) {
throw new IllegalArgumentException("URL path variable: " + name + " not found in: " + urlPath);
}
if (value == null) {
throw new IllegalArgumentException("Null value for path parameter " + name + " is illegal");
} else if (value instanceof Collection) {
throw new IllegalArgumentException("Collection value for path parameter " + name + " is illegal");
} else if (value.getClass().isArray()) {
throw new IllegalArgumentException("Array value for path parameter " + name + " is illegal");
} else {
paramSetter.handle(parameters, true, name, value);
}
return getX();
}
public abstract HttlRequest build();
/**
* Buid and execute Request and then return raw unprocessed Response.
* Response is open and caller is responsibe for closing.
*/
public HttlResponse execute() {
HttlRequest request = build();
return sender.execute(request);
}
/**
* Buid and execute Request and then let ResponseHandler parameter to process Response.
*/
public void execute(HttlResponseHandler handler) {
HttlRequest request = build();
sender.execute(request, handler);
}
/**
* Buid and execute Request and then extract response.
*/
public ExtractedResponse extract(Class clazz) {
HttlRequest request = build();
return sender.extract(request, clazz);
}
/**
* Buid and execute Request and then extract response.
*/
public ExtractedResponse extract(GenericType typeReference) {
HttlRequest request = build();
return sender.extract(request, typeReference);
}
/**
* Buid and execute Request and then extract response.
*/
public ExtractedResponse extract(HttlResponseExtractor extractor) {
HttlRequest request = build();
return sender.extract(request, extractor);
}
public Future start() {
HttlRequest request = build();
return sender.start(request);
}
public Future> start(HttlResponseExtractor extractor) {
HttlRequest request = build();
return sender.start(request, extractor);
}
public Future> start(Class resultType) {
HttlRequest request = build();
return sender.start(request, resultType);
}
public void start(HttlResponseHandler handler) {
HttlRequest request = build();
sender.start(request, handler);
}
@Override
public String toString() {
return "HttlRequestBuilder [sender=" + sender + ", method=" + method + ", urlPath=" + urlPath + ", headers="
+ headers + ", parameters=" + parameters + "]";
}
protected abstract X getX(); //Generic trick
/**
* GET, HEAD, DELETE, OPTIONS
*
* @author martin.vanek
*
*/
public static class BodylessRequestBuilder extends HttlRequestBuilder {
public BodylessRequestBuilder(HttlSender httpSender, Method method, String urlPath) {
super(httpSender, method, urlPath);
}
@Override
protected BodylessRequestBuilder getX() {
return this;
}
public HttlRequest build() {
List interceptors = sender.getConfig().getBuilderVisitors();
for (HttlBuilderVisitor interceptor : interceptors) {
interceptor.visit(this);
}
return new HttlRequest(sender, method, urlPath, parameters, headers, null, readTimeoutMillis);
}
}
/**
* PUT, POST
*
* @author martin.vanek
*
*/
public static class BodyfulRequestBuilder extends HttlRequestBuilder {
public BodyfulRequestBuilder(HttlSender httpSender, Method method, String path) {
super(httpSender, method, path);
}
protected HttlBody body;
/**
* Set body as String
*/
public BodyfulRequestBuilder body(String payload, String mediaType) {
if (payload == null) {
throw new HttlRequestException("Payload string is null");
}
setContentType(mediaType);
this.body = new HttlBody(payload);
return this;
}
/**
* Set request body as byte array
*/
public BodyfulRequestBuilder body(byte[] payload, String mediaType) {
if (payload == null) {
throw new HttlRequestException("Payload byte[] is null");
}
setContentType(mediaType);
this.body = new HttlBody(payload);
return this;
}
/**
* Set body as InputStream
*/
public BodyfulRequestBuilder body(InputStream stream, String mediaType, boolean buffer) {
if (stream == null) {
throw new HttlRequestException("Payload stream is null");
}
setContentType(mediaType);
if (buffer) {
try {
byte[] bytes = HttlUtil.readAsBytes(stream, HttlUtil.KILO16);
this.body = new HttlBody(bytes);
} catch (IOException iox) {
throw new HttlRequestException(iox);
}
} else {
this.body = new HttlBody(stream);
}
return this;
}
/**
* Set body as Reader
*/
public BodyfulRequestBuilder body(Reader reader, String mediaType, boolean buffer) {
if (reader == null) {
throw new HttlRequestException("Payload reader is null");
}
setContentType(mediaType);
if (buffer) {
try {
String string = HttlUtil.readAsString(reader, HttlUtil.KILO16);
this.body = new HttlBody(string);
} catch (IOException iox) {
throw new HttlRequestException(iox);
}
} else {
this.body = new HttlBody(reader);
}
return this;
}
/**
* Set body as non buffered
*/
public BodyfulRequestBuilder body(Object body, String mediaType) {
return body(body, mediaType, false);
}
/**
* Will make best effort to figure out what is body type and how it should be sent with request
*
* Content-Type header must be specified before
*/
public BodyfulRequestBuilder body(Object body) {
return body(body, null);
}
private String[] setContentType(String mediaType) {
if (mediaType == null) {
mediaType = headers.getFirst(HttlConstants.Content_Type);
if (mediaType == null) {
mediaType = sender.getConfig().getDefaultHeaders().getFirst(HttlConstants.Content_Type);
if (mediaType == null) {
throw new HttlRequestException("Content-Type not found. Cannot set request body");
}
}
}
String[] mimeTypeAndCharset = HttlUtil.splitContentType(mediaType, sender.getConfig().getCharset());
headers.set(HttlConstants.Content_Type, mimeTypeAndCharset[0] + "; charset=" + mimeTypeAndCharset[1]);
return mimeTypeAndCharset;
}
/**
* payload can be byte[], String, InputStream, Reader or anything else that can be marshalled
*/
public BodyfulRequestBuilder body(Object payload, String mediaType, boolean buffer) {
if (payload == null) {
throw new HttlRequestException("Payload is null");
}
if (payload instanceof InputStream) {
return body((InputStream) payload, mediaType, buffer);
} else if (payload instanceof Reader) {
return body((Reader) payload, mediaType, buffer);
} else if (payload instanceof String) {
return body((String) payload, mediaType);
} else if (payload instanceof byte[]) {
return body((byte[]) payload, mediaType);
} else {
//marshalling...
String[] contentType = setContentType(mediaType);
if (buffer) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
sender.getMarshaller().marshall(payload, contentType[0], contentType[1], baos);
} catch (IOException iox) {
throw new HttlRequestException(iox);
}
this.body = new HttlBody(baos.toByteArray());
} else {
this.body = new HttlBody(payload);
}
}
return getX();
}
@Override
public HttlRequest build() {
List visitors = sender.getConfig().getBuilderVisitors();
for (HttlBuilderVisitor visitor : visitors) {
visitor.visit(this);
}
return new HttlRequest(sender, method, urlPath, parameters, headers, body, readTimeoutMillis);
}
@Override
protected BodyfulRequestBuilder getX() {
return this;
}
}
public static String[] digContentType(Multival requestHeaders, SenderConfigurer config) {
return digContentType(requestHeaders.getFirst(HttlConstants.Content_Type),
config.getDefaultHeaders().getFirst(HttlConstants.Content_Type), config.getCharset());
}
/**
* @param requestContentType - can be null
* @param defaultMediaType - can be null
* @param defaultCharset = never null
* @return
*/
public static String[] digContentType(String requestContentType, String defaultContentType, String defaultCharset) {
String mediaType;
String charset;
if (requestContentType != null) {
int idxMediaEnd = requestContentType.indexOf(";");
if (idxMediaEnd != -1) {
mediaType = requestContentType.substring(0, idxMediaEnd);
} else {
mediaType = requestContentType;
}
int idxCharset = requestContentType.indexOf("charset=");
if (idxCharset != -1) {
charset = requestContentType.substring(idxCharset + 8);
} else {
charset = defaultCharset;
}
} else if (defaultContentType != null) {
int idxMediaEnd = defaultContentType.indexOf(";");
if (idxMediaEnd != -1) {
mediaType = defaultContentType.substring(0, idxMediaEnd);
} else {
mediaType = defaultContentType;
}
int idxCharset = defaultContentType.indexOf("charset=");
if (idxCharset != -1) {
charset = defaultContentType.substring(idxCharset + 8);
} else {
charset = defaultCharset;
}
} else {
mediaType = null;
charset = defaultCharset;
}
return new String[] { mediaType, charset };
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy