Skip to content

Instantly share code, notes, and snippets.

@Popalay
Last active February 11, 2017 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Popalay/16cf34a5d558f31b787598afd34e882e to your computer and use it in GitHub Desktop.
Save Popalay/16cf34a5d558f31b787598afd34e882e to your computer and use it in GitHub Desktop.
Generate Multipart
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.webkit.MimeTypeMap;
import com.google.gson.annotations.SerializedName;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public final class MultipartFactory {
private final static String PART_POSTFIX = "]";
private final static String PART_PREFIX = "[";
private final Object mObject;
@NonNull
public static MultipartFactory create(@NonNull Object object) {
return new MultipartFactory(object);
}
@WorkerThread
public MultipartBody getMultipartBody() {
if (!mObject.getClass().isAnnotationPresent(Partable.class)) {
throw new IllegalArgumentException(mObject.getClass().getSimpleName() + " must has Partable annotation");
}
final String partName = mObject.getClass().getAnnotation(Partable.class).value();
final List<MultipartBody.Part> parts = generateParts(partName, mObject, null, null, false);
final MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (MultipartBody.Part part : parts) {
requestBodyBuilder.addPart(part);
}
return requestBodyBuilder.build();
}
private MultipartFactory(@NonNull Object object) {
mObject = object;
}
private List<MultipartBody.Part> generateParts(String partName, @NonNull Object object,
@Nullable String parentPrefix, @Nullable String parentPostfix, boolean isListItem) {
partName += isListItem ? PART_PREFIX + PART_POSTFIX : PART_PREFIX;
final List<MultipartBody.Part> parts = new ArrayList<>();
if (object instanceof File) {
putFile(partName, parts, (File) object);
return parts;
}
final String prefix = parentPrefix == null ? partName : parentPrefix + partName;
final String postfix = parentPostfix == null ? PART_POSTFIX : parentPostfix + PART_POSTFIX;
final Field[] fields = object.getClass().getDeclaredFields();
SerializedName serialName;
Object value;
for (Field field : fields) {
value = getFieldValue(object, field);
if (value != null) {
serialName = field.getAnnotation(SerializedName.class);
if (serialName != null) {
if (value.getClass().isAnnotationPresent(Partable.class)) {
parts.addAll(generateParts(serialName.value(), value, prefix, postfix, false));
} else if (value instanceof List) {
for (Object o : ((List) value)) {
parts.addAll(generateParts(serialName.value(), o, prefix, postfix, true));
}
} else {
parts.add(MultipartBody.Part.createFormData(prefix + serialName.value() + postfix,
value.toString()));
}
}
}
}
return parts;
}
@Nullable
private Object getFieldValue(@NonNull Object object, @NonNull Field field) {
try {
field.setAccessible(true);
return field.get(object);
} catch (IllegalAccessException e) {
return null;
}
}
private String getMimeType(File file) {
String type = null;
final String extension = MimeTypeMap.getFileExtensionFromUrl(file.getPath());
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
private void putFile(String name, @NonNull List<MultipartBody.Part> parts, File file) {
parts.add(MultipartBody.Part.createFormData(name, file.getName(),
RequestBody.create(MediaType.parse(getMimeType(file)), file)));
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Partable {
String value() default "";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment