当前位置:首页 » 文件管理 » okhttp图片上传

okhttp图片上传

发布时间: 2022-05-02 14:20:45

1. android 上传图片报此异常java.io.EOFException 求大神指点

这个我在部署到tomcat的时候遇到过这个情况,不知道和你的是否一样,我的处理方法
apache-tomcat-6.0.37\work\Catalina\localhost,把你的项目删除,重新跑一遍,tomcat中的错误是因为有一个文件在启动的时候会短暂的出现,然后被删除,如果没有删除就会报eofe 的异常

2. okhttp3使用详解get怎么传参数

kHttp 可以做很多事,包括上传字符串、上传文件、上传流、上传表格参数、上传多部分的请求、响应 Json、响应缓存等。目前主要流行 Json 数据通信,所以我们就来讲讲基于 Json 通信的 GET 和 POST 请求与响应。
2 下载 OkHttp
介绍了这么多理论知识,接下来就进入实战阶段了,首先下载 OkHttp 的 jar 包,可以去 GitHub 下载最近的包。
这是最新下载地址:https://search.maven.org/remote_content?g=com.squareup.okhttp3&a=okhttp&v=LATEST
当然,你也可以在项目中直接添加编译(用于 Android Studio):compile 'com.squareup.okhttp3:okhttp:3.2.0'
OkHttp 的项目地址:https://github.com/square/okhttp
除此之外,还需要添加一个 OkHttp 的依赖包:okio.jar,下载地址:https://search.maven.org/remote_content?g=com.squareup.okio&a=okio&v=LATEST
项目地址:https://github.com/square/okio
编译地址:compile 'com.squareup.okio:okio:1.6.0'
3 GET 请求
我们从最简单的 Http 请求开始学起,首先需要获取一个 OkHttpClient 对象,方法如下:

[java] view plain print?

3. android:怎样将Uri类型的图片数据转换成流

ContentResolver resolver = getContentResolver();

Cursor cursor = resolver.query(originalUri, proj, null, null, null);
// 按我个人理解 这个是获得用户选择的图片的索引值
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 将光标移至开头 ,这个很重要,不小心很容易引起越界
cursor.moveToFirst();
// 最后根据索引值获取图片路径
String path = cursor.getString(column_index);

这样就获得了图片的路径。

下面说图片上传,现在一般上传都用Okhttp 框架了,直接上传个File类就可以,不需要自己在转成数据流,给你个连接,我写的工具类,你也可以查一下,这个很方便http://blog.csdn.net/xihe9152/article/details/68485040,使用前需要先依赖Okhttp3


4. Android 使用OkhttpUtils上传图片

IMAGE_FILE_NAME这个确定是文件路径么?
那个其他我看不出来,我上传图片用的都是Xutils,你可以搜搜试试。

5. 如何使用OkHttp post传递文字和图片

1、测试App在指定终端是否可正常安装、卸载,定位错误原因 2、无需编写脚本/自动遍历/页面截图/记录操作路径 3、随机性压力测试、测试App运行期的稳定性 4、爱内测平台就是针对app兼容性问题进行测试的

6. android的Okhttp

okhttp,你的封装或者请求方法写的有问题吧,URL不对也不会闪退,有请求失败方法,没进方法说明请求没成功,看看接收解析的地方是否为空或异常没有捕获处理,检查一下。
xUtils,现在更新到xUtils3;okhttp,现在也更新到okhttp3了。下载最新的包吧,注意新版本的差异。

7. 如何高效的使用Okhttp

OkHttp 是一个在开发可汗学院Android APP过程中非常重要的依赖库。它的默认的配置为我们提供了非常重要实用功能,下面一些步骤我们可以让Okhttp提供更多功能使用灵活和内省能力。

1. 启用文件系统上的响应缓存

默认情况下,Okhttp不支持响应缓存,包括HTTP Cache-Control头允许缓存响应。因此,客户端通过一次又一次的请求相同的资源浪费时间和带宽。而不是简单地读取初始响应后缓存的副本。

要在文件系统中启用响应缓存,需要配置com.squareup.okhttp.Cache实例,并把它传递给你的OkHttpClient实例的setCache方法。你必须初始化缓存与存放目录的文件,并以字节为单位的最大值。

响应返回数据可以写入给定目录文件,如果一个响应的缓存超过了给定的大小。我们可以采取 LRU policy 。

我们可以在 stackoverflow 查看 Jesse Wilson 的回复。我们可以通过context.getCacheDir()在子目录中缓存我们的响应:

// Base directory recommended by http://stackoverflow.com/a/32752861/400717.
// Guard against null, which is possible according to
// https://groups.google.com/d/msg/android-developers/-694j87eXVU/YYs4b6kextwJ and
// http://stackoverflow.com/q/4441849/400717.
final @Nullable File baseDir = context.getCacheDir();
if (baseDir != null) {
final File cacheDir = new File(baseDir, "HttpResponseCache");
okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
}

// Base directory recommended by http://stackoverflow.com/a/32752861/400717.
// Guard against null, which is possible according to
// https://groups.google.com/d/msg/android-developers/-694j87eXVU/YYs4b6kextwJ and
// http://stackoverflow.com/q/4441849/400717.
final @NullableFilebaseDir = context.getCacheDir();
if (baseDir != null) {
final FilecacheDir = new File(baseDir, "HttpResponseCache");
okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
}

在可汗学院的程序中我们指定 HTTP_RESPONSE_DISK_CACHE_MAX_SIZE as 10 * 1024 * 1024 , or 10 MB的大小

2. 集成Stetho

Stetho 是Facebook的一个可爱的库,可以使用Chrome浏览器的Chrome开发人员工具功能来检查你的Andr oid应用程序。

Stetho除了允许你检查你的应用程序的SQLite数据库,还可以查看View的层次结构。允许你检查由OkHttp发起的每个请求和响应:

这种自省机制是确保服务器返回允许资源缓存的HTTP头是非常有用的,以及验证没有请求时,保证缓存的资源存在。

要想使用Stetho,只需添加一个StethoInterceptor实例的网络拦截器列表:

okHttpClient.networkInterceptors().add(new StethoInterceptor());

okHttpClient.networkInterceptors().add(new StethoInterceptor());

然后,运行应用程序,打开浏览器后,输入chrome://inspect。然后你就会看到应用程序的设备和标识符的列表。然后鼠标右键选择inspect 打开开发者工具,然后打开新的tab,开始监控OkHttp请求。

3. 使用Picasso 和 Retrofit

你可能使用过 Picasso 来加载网络图片,或者使用 Retrofit 来简化发出请求和解码响应。这些第三方库将隐式地创建自己的OkHttpClient供内部使用,如果你不明确指定一个。

Picasso version 2.5.2的OkHttpDownloader类:

private static OkHttpClient defaultOkHttpClient() {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
return client;
}

private static () {
OkHttpClientclient = new OkHttpClient();
client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
return client;
}

Retrofit也有类似的工厂方法来创建自己的OkHttpClient。

图片一般在应用程序中需要加载的比较大的资源。尽管Picasso自己维护它的LRU机制来缓存图片,在内存中严格执行。如果客户端尝试使用Picasso来加载图片。Picasso会找不到其在内存中缓存图像,然后将委托加载该图片到它的内部OkHttpClient实例。并且默认情况下该实例将始终从服务器加载图片资源。

作为defaultOkHttpClient的方法不能与上面提到的文件系统中的响应缓存配置结合起来。

指定你自己的OkHttpClient实例允许返回数据从文件系统缓存响应,图片不会从服务器加载。这是非常重要的在程序第一次启动以后。这个时候Picasso的内存缓存是冷的。所以它会频繁的委托OkHttpClient实例去加载图片。

这就需要构建配置了您Picasso 的OkHttpClient实例,如果你在你的代码中使用

Picasso.with(context).load(...)

Picasso.with(context).load(...)

加载图片,你是用的是Picasso的单例模式。这是通过with方法懒汉模式地实例化并配置自己的OkHttpClient。因此,我们必须使我们自己的Picasso实例在单例之前通过wiht方法调用。

实现这个,可以简单的将OkHttpClient实例封装在OkHttpDownloader中,然后传递给 Picasso.Builder 实例的downloader方法。

final Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
.build();

// The client should inject this instance whenever it is needed, but replace the singleton
// instance just in case.
Picasso.setSingletonInstance(picasso);

final Picassopicasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
.build();

// The client should inject this instance whenever it is needed, but replace the singleton
// instance just in case.
Picasso.setSingletonInstance(picasso);

在Retrofit中要使用OkHttpClient实例,需要改造1.9.x的一个RestAdapter,需要将OkHttpClient封装OkClient的实例中。然后把它传递给RestAdapter.Builder实例的setClient方法。

restAdapterBuilder.setClient(new OkClient(httpClient));

restAdapterBuilder.setClient(new OkClient(httpClient));

在 Retrofit 2.0中只需要简单的将OkHttpClient传递给Retrofit.Builder实例的client方法。

在可汗学院的APP中我们通过 Dagger 依赖注入来确保我们只有一个OkHttpClient的实例。这种方法同样也适用于Picasso和Retrofit我们提供了一个为OkHttpClient实例提供单例模式的注解示例:

@Provides
@Singleton
public OkHttpClient okHttpClient(final Context context, ...) {
final OkHttpClient okHttpClient = new OkHttpClient();
configureClient(okHttpClient, ...);
return okHttpClient;
}

@Provides
@Singleton
public OkHttpClientokHttpClient(final Contextcontext, ...) {
final OkHttpClientokHttpClient = new OkHttpClient();
configureClient(okHttpClient, ...);
return okHttpClient;
}

OkHttpClient将会通过Dagger的注解创建一个实例提供给我们的Picasso和Retrofit。

4.指定一个用户代理拦截器

日志文件和分析为我们提供了更多有用的信息,当客户在每个请求提供详细的User-Agent
header值的时候。默认情况下,Okhttp包含User-Agent值只有在特定的Okhttp版本中。为了指定我们自己的user
agent。首先创建拦截器的替换值, 我们可以看stackoverflow的建议 。

public final class UserAgentInterceptor implements Interceptor {
private static final String USER_AGENT_HEADER_NAME = "User-Agent";
private final String userAgentHeaderValue;

public UserAgentInterceptor(String userAgentHeaderValue) {
this.userAgentHeaderValue = Preconditions.checkNotNull(userAgentHeaderValue);
}

@Override
public Response intercept(Chain chain) throws IOException {
final Request originalRequest = chain.request();
final Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader(USER_AGENT_HEADER_NAME)
.addHeader(USER_AGENT_HEADER_NAME, userAgentHeaderValue)
.build();
return chain.proceed(requestWithUserAgent);
}
}

public final class UserAgentInterceptor implements Interceptor {
private static final String USER_AGENT_HEADER_NAME = "User-Agent";
private final String userAgentHeaderValue;

public UserAgentInterceptor(String userAgentHeaderValue) {
this.userAgentHeaderValue = Preconditions.checkNotNull(userAgentHeaderValue);
}

@Override
public Responseintercept(Chainchain) throws IOException {
final RequestoriginalRequest = chain.request();
final RequestrequestWithUserAgent = originalRequest.newBuilder()
.removeHeader(USER_AGENT_HEADER_NAME)
.addHeader(USER_AGENT_HEADER_NAME, userAgentHeaderValue)
.build();
return chain.proceed(requestWithUserAgent);
}
}

为了创建User-Agent header值人然后传递给UserAgentInterceptor的构造器,使用你得到的任何信息。

我们可以使用:

android 的系统信息可以清晰的传递出这是一台android 设备
Build.MODEL 或者“制造商提供的用户可见最终可见的名称”
Build.BRAND或者“消费者可见的品牌与产品/硬件相关信息”
Build.VERSION.SDK_INT或者“消费者可见的Android提供的SDK版本号”
BuildConfig.APPLICATION_ID
BuildConfig.VERSION_NAME
BuildConfig.VERSION_CODE

最后三个值由的applicationID,VERSIONCODE和VERSIONNAME的值在我们的Gradle build脚本中

了解更多信息可以查看 versioning your applications 和 configuring your applicationId with Gradle

请注意,如果您的应用程序使用的是WebView,您可以配置使用相同的 User-Agent header值,你可以通过下面方法创建UserAgentInterceptor:

WebSettings settings = webView.getSettings();
settings.setUserAgentString(userAgentHeaderValue);

WebSettingssettings = webView.getSettings();
settings.setUserAgentString(userAgentHeaderValue);

5.指定合理的超时

2.5.0版本之前,OkHttp请求默认为永不超时。2.5.0版本开始如果建立连接请求超时,如果从连接读取下一个字节或写入的下一个字节到连接,花费超过10秒,就终止。这样做需要更新到2.5.0版本我们就不需要在我们的代码中修改bug。原因很简单是我因为我们第一次使用的时候使用了错误的路径。

要覆盖这些默认值,可以分别调用setConnectTimeout,setReadTimeout或setWriteTimeout。

需要注意的是Picasso和Retrofit为OkHttpClient实例指定不同的超时值时,默认情况下,Picasso指定:

连接超过15秒.
读取超过20秒
写入超过20秒

而Retrofit指定:

连接超过15秒.
读取超过20秒
没有写入超时

通过配置Picasso和Retrofit自己的OkHttpClient实例你可以确保所有的请求超时是一致的

8. okhttp最大支持上传多大的文件

/**
* 上传文件
* @param actionUrl 连接地址
* @param paramsMap 参数
* @param callback 回调
* @param <T>
*/
public static <T>void upLoadFile(String actionUrl, HashMap<String, Object> paramsMap, Callback callback) {

// RequestBody requestBody = new MultipartBuilder() //建立请求的内容
// .type(MultipartBuilder.FORM)//表单形式
// .addFormDataPart("token", token)//携带的参数
// .addFormDataPart("file", file.getName(), RequestBody.create(null, file))//第一个参数是服务器接收的名称,第二个是上传文件的名字,第三个是上传的文件
// .build();
// Request request = new Request.Builder()//建立请求
// .url(url)//请求的地址
// .post(requestBody)//请求的内容(上面建立的requestBody)
// .build();

try {
OkHttpClient okHttpClient = new OkHttpClient();
MultipartBuilder builder = new MultipartBuilder();
builder.type(MultipartBuilder.FORM);
//追加参数
for (String key : paramsMap.keySet()) {
Object object = paramsMap.get(key);
if (!(object instanceof File)) {
builder.addFormDataPart(key, object.toString());
} else {
File file = (File) object;
builder.addFormDataPart(key, file.getName(), RequestBody.create(null, file));
}
}
//创建RequestBody
RequestBody body = builder.build();
//创建Request
final Request request = new Request.Builder().url(actionUrl).post(body).build();
HLog.v("upLoadFile","upLoadFile",request.urlString());
Call call=okHttpClient.newCall(request);
call.enqueue(callback);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}

9. 为什么okhttpclient不能builder

一、概述
最近在群里听到各种讨论okhttp的话题,可见okhttp的口碑相当好了。再加上Google貌似在6.0版本里面删除了HttpClient相关API,对于这个行为不做评价。为了更好的在应对网络访问,学习下okhttp还是蛮必要的,本篇博客首先介绍okhttp的简单使用,主要包含:
一般的get请求
一般的post请求
基于Http的文件上传
文件下载
加载图片
支持请求回调,直接返回对象、对象集合
支持session的保持
最后会对上述几个功能进行封装,完整的封装类的地址见:https://github.com/hongyangAndroid/okhttp-utils
使用前,对于Android Studio的用户,可以选择添加:
compile 'com.squareup.okhttp:okhttp:2.4.0'1

或者Eclipse的用户,可以下载最新的jar okhttp he latest JAR ,添加依赖就可以用了。
注意:okhttp内部依赖okio,别忘了同时导入okio:
gradle: compile 'com.squareup.okio:okio:1.5.0'
最新的jar地址:okio the latest JAR
二、使用教程
(一)Http Get
对了网络加载库,那么最常见的肯定就是http get请求了,比如获取一个网页的内容。
//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//请求加入调度
call.enqueue(new Callback()
{
@Override
public void onFailure(Request request, IOException e)
{
}

@Override
public void onResponse(final Response response) throws IOException
{
//String htmlStr = response.body().string();
}
}); 以上就是发送一个get请求的步骤,首先构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:header、method等。
然后通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。
最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。
看到这,你会发现,整体的写法还是比较长的,所以封装肯定是要做的,不然每个请求这么写,得累死。
ok,需要注意几点:
onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()
看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等,例如:
@Override
public void onResponse(final Response response) throws IOException
{
final String res = response.body().string();
runOnUiThread(new Runnable()
{
@Override
public void run()
{
mTv.setText(res);
}

});
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
我们这里是异步的方式去执行,当然也支持阻塞的方式,上面我们也说了Call有一个execute()方法,你也可以直接调用call.execute()通过返回一个Response。
(二) Http Post 携带参数
看来上面的简单的get请求,基本上整个的用法也就掌握了,比如post携带参数,也仅仅是Request的构造的不同。
Request request = buildMultipartFormRequest(
url, new File[]{file}, new String[]{fileKey}, null);
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","张鸿洋");

Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
mOkHttpClient.newCall(request).enqueue(new Callback(){});12345678910

大家都清楚,post的时候,参数是包含在请求体中的;所以我们通过FormEncodingBuilder。添加多个String键值对,然后去构造RequestBody,最后完成我们Request的构造。
后面的就和上面一样了。
(三)基于Http的文件上传
接下来我们在介绍一个可以构造RequestBody的Builder,叫做MultipartBuilder。当我们需要做类似于表单上传的时候,就可以使用它来构造我们的requestBody。
File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");

RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);

RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"username\""),
RequestBody.create(null, "张鸿洋"))
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"mFile\";
filename=\"wjd.mp4\""), fileBody)
.build();

Request request = new Request.Builder()
.url("http://192.168.1.103:8080/okHttpServer/fileUpload")
.post(requestBody)
.build();

Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback()
{
//...
});2526

上述代码向服务器传递了一个键值对username:张鸿洋和一个文件。我们通过MultipartBuilder的addPart方法可以添加键值对或者文件。
其实类似于我们拼接模拟浏览器行为的方式,如果你对这块不了解,可以参考:从原理角度解析Android (Java) http 文件上传
ok,对于我们最开始的目录还剩下图片下载,文件下载;这两个一个是通过回调的Response拿到byte[]然后decode成图片;文件下载,就是拿到inputStream做写文件操作,我们这里就不赘述了。
关于用法,也可以参考泡网OkHttp使用教程
接下来我们主要看如何封装上述的代码。
三、封装
由于按照上述的代码,写多个请求肯定包含大量的重复代码,所以我希望封装后的代码调用是这样的

附上出处链接:http://blog.csdn.net/lmj623565791/article/details/47911083

10. okhttp 上传文件socket关闭怎么解决

使用okhttp上传文件时,每次上传超过5M的文件就会失败, java.net.SocketException: sendto failed: EPIPE (Broken pipe)

原因是okhttp的请求头RequestBody出现了问题

原代码:

RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), RequestBody.create(null, file))
.addFormDataPart("filekey", fileKey)
.addFormDataPart("isSend", "true")
.addPart(Headers.of("Content-Disposition", "form-data; name=\"another\";filename=" + file.getName() + "")

,RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();

改正后的代码,删除了addPart
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), RequestBody.create(null, file))
.addFormDataPart("filekey", fileKey)
.addFormDataPart("isSend", "true")
.build();

热点内容
商道高手安卓哪个服比较好 发布:2024-11-16 17:26:52 浏览:359
访问造句二年级 发布:2024-11-16 17:20:27 浏览:886
阿里云的tcp服务器ip和端口 发布:2024-11-16 17:12:30 浏览:177
php专业培训 发布:2024-11-16 17:10:07 浏览:125
57时间算法 发布:2024-11-16 17:02:42 浏览:510
服务器日志怎么查看是否有爬虫 发布:2024-11-16 16:36:27 浏览:916
医院上传怀孕 发布:2024-11-16 16:30:42 浏览:899
云存储名称 发布:2024-11-16 16:29:10 浏览:590
佛山压缩机厂 发布:2024-11-16 16:29:01 浏览:889
新乡java培训 发布:2024-11-16 16:28:10 浏览:429