Since a few days I am fiddling with Java a project to send/receive files with a RESTful webservice. I do this with as little extra libraries as possible because this will be an extension to an existing software system. To make my project run within this software system I need to follow their API. And I need to provide my 'extension' as an OSGI bundle.
Because the result of my project will need to run snappy and possibly on mobile devices also I would also like to use GZip compression on the file. Further more when I read about sending files via REST it seems best to Base64 encode the contents of the file and send the filename with it.
This brings me to the following client code sample: (not the actual 'extension')
IWorkOrderService workOrderService = connection.getImplementation(IWorkOrderService.class);
File file = Paths.get("C:/Temp/", "filename.txt").toFile();
PlnJsonResponse response = workOrderService.createDocument("pln", "dBM", file.getName(), base64EncodeAndGZipFile(file));
System.out.println("WorkOrder Service createDocument: success? " + response.isSuccess() + ", Message: '" + response.getMessage() + "'");
private static String base64EncodeAndGZipFile(File file) {
try (FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Base64OutputStream base64OutputStream = new Base64OutputStream(byteArrayOutputStream);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(base64OutputStream)) {
int len;
byte[] buffer = new byte[1024];
while((len=fis.read(buffer)) != -1){
gzipOutputStream.write(buffer, 0, len);
}
gzipOutputStream.finish();
String byteArrayAsString = byteArrayOutputStream.toString("UTF-8");
System.out.println("byteArrayAsString: '" + byteArrayAsString.length() + "' bytes");
System.out.println(byteArrayAsString);
return byteArrayAsString;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
From the log output this part seems to work fine. (First 3 lines)
byteArrayAsString: '102' bytes
H4sIAAAAAAAAAAvJyCxWAKJEhZLU4hKFtMycVIW0/CKFINfgkPgUJ1/HxLy81NzUomJeLl1iAS+X
T2ZeqoIhlDaC0sYAwQ1Gr2wA
WorkOrder Service createDocument: success? false, Message: 'CreateDocument: uncompressedByteArray: 'null''
The problem appears when I try to read, decode, decompress this in my service. (The 'extension' on the software system) As printed on the last line in the log above.
The code to receive the call is like this:
private static final byte NEWLINE = (byte) '\n';
private static final byte CARRIAGE_RETURN = (byte) '\r';
private static final byte[] LINE_SEPARATORS = new byte[] {CARRIAGE_RETURN, NEWLINE};
public PlnJsonResponse createDocument(String plnOrderNumber, String dBMOrderNumber, String fileName, String byteArrayAsString) {
System.out.println(">> createDocument <<");
System.out.println(">> byteArrayAsString: '" + byteArrayAsString.length() + "' bytes");
System.out.println(byteArrayAsString);
System.out.println("<< isBase64? " + Base64.isBase64(byteArrayAsString));
final byte[] compressedByteArray = byteArrayAsString.getBytes(Charset.forName("UTF-8"));
byte[] uncompressedByteArray = null;
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(compressedByteArray);
Base64InputStream base64InputStream = new Base64InputStream(byteArrayInputStream, false, 76, LINE_SEPARATORS);
GZIPInputStream gzipInputStream = new GZIPInputStream(base64InputStream, 1024);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len;
while((len = gzipInputStream.read(buffer, 0, buffer.length)) != -1){
byteArrayOutputStream.write(buffer, 0, len);
}
uncompressedByteArray = byteArrayOutputStream.toByteArray();
String uncompressedByteArrayAsString = byteArrayOutputStream.toString("UTF-8");
System.out.println(">> uncompressedByteArrayAsString: '" + uncompressedByteArrayAsString.length() + "'");
System.out.println(uncompressedByteArrayAsString);
System.out.println("<<");
} catch (IOException e) {
e.printStackTrace();
}
return new PlnJsonResponse.Builder().withMessage("CreateDocument: uncompressedByteArray: '" + uncompressedByteArray + "'").build();
}
I looked around on the web and stackoverflow but kind seem to get it right. I got some idea's from posts like: How to convert Java String into byte[]? and Stream decoding of Base64 data with out success. There must be something I overlooked.
The loging from the server is:
INFO | jvm 1 | 2015/05/04 20:35:11 | >> createDocument <<
INFO | jvm 1 | 2015/05/04 20:35:11 | << isBase64? true
INFO | jvm 1 | 2015/05/04 20:35:11 | java.io.EOFException
INFO | jvm 1 | 2015/05/04 20:35:11 | at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:264)
INFO | jvm 1 | 2015/05/04 20:35:11 | at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:254)
INFO | jvm 1 | 2015/05/04 20:35:11 | at java.util.zip.GZIPInputStream.readUInt(GZIPInputStream.java:247)
INFO | jvm 1 | 2015/05/04 20:35:11 | at java.util.zip.GZIPInputStream.readTrailer(GZIPInputStream.java:218)
INFO | jvm 1 | 2015/05/04 20:35:11 | at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:118)
INFO | jvm 1 | 2015/05/04 20:35:11 | at ***.impl.WorkOrderService.createDocument(WorkOrderService.java:61)
INFO | jvm 1 | 2015/05/04 20:35:11 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
When I comment out the GZip compressing this works just fine. Any help or tip would be greatly appreciated.
Kind regards