Last active
February 11, 2017 18:58
-
-
Save Popalay/16cf34a5d558f31b787598afd34e882e to your computer and use it in GitHub Desktop.
Generate Multipart
This file contains hidden or 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
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))); | |
} | |
} |
This file contains hidden or 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
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