Ago*_*noX 8 java upload jersey
我有一个球衣客户端需要上传一个足够大的文件来要求进度条.
问题是,对于需要几分钟的上传,我看到一旦应用程序启动,转移的字节就会变为100%.然后打印"完成"字符串需要几分钟.
就好像字节被发送到一个缓冲区,我正在读取transfert到缓冲区的速度而不是实际的上传速度.这使得进度条无用.
这是非常简单的代码:
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource resource = client.resource("www.myrestserver.com/uploads");
WebResource.Builder builder = resource.type(MediaType.MULTIPART_FORM_DATA_TYPE);
FormDataMultiPart multiPart = new FormDataMultiPart();
FileDataBodyPart fdbp = new FileDataBodyPart("data.zip", new File("data.zip"));
BodyPart bp = multiPart.bodyPart(fdbp);
String response = builder.post(String.class, multiPart);
Run Code Online (Sandbox Code Playgroud)
为了获得进展状态,我在调用builder.post之前添加了一个ContainerListener过滤器.
final ContainerListener containerListener = new ContainerListener() {
@Override
public void onSent(long delta, long bytes) {
System.out.println(delta + " : " + long);
}
@Override
public void onFinish() {
super.onFinish();
System.out.println("on finish");
}
};
OnStartConnectionListener connectionListenerFactory = new OnStartConnectionListener() {
@Override
public ContainerListener onStart(ClientRequest cr) {
return containerListener;
}
};
resource.addFilter(new ConnectionListenerFilter(connectionListenerFactory));
Run Code Online (Sandbox Code Playgroud)
为 java.io.File 提供自己的 MessageBodyWriter 应该足够了,它会在进度更改时触发一些事件或通知一些侦听器
@Provider()
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public class MyFileProvider implements MessageBodyWriter<File> {
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return File.class.isAssignableFrom(type);
}
public void writeTo(File t, Class<?> type, Type genericType, Annotation annotations[], MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
InputStream in = new FileInputStream(t);
try {
int read;
final byte[] data = new byte[ReaderWriter.BUFFER_SIZE];
while ((read = in.read(data)) != -1) {
entityStream.write(data, 0, read);
// fire some event as progress changes
}
} finally {
in.close();
}
}
@Override
public long getSize(File t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return t.length();
}
}
Run Code Online (Sandbox Code Playgroud)
并让您的客户端应用程序简单地使用这个新的提供程序:
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(MyFileProvider.class);
Run Code Online (Sandbox Code Playgroud)
或者
ClientConfig config = new DefaultClientConfig();
MyFileProvider myProvider = new MyFileProvider ();
cc.getSingletons().add(myProvider);
Run Code Online (Sandbox Code Playgroud)
您还必须包含一些算法来识别接收进度事件时传输的文件。
编辑:
我刚刚发现默认情况下 HTTPUrlConnection 使用缓冲。要禁用缓冲,您可以执行以下操作:
所以我建议您问题的最终解决方案使用第一个选项,如下所示:
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(MyFileProvider.class);
URLConnectionClientHandler clientHandler = new URLConnectionClientHandler(new HttpURLConnectionFactory() {
@Override
public HttpURLConnection getHttpURLConnection(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setChunkedStreamingMode(1024);
return connection;
}
});
Client client = new Client(clientHandler, config);
Run Code Online (Sandbox Code Playgroud)