Merge pull request #1032 from xhh/retrofit-string-resp

Retrofit template: return body string directly when failed to parse response body as JSON
This commit is contained in:
wing328 2015-07-30 15:58:05 +08:00
commit cc358cf9ce
5 changed files with 139 additions and 7 deletions

View File

@ -2,8 +2,20 @@ package {{invokerPackage}};
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import retrofit.RestAdapter;
import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.converter.GsonConverter;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;
public class ServiceGenerator {
// No need to instantiate this class.
@ -15,9 +27,63 @@ public class ServiceGenerator {
.create();
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint("{{basePath}}")
.setConverter(new GsonConverter(gson))
.setConverter(new GsonConverterWrapper(gson))
.build();
return adapter.create(serviceClass);
}
}
/**
* This wrapper is to take care of this case:
* when the deserialization fails due to JsonParseException and the
* expected type is String, then just return the body string.
*/
class GsonConverterWrapper implements Converter {
private GsonConverter converter;
public GsonConverterWrapper(Gson gson) {
converter = new GsonConverter(gson);
}
@Override public Object fromBody(TypedInput body, Type type) throws ConversionException {
byte[] bodyBytes = readInBytes(body);
TypedByteArray newBody = new TypedByteArray(body.mimeType(), bodyBytes);
try {
return converter.fromBody(newBody, type);
} catch (ConversionException e) {
if (e.getCause() instanceof JsonParseException && type.equals(String.class)) {
return new String(bodyBytes);
} else {
throw e;
}
}
}
@Override public TypedOutput toBody(Object object) {
return converter.toBody(object);
}
private byte[] readInBytes(TypedInput body) throws ConversionException {
InputStream in = null;
try {
in = body.in();
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[0xFFFF];
for (int len; (len = in.read(buffer)) != -1;)
os.write(buffer, 0, len);
os.flush();
return os.toByteArray();
} catch (IOException e) {
throw new ConversionException(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
}
}
}
}

View File

@ -2,8 +2,20 @@ package io.swagger.client;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import retrofit.RestAdapter;
import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.converter.GsonConverter;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;
public class ServiceGenerator {
// No need to instantiate this class.
@ -15,9 +27,63 @@ public class ServiceGenerator {
.create();
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint("http://petstore.swagger.io/v2")
.setConverter(new GsonConverter(gson))
.setConverter(new GsonConverterWrapper(gson))
.build();
return adapter.create(serviceClass);
}
}
/**
* This wrapper is to take care of this case:
* when the deserialization fails due to JsonParseException and the
* expected type is String, then just return the body string.
*/
class GsonConverterWrapper implements Converter {
private GsonConverter converter;
public GsonConverterWrapper(Gson gson) {
converter = new GsonConverter(gson);
}
@Override public Object fromBody(TypedInput body, Type type) throws ConversionException {
byte[] bodyBytes = readInBytes(body);
TypedByteArray newBody = new TypedByteArray(body.mimeType(), bodyBytes);
try {
return converter.fromBody(newBody, type);
} catch (ConversionException e) {
if (e.getCause() instanceof JsonParseException && type.equals(String.class)) {
return new String(bodyBytes);
} else {
throw e;
}
}
}
@Override public TypedOutput toBody(Object object) {
return converter.toBody(object);
}
private byte[] readInBytes(TypedInput body) throws ConversionException {
InputStream in = null;
try {
in = body.in();
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[0xFFFF];
for (int len; (len = in.read(buffer)) != -1;)
os.write(buffer, 0, len);
os.flush();
return os.toByteArray();
} catch (IOException e) {
throw new ConversionException(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
}
}
}
}

View File

@ -89,14 +89,14 @@ public interface PetApi {
/**
* Deletes a pet
*
* @param apiKey
* @param petId Pet id to delete
* @param apiKey
* @return Void
*/
@DELETE("/pet/{petId}")
Void deletePet(
@Header("api_key") String apiKey,@Path("petId") Long petId
@Path("petId") Long petId,@Header("api_key") String apiKey
);
/**

View File

@ -34,13 +34,13 @@ public class Pet {
**/
@ApiModelProperty(required = true, value = "")
@SerializedName("photoUrls")
private List<String> photoUrls = new ArrayList<String>() ;
private List<String> photoUrls = null;
/**
**/
@ApiModelProperty(value = "")
@SerializedName("tags")
private List<Tag> tags = new ArrayList<Tag>() ;
private List<Tag> tags = null;
public enum StatusEnum {
available, pending, sold,
};

View File

@ -120,7 +120,7 @@ public class PetApiTest {
api.addPet(pet);
Pet fetched = api.getPetById(pet.getId());
api.deletePet(null, fetched.getId());
api.deletePet(fetched.getId(), null);
try {
fetched = api.getPetById(fetched.getId());