泽西客户端上传进度 [英] Jersey client upload progress

查看:139
本文介绍了泽西客户端上传进度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个球衣客户端,需要上传一个足够大的文件才能要求进度条。

问题是,对于需要几分钟的上传,我看到转移的字节数去了应用程序启动后立即100% 。然后打印on finished字符串需要几分钟。
就像字节被发送到缓冲区一样,我正在读取transfert到缓冲区的速度而不是实际的上传速度速度。这使得进度条无用。

I have a jersey client that need to upload a file big enough to require a progress bar.
The problem is that, for an upload that requires some minutes, i see the bytes transfered to go to 100% as soon as the application has started. Then it takes some minutes to print the "on finished" string.
It is as if the bytes were sent to a buffer, and i was reading the transfert-to-the buffer speed instead of the actual upload speed. This makes the progress bar useless.

这是非常简单的代码:

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);

为了获得进展状态,我在调用builder.post:

To get progress state i've added a ContainerListener filter, obviouslt before calling builder.post:

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));


推荐答案

它应该足以为java提供自己的MessageBodyWriter .io.File会触发某些事件或通知某些听众进度变化

it should be enough to provide you own MessageBodyWriter for java.io.File which fires some events or notifies some listeners as progress changes

@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();
    }
}

并让您的客户端应用程序简单地使用这个新的提供者:

and to make your client application uses this new provider simply:

ClientConfig config = new DefaultClientConfig();
config.getClasses().add(MyFileProvider.class);

ClientConfig config = new DefaultClientConfig();
MyFileProvider myProvider = new MyFileProvider ();
cc.getSingletons().add(myProvider);

您还必须包含一些算法来识别接收进度事件时传输的文件。

You would have to also include some algorithm to recognize which file is transfered when receiving progress events.

编辑:

我发现默认情况下HTTPUrlConnection使用缓冲。要禁用缓冲,你可以做几件事:

I just found that by default HTTPUrlConnection uses buffering. And to disable buffering you could do couple of things:


  1. httpUrlConnection.setChunkedStreamingMode(chunklength) - 禁用缓冲并使用分块传输编码发送请求

  2. httpUrlConnection.setFixedLengthStreamingMode(contentLength) - 禁用缓冲,但会对流式传输一些约束:必须发送确切的字节数

所以我建议你的问题的最终解决方案使用第一个选项,看起来像这样:

So I suggest the final solution to your problem uses 1st option and would look like this:

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);

这篇关于泽西客户端上传进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆