Skip to content

Instantly share code, notes, and snippets.

@kamikat
Last active August 29, 2015 14:04
Show Gist options
  • Save kamikat/01030d2ebc6106537f7f to your computer and use it in GitHub Desktop.
Save kamikat/01030d2ebc6106537f7f to your computer and use it in GitHub Desktop.
RoboSpice request uploading file to Qiniu CDN with upload progress notification
import com.octo.android.robospice.request.springandroid.SpringAndroidSpiceRequest;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class QiniuUploadRequest extends SpringAndroidSpiceRequest<QiniuKey> {
public static class QiniuKey {
public String key;
public String hash;
}
private File mLocalFile;
private String mResKey;
private String mToken;
public QiniuUploadRequest(File localFile, String resKey, String token) {
super(QiniuKey.class);
mLocalFile = localFile;
mResKey = resKey;
mToken = token;
}
@Override
public QiniuKey loadDataFromNetwork() throws Exception {
RestTemplate rest = getRestTemplate();
ClientHttpRequestFactory factory = rest.getRequestFactory();
// workaround: avoid read full file into memory
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
rest.setRequestFactory(requestFactory);
rest.getMessageConverters().add(new FormHttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("key", mResKey);
parts.add("token", mToken);
parts.add("file", new ProgressiveFileSystemResource(mLocalFile));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(parts, requestHeaders);
ResponseEntity<QiniuKey> response = rest.exchange("http://up.qiniu.com", HttpMethod.POST, requestEntity, QiniuKey.class);
// restore request factory
rest.setRequestFactory(factory);
return response.getBody();
}
class ProgressiveFileSystemResource extends FileSystemResource {
public ProgressiveFileSystemResource(File file) {
super(file);
}
@Override
public InputStream getInputStream() throws IOException {
return new ProgressiveFileInputStream(getFile());
}
}
class ProgressiveFileInputStream extends FileInputStream {
private final long mFileSize;
private long mReadBytes;
public ProgressiveFileInputStream(File file) throws FileNotFoundException {
super(file);
mFileSize = file.length();
}
@Override
public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
int bytes = super.read(buffer, byteOffset, byteCount);
mReadBytes += bytes;
publishProgress((float) mReadBytes / mFileSize);
return bytes;
}
@Override
public long skip(long byteCount) throws IOException {
long bytes = super.skip(byteCount);
mReadBytes += bytes;
return bytes;
}
@Override
public synchronized void reset() throws IOException {
mReadBytes = 0;
super.reset();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment