精华内容
下载资源
问答
  • 在上一讲中 OkHttp下载文件并带进度条 中,我们知道怎样去下载文件了。那上传文件呢 一、编写服务器端 在上一讲服务器下新建UploadFileServlet,代码如下:然后重启服务器! @WebServlet(/UploadFileServlet) @...
  • 在开发android手机客户端,常常会需要上传文件到服务器,使用okhttp会是一个很好的选择,它使用很简单,而且运行效率也很高,下面小编给大家带来了android 开发中使用okhttp上传文件到服务器功能,一起看看吧
  • okhttp上传文件,包含Android客户端代码和Java Servlet服务端代码,本地测试通过。
  • android OkHttp上传文件并带进度条
  • okhttp 上传文件

    2021-08-11 06:26:38
    compile 'com.squareup.okhttp3:okhttp:3.2.0'import okhttp3.*/****/class ClientUploadUtils {static ResponseBody upload(String url, String filePath, String fileName) throws Exception {OkHttpClient client...

    compile 'com.squareup.okhttp3:okhttp:3.2.0'

    import okhttp3.*

    /**

    *

    */

    class ClientUploadUtils {

    static ResponseBody upload(String url, String filePath, String fileName) throws Exception {

    OkHttpClient client = new OkHttpClient()

    RequestBody requestBody = new MultipartBody.Builder()

    .setType(MultipartBody.FORM)

    .addFormDataPart("file", fileName,

    RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath)))

    .build()

    Request request = new Request.Builder()

    .header("Authorization", "Client-ID " + UUID.randomUUID())

    .url(url)

    .post(requestBody)

    .build()

    Response response = client.newCall(request).execute();

    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response)

    return response.body()

    }

    static void main(String[] args) throws IOException {

    try {

    String fileName = "com.jdsoft.biz.test.zip"

    String filePath = "D:\\ExtJsTools\\Sencha\\Cmd\\repo\\pkgs\\test.zip"

    String url = "http://localhost:9990/upload_app_package"

    System.out.println(upload(url, filePath, fileName).string())

    } catch (Exception e) {

    e.printStackTrace()

    }

    }

    }

    展开全文
  • Android OkHttp Post上传文件并且携带参数 这里整理一下 OkHttp 的 post 在上传文件的同时,也要携带请求参数的方法。 使用 OkHttp 版本如下: compile 'com.squareup.okhttp3:okhttp:3.4.1' 代码如下: protected...
  • Android OKhttp上传图片并且携带参数,亲测好用,可下载使用
  • okhttp上传文件

    千次阅读 2016-08-25 20:05:28
    1.先做好准备工作,在网上下载okhttp的...2.对于android端开发的人员来说,只需完成client端的代码,然后调用服务器端的接口拼接到url后面,即可以完成文件上传工作。这里先给出client端的代码: package cn.edu.q

    1.先做好准备工作,在网上下载okhttp的jar包,放到工程的libs目录下:

    下载地址:http://download.csdn.net/detail/ljw124213/9613065

    2.对于android端开发的人员来说,只需完成client端的代码,然后调用服务器端的接口拼接到url后面,即可以完成文件的上传工作。这里先给出client端的代码:

    package cn.edu.qianfeng;
    
    
    import java.io.IOException;
    import com.squareup.okhttp.Callback;
    import com.squareup.okhttp.MultipartBuilder;
    import com.squareup.okhttp.OkHttpClient;
    import com.squareup.okhttp.Request;
    import com.squareup.okhttp.RequestBody;
    import com.squareup.okhttp.Response;
    
    
    public class TestFileUpload {
    	public static void main(String[] args) {
    		//创建OkHttpClient对象(前提是导入了okhttp.jar和okio.jar)
    		OkHttpClient client = new OkHttpClient();
    		//封装请求数据
    		RequestBody body = new MultipartBuilder().addFormDataPart("user", "lu")  //提交普通表单数据
    							 .addFormDataPart("file1", "1.txt", RequestBody.create(null, "D:\1.txt"))
    							 .build();
    		//封装request,使用okhttp框架上传数据只能使用post提交方式
    		Request request = new Request.Builder().url("http://localhost:8080/uploadserver/FileUploadServlet")
    				                       .post(body)
    				                       .build();
    		//执行请求    enqueue:异步执行
    		client.newCall(request).enqueue(new Callback() {
    			//请求成功会执行此方法
    			@Override
    			public void onResponse(Response response) throws IOException {
    				if (response.isSuccessful()) {
    					//服务器端把返回的结果封装在了body()中
    					byte[] result = response.body().bytes();
    					System.out.println(new String(result));
    				}
    			}
    			//请求失败会执行此方法
    			@Override
    			public void onFailure(Request request, IOException e) {
    				e.printStackTrace();
    			}
    		});
    	}
    }


    3.下面是服务器端的servlet代码,可以用来测试上面的代码,需要下载两个上传文件的jar包:

    下载地址:http://download.csdn.net/detail/ljw124213/9613084

    package cn.edu.lu;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileItemFactory;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    @WebServlet("/FileUploadServlet")
    public class FileUploadServlet extends HttpServlet {
    
    	@Override
    	protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
    
    		request.setCharacterEncoding("utf-8");
    		String uploadFileName = ""; // 上传的文件名
    		String fieldName = ""; // 表单字段元素的name属性值
    		// 请求信息中的内容是否是multipart类型
    		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    		// 上传文件的存储路径(服务器文件系统上的绝对文件路径)
    		// String uploadFilePath =
    		// request.getSession().getServletContext().getRealPath("\\test" );
    		if (isMultipart) {
    			FileItemFactory factory = new DiskFileItemFactory();
    			ServletFileUpload upload = new ServletFileUpload(factory);
    			try {
    				// 解析form表单中所有文件
    				List<FileItem> items = upload.parseRequest(request);
    				Iterator<FileItem> iter = items.iterator();
    				while (iter.hasNext()) { // 依次处理每个文件
    					FileItem item = (FileItem) iter.next();
    					if (item.isFormField()) { // 普通表单字段
    						fieldName = item.getFieldName(); // 表单字段的name属性值
    						if (fieldName.equals("user")) {
    							// 输出表单字段的值
    							System.out.print(item.getString("UTF-8") + "上传了文件.");
    						}
    					} else { // 文件表单字段
    						String fileName = item.getName();
    						if (fileName != null && !fileName.equals("")) {
    							File fullFile = new File(item.getName());
    							File saveFile = new File("D:\\test", fullFile.getName());
    							item.write(saveFile);
    							uploadFileName = fullFile.getName();
    							System.out.println("上传的文件名是:" + uploadFileName);
    						}
    					}
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }

    4.上传文件的html代码:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<div style="text-align: center;">	
    		<form action="FileUploadServlet" method="post" enctype="multipart/form-data">
    			<p>用户名:<input type="text" name="user"></p>
    			<p>密码<input type="file" name="file1"></p>
    			<p><input type="submit" value="上传"></p>
    		</form>
    	</div>
    </body>
    </html>

    展开全文
  • okhttp上传、下载文件设置进度监听

    从okhttp用法入手

    OkHttpClient client = new OkHttpClient();
    RequestBody requestBody = new RequestBody.Builder().build();
    Request request = new Request.Builder().post(requestBody).build();
    client.newCall(request).enqueue(callback);
    

    使用步骤很简单

    1. 新建request
    2. 扔到client中执行

    其中request就是http请求对象,包含了完整的http请求报文的内容,header和body。
    client把扔进来的request对象进行处理,建立http连接,然后把处理的报文传出去。

    http的multipart方式传输文件其实是将文件的二进制流写入报文的body中进行传输。
    我们看看okhttp提供的MultipartBody 源码

    public final class MultipartBody extends RequestBody {
        一堆请求体包含的内容
    
    	@Override 
    	public void writeTo(BufferedSink sink) throws IOException {
        	writeOrCountBytes(sink, false);
      	}
    
      	private long writeOrCountBytes(BufferedSink sink, boolean countBytes) throws IOException {
        	...
        	sink.write(一堆请求体包含的内容);
        	...
      }
    }
    

    okhttp就是通过writeTo方法将请求体内容组织以okio流的方式写入socket连接流中传输到服务器上的。我们可以从writeTo方法里入手,监听writeTo写多少字节的数据。以此来看文件传输(其实是报文发送)进度。

    监听数据写入量,代理的编程思想

    首先要去了解一下okio是个神马…

    okhttp是用okio来进行流处理的。okio这玩意有个ForwardingSink,这个东西真的奇妙。

    public abstract class ForwardingSink implements Sink {
      private final Sink delegate;
    
      public ForwardingSink(Sink delegate) {
        if (delegate == null) throw new IllegalArgumentException("delegate == null");
        this.delegate = delegate;
      }
    
      public final Sink delegate() {
        return delegate;
      }
      @Override public void write(Buffer source, long byteCount) throws IOException {
        delegate.write(source, byteCount);
      }
      @Override public void flush() throws IOException {
        delegate.flush();
      }
      @Override public Timeout timeout() {
        return delegate.timeout();
      }
      @Override public void close() throws IOException {
        delegate.close();
      }
      @Override public String toString() {
        return getClass().getSimpleName() + "(" + delegate.toString() + ")";
      }
    }
    

    这个是ForwardingSink 完整的代码,他什么也没做,里面有个Sink类型的delegate对象。ForwardingSink的方法都原封不动的调用了一遍delegate对象的方法。我第一次看完全没搞懂这么做有什么用,就像一个奸商一样,把拦下来的活全交给另一个人干。看了半天我才明白这样写真是精妙。

    我们看到MultipartBody中的writeTo方法传入了一个参数BufferedSink sink,okio就是通过sink的write方法写入socket的流,sink对象是个传过来参数,而我们想要监听sink写了多少数据就要重写write方法。

    怎么办,我封装一个自定义的sink,继承自这个代理sink类,我们就可以重写write方法了。

    class ProgressBufferSink extends ForwardingSink {
    
            ProgressBufferSink(Sink delegate) {
                super(delegate);
            }
            
            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                bytesWritten += byteCount;
                progressListener.onProgress(bytesWritten, contentLength);
            }
    }
    

    这样写ProgressBufferSink 还是一个sink,重写自己的write方法做一些其它的事,可以给writeOrCountBytes方法执行,虽然调用的是ProgressBufferSink 的write方法,但最终还是调用的delegate的write方法。

    我们也模仿着写一个代理的类 ProgressMultipartRequestBody ,把实际的工作交给MultipartBody来做

    public class ProgressMultipartRequestBody extends RequestBody {
     	private final MultipartBody requestBody;
    
    	 @Override
       	 public MediaType contentType() {
          	  return requestBody.contentType();
       	 }
    	
    	@Override
       	 public void writeTo(BufferedSink sink) throws IOException {
       	 	  ...
    		  requestBody.writeTo(bufferedSink);
    		  ...
       	 }
    ...
    }
    

    现在就差一步,怎么把ProgressBufferSink当成BufferedSink 传给requestBody.writeTo方法。okio提供了一个静态方法,可以把sink转成bufferSink。

    public static BufferedSink buffer(Sink sink) 
    
     	@Override
        public void writeTo(BufferedSink sink) throws IOException {
            requestBody.writeTo(Okio.buffer(new ProgressBufferSink(sink)));
        }
    

    优化使用

    此时使用ProgressMultipartRequestBody 比较麻烦,要新建一个MultipartBody,再封装到ProgressMultipartRequestBody ,再给client去执行。

    RequestBody requestBody = new MultipartBody.Builder().build();
    ProgressMultipartRequestBody multiRequestBody = new ProgressMultipartRequestBody(requestBody );
    Request request = new Request.Builder().post(multiRequestBody )build();
    client.newCall(request);
    

    我们可以按照MultipartBody的生产者模式封装一层ProgressMultipartRequestBody生产者模式

     public static final class Builder {
            private MediaType type = MIXED;
            private final List<MultipartBody.Part> parts = new ArrayList<>();
            private ProgressListener progressListener;
    
            public Builder() {
            }
    
            public Builder setType(MediaType type) {
                if (type == null) {
                    throw new NullPointerException("type == null");
                }
                if (!type.type().equals("multipart")) {
                    throw new IllegalArgumentException("multipart != " + type);
                }
                this.type = type;
                return this;
            }
    
            public Builder addPart(RequestBody body) {
                return addPart(MultipartBody.Part.create(body));
            }
    
            public Builder addPart(Headers headers, RequestBody body) {
                return addPart(MultipartBody.Part.create(headers, body));
            }
    
            public Builder addFormDataPart(String name, String value) {
                return addPart(MultipartBody.Part.createFormData(name, value));
            }
    
            public Builder addFormDataPart(String name, String filename, RequestBody body) {
                return addPart(MultipartBody.Part.createFormData(name, filename, body));
            }
    
            public Builder addPart(MultipartBody.Part part) {
                if (part == null) throw new NullPointerException("part == null");
                parts.add(part);
                return this;
            }
    
            public Builder addProgressListener(ProgressListener progressListener) {
                this.progressListener = progressListener;
                return this;
            }
    
            public ProgressMultipartRequestBody build() throws IOException, IllegalStateException {
                if (parts.isEmpty()) {
                    throw new IllegalStateException("Multipart body must have at least one part.");
                }
                if (progressListener == null) {
                    throw new IllegalStateException("progress listener is null");
                }
                MultipartBody.Builder builder = new MultipartBody.Builder().setType(type);
                for (MultipartBody.Part part : parts) {
                    builder.addPart(part);
                }
                return new ProgressMultipartRequestBody(builder.build(), progressListener);
            }
        }
    

    这样使用上就变成了,在原MultipartBody使用上,将MultipartBody改为ProgressMultipartRequestBody就可以了。

    RequestBody requestBody = new ProgressMultipartRequestBody.Builder().build();
    Request request = new Request.Builder().post(requestBody).build();
    client.newCall(request);
    

    完整代码

    代码下载

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import okhttp3.Headers;
    import okhttp3.MediaType;
    import okhttp3.MultipartBody;
    import okhttp3.RequestBody;
    import okio.Buffer;
    import okio.BufferedSink;
    import okio.ForwardingSink;
    import okio.Okio;
    import okio.Sink;
    
    import static okhttp3.MultipartBody.MIXED;
    
    public class ProgressMultipartRequestBody extends RequestBody {
        private final MultipartBody requestBody;
        private final ProgressListener progressListener;
        private BufferedSink bufferedSink;
    
        private long bytesWritten = 0L;
        private long contentLength;
    
        private ProgressMultipartRequestBody(MultipartBody requestBody, ProgressListener progressListener) throws IOException {
            this.requestBody = requestBody;
            this.progressListener = progressListener;
            contentLength = requestBody.contentLength();
        }
    
        @Override
        public MediaType contentType() {
            return requestBody.contentType();
        }
    
        @Override
        public long contentLength() {
            return contentLength;
        }
    
        @Override
        public void writeTo(BufferedSink sink) throws IOException {
            if (bufferedSink == null) {
                bufferedSink = Okio.buffer(new ProgressBufferSink(sink));
            }
            requestBody.writeTo(bufferedSink);
            bufferedSink.flush();
        }
    
        class ProgressBufferSink extends ForwardingSink {
    
            ProgressBufferSink(Sink delegate) {
                super(delegate);
            }
    
            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                bytesWritten += byteCount;
                progressListener.onProgress(bytesWritten, contentLength);
            }
    
        }
    
        public interface ProgressListener {
            void onProgress(long currentBytes, long contentLength);
        }
    
        public static final class Builder {
            private MediaType type = MIXED;
            private final List<MultipartBody.Part> parts = new ArrayList<>();
            private ProgressListener progressListener;
    
            public Builder() {
            }
    
            public Builder setType(MediaType type) {
                if (type == null) {
                    throw new NullPointerException("type == null");
                }
                if (!type.type().equals("multipart")) {
                    throw new IllegalArgumentException("multipart != " + type);
                }
                this.type = type;
                return this;
            }
    
            public Builder addPart(RequestBody body) {
                return addPart(MultipartBody.Part.create(body));
            }
    
            public Builder addPart(Headers headers, RequestBody body) {
                return addPart(MultipartBody.Part.create(headers, body));
            }
    
            public Builder addFormDataPart(String name, String value) {
                return addPart(MultipartBody.Part.createFormData(name, value));
            }
    
            public Builder addFormDataPart(String name, String filename, RequestBody body) {
                return addPart(MultipartBody.Part.createFormData(name, filename, body));
            }
    
            public Builder addPart(MultipartBody.Part part) {
                if (part == null) throw new NullPointerException("part == null");
                parts.add(part);
                return this;
            }
    
            public Builder addProgressListener(ProgressListener progressListener) {
                this.progressListener = progressListener;
                return this;
            }
    
            public ProgressMultipartRequestBody build() throws IOException, IllegalStateException {
                if (parts.isEmpty()) {
                    throw new IllegalStateException("Multipart body must have at least one part.");
                }
                if (progressListener == null) {
                    throw new IllegalStateException("progress listener ");
                }
                MultipartBody.Builder builder = new MultipartBody.Builder().setType(type);
                for (MultipartBody.Part part : parts) {
                    builder.addPart(part);
                }
                return new ProgressMultipartRequestBody(builder.build(), progressListener);
            }
        }
    }
    
    
    展开全文
  • okhttp文件上传

    2017-04-21 08:47:41
    使用okhttp进行多文件上传,包含服务器端代码
  • 关于okhttp上传文件

    2021-08-09 01:59:10
    老师讲的类已经被不用了,对于新的okhttp3.5.0,上传表单带图片怎么图片一直传布上去,也看了okhttp3.x的demopublicvoiddoUpload(Viewview){Filefile=newFile(Environment.getExternalStorageDirectory(),"2.jpg");...

    老师讲的类已经被不用了,对于新的okhttp3.5.0,上传表单带图片怎么图片一直传布上去,也看了okhttp3.x的demopublic void doUpload(View view) {

    File file = new File(Environment.getExternalStorageDirectory(), "2.jpg");

    if (!file.exists()) {

    L.e(file.getAbsolutePath() + "not exist!");

    }

    RequestBody requestBody = new MultipartBody.Builder()

    .setType(MultipartBody.FORM)

    .addFormDataPart("username", "xiaoqiang")

    .addFormDataPart("password", "123")

    .addFormDataPart("mPhoto", "2.jpg", RequestBody.create(MediaType.parse("image/jpeg"), file))

    .build();

    Request request = new Request.Builder()

    .url(BaseUrl + "uploadInfo")

    .post(requestBody)

    .build();

    executeRequest(request);

    }

    这个是我写的,可是一直报错,在服务端图片接收不到,图片是按老师写的

    展开全文
  • 本篇文章主要介绍了RxJava+Retrofit+OkHttp实现文件上传,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • OkHttp 上传文件, 支持单个, 多个文件上传 /** * 上传文件 */ public void upLoadingFile(String userId, String businessId, String type, ...
  • OkHttp上传文件和图片操作

    千次阅读 2020-05-31 16:43:00
    1:首先你得找到文件上传的路径;需要提前将文件准备好 2:添加读写权限 3:导入依赖 4:如下:如果文件不存在则提示文件不从在 5:如下:首先是文件的类型,和将文件放入requestbody中再将其放入muitipartbody中...
  • 记录OkHttp上传文件

    千次阅读 2018-06-12 15:33:05
    理解文件上传我觉得还是需要一些JavaWeb方面的知识,比如什么是表单了,等等 博主先用现学了下,理解也不咋透彻,所以先记录下,有不对的欢迎指正。 先上一下文件上传的代码,代码参考地址 客户端Android代码: ...
  • okhttp上传文件出现OOM

    千次阅读 2019-09-18 23:31:17
    okhttp是一个比较优秀的库,使用非常广泛,相信大家都比较熟悉。在最近的使用中却发现了一个OOM的情况,在上传比较大的图片或视频时会发生,日志如下 Caused by: java.lang.OutOfMemoryerror: Failed to alocate a...
  • (android开发)使用okhttp上传文件

    千次阅读 2019-05-30 11:29:59
    开发android手机客户端,常常会需要上传文件到服务器,比如:你手机里的照片。 使用okhttp会是一个很好的选择。它使用很简单,而且运行效率也很高。 首先,在 app/build.gradle 的 dependencies 增加 implementation...
  • OkHttp上传文件,监听上传进度

    千次阅读 2019-03-05 22:04:49
    过去开发使用HttpClient上传文件可以使用CountingHttpEntity...由于现在开发使用okhttp,但是貌似okhttp没有提供监听上传文件进度的方法。 使用HttpClient时,监听上传进度可以使用下面的方法 HttpPosthttpp...
  • 使用okhttp上传文件---单文件或多文件
  • public class UploadImgUtils {public static final StringMULTIPART_FORM_DATA ="Multipart/form... // 指明要上传文件格式public static void okHttpUpload(String url,List keyList,List valueList,String file...
  • OkHttp上传文件到服务器并带进度

    千次阅读 2017-07-02 22:11:08
    在上一讲中 OkHttp下载文件并带进度条 中,我们知道怎样去下载文件了。那上传文件呢一、编写服务器端在上一讲服务器下新建UploadFileServlet,代码如下:然后重启服务器!@WebServlet("/UploadFileServlet") @...
  • 本篇文章主要介绍了android中实现OkHttp下载文件并带进度条,OkHttp是比较火的网络框架,它支持同步与异步请求,支持缓存,可以拦截,更方便下载大文件上传文件的操作,有兴趣的可以了解一下
  • Okhttp文件上传

    2017-12-26 17:11:56
    Okhttp文件上传上传文件代码示例及demo,附带一些优秀博主的几篇博客,请参考。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,861
精华内容 4,344
关键字:

okhttp上传文件