Skip to content

Commit bde61ae

Browse files
committed
Add sync client
1 parent e2824dd commit bde61ae

File tree

3 files changed

+97
-6
lines changed

3 files changed

+97
-6
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.servicestack.client;
2+
3+
public class FileUpload {
4+
private String fieldName;
5+
private String fileName;
6+
private String contentType;
7+
private byte[] fileBytes;
8+
9+
public FileUpload(String fieldName, String fileName, String contentType, byte[] fileBytes) {
10+
this.fieldName = fieldName;
11+
this.fileName = fileName;
12+
this.contentType = contentType != null ? contentType : "application/octet-stream";
13+
this.fileBytes = fileBytes;
14+
}
15+
16+
public String getFieldName() { return fieldName != null ? fieldName : "upload"; }
17+
public String getFileName() { return fileName; }
18+
public String getContentType() { return contentType; }
19+
public byte[] getFileBytes() { return fileBytes; }
20+
}

src/AndroidClient/android/src/main/java/net/servicestack/client/JsonServiceClient.java

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@
88
import com.google.gson.JsonElement;
99
import com.google.gson.JsonObject;
1010

11-
import java.io.BufferedReader;
12-
import java.io.DataOutputStream;
13-
import java.io.IOException;
14-
import java.io.InputStream;
15-
import java.io.InputStreamReader;
16-
import java.io.UnsupportedEncodingException;
11+
import java.io.*;
1712
import java.lang.reflect.Field;
1813
import java.lang.reflect.Type;
1914
import java.net.CookieHandler;
@@ -683,4 +678,75 @@ public void clearCookies() {
683678
CookieManager cookieManager = (CookieManager) CookieHandler.getDefault();
684679
cookieManager.getCookieStore().removeAll();
685680
}
681+
682+
// Add these methods to JsonServiceClient class:
683+
684+
public <TResponse> TResponse postFilesWithRequest(IReturn<TResponse> request, FileUpload[] filesresponseType) {
685+
String requestUrl = this.replyUrl + requestDto.getClass().getSimpleName();
686+
return postFilesWithRequest(requestUrl, request, files, request.getResponseType());
687+
}
688+
689+
public <TResponse> TResponse postFilesWithRequest(Object request, FileUpload[] files, Class<TResponse> responseType) {
690+
String requestUrl = this.replyUrl + requestDto.getClass().getSimpleName();
691+
return postFilesWithRequest(requestUrl, request, files, responseType);
692+
}
693+
694+
private static final String BOUNDARY = "---" + UUID.randomUUID().toString() + "---";
695+
696+
public <TResponse> TResponse postFilesWithRequest(String path, Object request, FileUpload[] files, Class<TResponse> responseType) {
697+
try {
698+
// Prepare multipart data
699+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
700+
DataOutputStream dos = new DataOutputStream(baos);
701+
702+
// Add request DTO fields
703+
for (Field field : Utils.getSerializableFields(request.getClass())) {
704+
Object value = field.get(request);
705+
if (value != null) {
706+
writeMultipartField(dos, field.getName(), Utils.stripQuotes(getGson().toJson(value)));
707+
}
708+
}
709+
710+
// Add files
711+
for (FileUpload file : files) {
712+
writeMultipartFile(dos, file);
713+
}
714+
715+
// End multipart
716+
dos.writeBytes("--" + BOUNDARY + "--\r\n");
717+
dos.flush();
718+
dos.close();
719+
720+
byte[] requestBody = baos.toByteArray();
721+
String contentType = "multipart/form-data; boundary=" + BOUNDARY;
722+
723+
return send(resolveUrl(path), HttpMethods.Post, requestBody, contentType, responseType);
724+
725+
} catch (IOException | IllegalAccessException e) {
726+
throw new RuntimeException(e);
727+
}
728+
}
729+
730+
private void writeMultipartField(DataOutputStream dos, String fieldName, String value) throws IOException {
731+
dos.writeBytes("--" + BOUNDARY + "\r\n");
732+
dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"\r\n");
733+
dos.writeBytes("Content-Type: text/plain; charset=" + UTF8.name() + "\r\n");
734+
dos.writeBytes("\r\n");
735+
dos.writeBytes(value + "\r\n");
736+
}
737+
738+
private void writeMultipartFile(DataOutputStream dos, FileUpload file) throws IOException {
739+
dos.writeBytes("--" + BOUNDARY + "\r\n");
740+
dos.writeBytes("Content-Disposition: form-data; name=\"" + file.getFieldName() +
741+
"\"; filename=\"" + file.getFileName() + "\"\r\n");
742+
dos.writeBytes("Content-Type: " + file.getContentType() + "\r\n");
743+
dos.writeBytes("\r\n");
744+
dos.write(file.getFileBytes());
745+
dos.writeBytes("\r\n");
746+
}
747+
748+
// Convenience method for single file upload
749+
public <TResponse> TResponse postFileWithRequest(String path, Object request, FileUpload file, Class<TResponse> responseType) {
750+
return postFilesWithRequest(path, request, new FileUpload[]{file}, responseType);
751+
}
686752
}

sync-client.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
rm -rf ./src/AndroidClient/android/src/main/java/net/servicestack/func
2+
cp -rf ./src/AndroidClient/client/src/main/java/net/servicestack/func ./src/AndroidClient/android/src/main/java/net/servicestack/
3+
4+
rm -rf ./src/AndroidClient/android/src/main/java/net/servicestack/client
5+
cp -rf ./src/AndroidClient/client/src/main/java/net/servicestack/client ./src/AndroidClient/android/src/main/java/net/servicestack/

0 commit comments

Comments
 (0)