Java 通过RESTful Web服务发送文件:Base64编码和GZip压缩
几天以来,我一直在摆弄一个用RESTful Web服务发送/接收文件的Java项目。我使用尽可能少的额外库来实现这一点,因为这将是对现有软件系统的扩展。为了使我的项目在这个软件系统中运行,我需要遵循他们的API。我需要以OSGI包的形式提供我的“扩展” 因为我的项目的结果将需要运行snappy,可能还需要在移动设备上运行,所以我还希望在文件上使用GZip压缩。此外,当我读到关于通过REST发送文件的内容时,似乎最好对文件内容进行Base64编码,并随文件名一起发送 这就引出了下面的客户机代码示例:不是实际的“扩展”Java 通过RESTful Web服务发送文件:Base64编码和GZip压缩,java,rest,base64,gzipinputstream,gzipoutputstream,Java,Rest,Base64,Gzipinputstream,Gzipoutputstream,几天以来,我一直在摆弄一个用RESTful Web服务发送/接收文件的Java项目。我使用尽可能少的额外库来实现这一点,因为这将是对现有软件系统的扩展。为了使我的项目在这个软件系统中运行,我需要遵循他们的API。我需要以OSGI包的形式提供我的“扩展” 因为我的项目的结果将需要运行snappy,可能还需要在移动设备上运行,所以我还希望在文件上使用GZip压缩。此外,当我读到关于通过REST发送文件的内容时,似乎最好对文件内容进行Base64编码,并随文件名一起发送 这就引出了下面的客户机代码示例
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;
}
从日志输出来看,这部分似乎工作正常。前3行
byteArrayAsString: '102' bytes
H4sIAAAAAAAAAAvJyCxWAKJEhZLU4hKFtMycVIW0/CKFINfgkPgUJ1/HxLy81NzUomJeLl1iAS+X
T2ZeqoIhlDaC0sYAwQ1Gr2wA
WorkOrder Service createDocument: success? false, Message: 'CreateDocument: uncompressedByteArray: 'null''
当我尝试在我的服务中读取、解码和解压缩时,问题就出现了。上面日志中最后一行打印的软件系统上的“扩展名”
接收呼叫的代码如下所示:
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();
}
我在网上四处看了看stackoverflow,但似乎没弄错。我从以下帖子中得到了一些想法:
和
没有成功。一定有什么我忽略了
从服务器进行的登录是:
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)
当我对GZip压缩进行注释时,它工作得很好。
任何帮助或提示都将不胜感激
这是从servlet还是REST框架提供的?这两种技术都有成熟的技术,可以根据MIME类型对响应进行压缩,并解决浏览器和服务器之间内容协商的困难部分。从我可以看到的API反编译类来看,这些Web服务是通过org.apache.http类处理的。我找不到任何框架的参考。我不确定我能在软件系统中配置多少,因为这是一个扩展。