Created
May 11, 2016 12:59
-
-
Save budjb/ce90727caadbe9859dceee4593587966 to your computer and use it in GitHub Desktop.
These classes implement the RequestBuilder found at https://budjb.com/simplifying-jersey-client-with-a-builder-style-syntax/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright 2013 Bud Byrd | |
* | |
* 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.budjb.util.jaxrs | |
import com.sun.jersey.api.client.Client | |
import com.sun.jersey.api.client.ClientResponse | |
import com.sun.jersey.api.client.WebResource | |
import com.sun.jersey.api.client.WebResource.Builder | |
import com.sun.jersey.api.representation.Form | |
import javax.ws.rs.core.MediaType | |
import groovy.json.JsonSlurper | |
class RequestBuilder { | |
/** | |
* The URI to hit. | |
*/ | |
String uri = null | |
/** | |
* Query parameters. | |
*/ | |
Map query = [:] | |
/** | |
* Headers | |
*/ | |
Map headers = [:] | |
/** | |
* Form parameters | |
* | |
* Note that if this is set, this is used and body is ignored. | |
*/ | |
Map form = [:] | |
/** | |
* Accept header. | |
*/ | |
String accept = null | |
/** | |
* Whether to attempt to slurp JSON automatically. | |
*/ | |
boolean convertJson = true | |
/** | |
* Whether the caller expects a binary return. | |
* | |
* If true, the returned object will be a byte array. | |
* | |
* Note that this is a workaround to jersey not providing | |
* automatic content conversion based on mime type. | |
*/ | |
boolean binaryResponse = false | |
/** | |
* Body of the request - only useful on POST or PUT. | |
*/ | |
Object body = null | |
/** | |
* Performs a GET request. | |
* | |
* @return | |
*/ | |
private Object doGet() { | |
// Build the request | |
WebResource.Builder request = buildRequest() | |
// Do the request | |
ClientResponse response = request.get(ClientResponse) | |
// Handle the response | |
return handleResponse(response) | |
} | |
/** | |
* Performs a GET request | |
* | |
* @param uri Request URI | |
* @return | |
*/ | |
Object get(String uri) { | |
// Set the uri | |
this.uri = uri | |
// Run the command | |
return doGet() | |
} | |
/** | |
* Performs a GET request. | |
* | |
* @param closure | |
* @return | |
*/ | |
Object get(Closure closure) { | |
// Run the provided closure | |
run closure | |
// Run the command | |
return doGet() | |
} | |
/** | |
* Performs a PUT request. | |
* | |
* @return | |
*/ | |
private Object doPut() { | |
// Build the request | |
WebResource.Builder request = buildRequest() | |
// Do the request | |
ClientResponse response = request.put(ClientResponse, getRequestBody()) | |
// Handle the response | |
return handleResponse(response) | |
} | |
/** | |
* Performs a PUT request. | |
* | |
* @param uri Request URI | |
* @return | |
*/ | |
Object put(String uri, Object body = null) { | |
// Set the uri | |
this.uri = uri | |
// Set the request body | |
this.body = body | |
// Run the command | |
return doPut() | |
} | |
/** | |
* Performs a PUT request. | |
* | |
* @param closure | |
* @return | |
*/ | |
Object put(Closure closure) { | |
// Run the provided closure | |
run closure | |
// Run the command | |
return doPut() | |
} | |
/** | |
* Performs a POST request. | |
* | |
* @return | |
*/ | |
private Object doPost() { | |
// Build the request | |
WebResource.Builder request = buildRequest() | |
// Do the request | |
ClientResponse response = request.post(ClientResponse, getRequestBody()) | |
// Handle the response | |
return handleResponse(response) | |
} | |
/** | |
* Performs a POST request. | |
* | |
* @param uri Request URI | |
* @return | |
*/ | |
Object post(String uri, Object body = null) { | |
// Set the uri | |
this.uri = uri | |
// Set the request body | |
this.body = body | |
// Run the command | |
return doPost() | |
} | |
/** | |
* Performs a POST request. | |
* | |
* @param closure | |
* @return | |
*/ | |
Object post(Closure closure) { | |
// Run the provided closure | |
run closure | |
// Run the command | |
return doPost() | |
} | |
/** | |
* Performs a DELETE request. | |
* | |
* @return | |
*/ | |
private Object doDelete() { | |
// Build the request | |
WebResource.Builder request = buildRequest() | |
// Do the request | |
ClientResponse response = request.delete(ClientResponse) | |
// Handle the response | |
return handleResponse(response) | |
} | |
/** | |
* Performs a DELETE request. | |
* | |
* @param uri Request URI | |
* @return | |
*/ | |
Object delete(String uri) { | |
// Set the uri | |
this.uri = uri | |
// Run the command | |
return doDelete() | |
} | |
/** | |
* Performs a DELETE request. | |
* | |
* @param closure | |
* @return | |
*/ | |
Object delete(Closure closure) { | |
// Run the provided closure | |
run closure | |
// Run the command | |
return doDelete() | |
} | |
/** | |
* Checks for bad status codes, and does auto conversion of responses if necessary. | |
* | |
* @param response Response object to handle. | |
* @return The content of the response. | |
*/ | |
private Object handleResponse(ClientResponse response) { | |
def result = null | |
// Check if the caller wants the raw output | |
if (binaryResponse) { | |
result = response.getEntity(byte[]) | |
} | |
else { | |
// Get the content type | |
MediaType contentType = response.getType() | |
// Get the response entity | |
result = response.getEntity(String) | |
// Attempt to auto-convert JSON if enabled | |
if (convertJson && MediaType.APPLICATION_JSON_TYPE.isCompatible(contentType)) { | |
result = new JsonSlurper().parseText(result) | |
} | |
} | |
// Check the status | |
if (Math.floor(response.status / 100) != 2) { | |
throw new ResponseStatusException(response.status, result) | |
} | |
return result | |
} | |
/** | |
* Builds the request. | |
* | |
* @return Built request object. | |
*/ | |
private WebResource.Builder buildRequest() { | |
// Create the client with the uri | |
WebResource resource = Client.create().resource(uri) | |
// Set any query params | |
query.each { param, value -> | |
resource = resource.queryParam(param, value) | |
} | |
// Get the builder | |
WebResource.Builder builder = resource.getRequestBuilder() | |
// Set the accept type | |
if (accept) { | |
builder = builder.accept(accept) | |
} | |
// Set any headers | |
headers.each { param, value -> | |
builder = builder.header(param, value) | |
} | |
return builder | |
} | |
/** | |
* Runs a passed closure to implement builder-style operation. | |
* | |
* @param closure | |
*/ | |
private void run(Closure closure) { | |
Closure clone = closure.clone() | |
clone.delegate = this | |
clone.resolveStrategy = Closure.DELEGATE_ONLY | |
clone() | |
} | |
/** | |
* Returns the body entity to send with the request. | |
* | |
* This function will check if values were entered for a POST form, | |
* and if present build the form object and return it, ignoring | |
* any body that was added. If no form values are found, body is | |
* returned. | |
* | |
* @return | |
*/ | |
private Object getRequestBody() { | |
// If we have items in the form map, make a Form object and return it | |
if (form.size()) { | |
Form f = new Form() | |
form.each { key, value -> | |
f.add(key, value) | |
} | |
return f | |
} | |
// Use the basic provided body, even if it's empty | |
return body | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright 2013 Bud Byrd | |
* | |
* 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.budjb.util.jaxrs | |
class ResponseStatusException extends Exception { | |
int status | |
Object content | |
public ResponseStatusException(int status, Object content) { | |
super(content as String) | |
this.status = status | |
this.content = content | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment