-
Notifications
You must be signed in to change notification settings - Fork 6k
Support binary data in body #669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Would like this implantation especially with tests. Thank you! |
The following workaround worked for me, and currently I'm not planning to modify the codegen sources. Preconditions:
package com.intuit.idps;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource.Builder;
import io.swagger.client.ApiException;
import io.swagger.client.ApiInvoker;
import java.util.Map;
import java.io.DataInputStream;
import javax.ws.rs.core.Response.Status.Family;
import java.io.IOException;
public class BinaryApiInvoker extends ApiInvoker {
static {
INSTANCE = new BinaryApiInvoker();
setUserAgent("Java-Swagger");
}
public static ApiInvoker getInstance() {
return INSTANCE;
}
public byte[] invokeBinaryAPI(String host, String path, String method, Map<String, String> queryParams, byte[] body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
Client client = getClient(host);
StringBuilder b = new StringBuilder();
for(String key : queryParams.keySet()) {
String value = queryParams.get(key);
if (value != null){
if(b.toString().length() == 0 && !path.contains("?"))
b.append("?");
else
b.append("&");
b.append(escapeString(key)).append("=").append(escapeString(value));
}
}
String querystring = b.toString();
Builder builder = client.resource(host + path + querystring).accept("application/octet-stream");
for(String key : headerParams.keySet()) {
builder = builder.header(key, headerParams.get(key));
}
for(String key : defaultHeaderMap.keySet()) {
if(!headerParams.containsKey(key)) {
builder = builder.header(key, defaultHeaderMap.get(key));
}
}
ClientResponse response = null;
if("GET".equals(method)) {
response = (ClientResponse) builder.get(ClientResponse.class);
}
else if ("POST".equals(method)) {
if(body == null)
response = builder.post(ClientResponse.class, null);
else
response = builder.type(contentType).post(ClientResponse.class, body);
}
else if ("PUT".equals(method)) {
if(body == null)
response = builder.put(ClientResponse.class);
else {
response = builder.type(contentType).put(ClientResponse.class, body);
}
}
else if ("DELETE".equals(method)) {
if(body == null)
response = builder.delete(ClientResponse.class);
else
response = builder.type(contentType).delete(ClientResponse.class, body);
}
else {
throw new ApiException(405, "unknown method " + method);
}
if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) {
return null;
}
else if(response.getClientResponseStatus().getFamily() == Family.SUCCESSFUL) {
if(response.hasEntity()) {
DataInputStream stream = new DataInputStream(response.getEntityInputStream());
byte[] data = new byte[response.getLength()];
try {
stream.readFully(data);
} catch (IOException ex) {
throw new ApiException(500, "Error obtaining binary response data");
}
return data;
}
else {
return new byte[0];
}
}
else {
String message = "error";
if(response.hasEntity()) {
try{
message = String.valueOf(response.getEntity(String.class));
}
catch (RuntimeException e) {
// e.printStackTrace();
}
}
throw new ApiException(
response.getClientResponseStatus().getStatusCode(),
message);
}
}
} Each time after generating the code, run the following commands: sed -i -- '3 i\
import com.intuit.idps.BinaryApiInvoker;' src/main/java/io/swagger/client/api/DefaultApi.java
sed -i -- '/ApiInvoker apiInvoker/ c\
BinaryApiInvoker apiInvoker = (BinaryApiInvoker)BinaryApiInvoker.getInstance();' src/main/java/io/swagger/client/api/DefaultApi.java
sed -i -- '/String binaryData/,/ApiException ex/{ s/public String/public byte[]/; s/String binaryData/byte[] binaryData/; s/String response/byte[] response/; s/invokeAPI/invokeBinaryAPI/; s/postBody,/binaryData,/; s/(String).*/response;/;}' src/main/java/io/swagger/client/api/DefaultApi.java
sed -i -- 's/\&/\&/g' src/main/java/io/swagger/client/api/DefaultApi.java # codegen escapes & in path, this may be an issue?
sed -i -- 's/private /protected /g' src/main/java/io/swagger/client/ApiInvoker.java I'm not closing the issue (anyway, preferred to implement it without workaround). |
Java API client now supports |
Hello,
Our Swagger 2.0 specs include several services that pass and receive binary data in the body (type="string, format="byte"), represented by content-type application/octet-stream (with respective
consumes
andproduces
clauses).When generating Java for these services, code generator treats input and output as
String
, which is not suitable for binary data.It would be advisable to generate
byte[]
parameter, and also avoid serialization treatment.I would consider contributing this code (for Java only), if you find this appropriate.
Thanks,
Michael.
The text was updated successfully, but these errors were encountered: