OkHttp 设置 User-Agent 教程
我们知道OkHttp走的并不是原生的http请求,因此在header里面并没有真正的User-Agent,而是“okhttp/版本号”这样的字符串,因为后台需要统计信息,要求传入正确的User-Agent,那么我们如何获取User-Agent并设置给Okhttp呢?
一、获取User-Agent
private static String getUserAgent() {
String userAgent = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
try {
userAgent = WebSettings.getDefaultUserAgent(context);
} catch (Exception e) {
userAgent = System.getProperty("http.agent");
}
} else {
userAgent = System.getProperty("http.agent");
}
StringBuffer sb = new StringBuffer();
for (int i = 0, length = userAgent.length(); i < length; i++) {
char c = userAgent.charAt(i);
if (c <= '\u001f' || c >= '\u007f') {
sb.append(String.format("\\u%04x", (int) c));
} else {
sb.append(c);
}
}
return sb.toString();
}
代码说明:
1. 在Android 17之后可以通过WebSettings.getDefaultUserAgent(context)获取,但是经过测试极个别手机会出现找不到类的情况,因此try-catch一下,那么第二种方式是System.getProperty("http.agent"),这两种方式有什么不同呢?从结果上来看是第一种得到的信息更全一点;
第一种:
Mozilla/5.0 (Linux; Android 6.0.1; MI 4LTE Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko)
Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36
第二种:
Dalvik/2.1.0 (Linux; U; Android 6.0.1; MI 4LTE MIUI/6.10.13)
2、在一些国产手机上面这个User-Agent里面会包含中文,就会报错
java.lang.IllegalArgumentException: Unexpected char 0x7231 at 33 in User-Agent value: Mozilla/5.0 (Linux; Android 5.1; 爱国者-X86 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2367)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2419)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5323)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Unexpected char 0x7231 at 33 in User-Agent value: Mozilla/5.0
(Linux; Android 5.1; 爱国者-X86 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36
at okhttp3.Headers$Builder.checkNameAndValue(Headers.java:320)
at okhttp3.Headers$Builder.add(Headers.java:270)
at okhttp3.Request$Builder.addHeader(Request.java:175)
什么原因引起的呢?okhttp3.Headers$Builder.checkNameAndValue进到这个方法里面可以看到okhttp对中文进行了过滤,如果不符合条件就抛出异常IllegalArgumentException
private void checkNameAndValue(String name, String value) {
if (name == null) throw new NullPointerException("name == null");
if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
for (int i = 0, length = name.length(); i < length; i++) {
char c = name.charAt(i);
if (c <= '\u001f' || c >= '\u007f') {
throw new IllegalArgumentException(Util.format(
"Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
}
}
if (value == null) throw new NullPointerException("value == null");
for (int i = 0, length = value.length(); i < length; i++) {
char c = value.charAt(i);
if (c <= '\u001f' || c >= '\u007f') {
throw new IllegalArgumentException(Util.format(
"Unexpected char %#04x at %d in %s value: %s", (int) c, i, name, value));
}
}
}
因此上段代码才会对返回结果进行过滤,如果不符合条件,会进行转码。
二、给Okhttp设置User-Agent
Request request = new Request.Builder().url(url).removeHeader("User-Agent").addHeader("User-Agent",
getUserAgent()).build();
httpClient.newCall(request).enqueue(handler);
OkHttp 设置 User-Agent 教程的更多相关文章
- CentOS 6.5、6.7 设置静态 ip 教程
CentOS 6.5.6.7 设置静态 ip 教程,可以ping通外网:www.baidu.com ①. 网络适配器(VMware Network Adapter) 选择NAT模式 ②. 设置静态 i ...
- 联想e431笔记本更改硬盘模式bios设置的详细教程
用硬盘安装系统,就要进入bios,将硬盘改为第一启动项即可重装系统.不同品牌的电脑,它的bios设置方法也就不同.那么,联想e431笔记本要如何更改硬盘模式呢?今天U大侠小编就和大家分享联想e431笔 ...
- 使用apache和htaccess对目录访问设置密码保护配置教程
对目录设置密码保护配置说明我们有时候访问某些网站的时候,要求输入用户名和密码才能访问.这是为了保护隐私,只让经过许可的人访问.在本教程中主要介绍两种方法,一种是通过apache httpd.conf配 ...
- Retrofit2.0+OkHttp设置统一的请求头(request headers)
有时候要求Retrofit2的接口中每个都要增加上headers,又不想做重复的事情,可以使用这种方法来为每个request请求都设置上相同的请求头header. 修改请求头request heade ...
- Python中为feedparser设置超时时间教程
python有一个用于解析feed的模块:feedparser,feedparser解析各种feed是非常方便的,唯一比较恼火的是遇到一些badurl,经常会导致堵塞,因此需要为feedparser设 ...
- CentOS 6.5设置静态IP教程 并且可以ping通
CentOS6.5掉电或重启,它的IP会被DHCP重新分配,如果要远程控制这台电脑,不得不去打开显示器去查看它的新IP,这样太麻烦了.于是需要将这台电脑的IP设置成静态的. 网上常规的设置静态ip的方 ...
- 设置Sql Agent运行Job时的执行账户
相信使用过Sql Server的人都应该知道,使用Sql Agent可以建立一些自动化Job来帮我们周期性地执行一些任务,其中执行SSIS包就是其中一个任务.而在SSIS包中有时候会去做读取文件等一些 ...
- Okhttp设置http缓存,在没有网络的情况下加载http缓存里面的内容
HTTP_CACHE_FILENAME为缓存地址根路径: private final String HTTP_CACHE_FILENAME = "HttpCache"; priva ...
- 设置User Agent
公司的前端要给项目的webview加一个区分,用来区别是iOS端访问.android访问还是在浏览器访问的,说是要加一个User Agent ,前端根据不同信息做适配,和我说来一头雾水,后来经过开发同 ...
随机推荐
- pg_dump 数据处理
从数据库导出数据 -U 用户 -p 端口 -h 主机地址 -f 导出文件地址 -O 备份数据库结构和数据,不设置拥有者 -s 只导出数据库结构 最后是库名 (全部导出)pg_dump -U post ...
- JavaSE基础知识(5)—面向对象(5.5 this和super关键字)
一.this关键字 1.说明 this关键字代表当前类的对象,可以访问本类的属性.方法.构造器注意:谁调用该方法,则this就指谁 2.语法 访问属性: this.属性名 = 值; System.ou ...
- spring微服务架构-脑图
spring团队对新一代软件开发的思索.为什么软件开发是spring boot?为什么软件开发是spring cloud?如何使用spring cloud搭建微服务. 清晰脑图查看
- Python-docx 读取word.docx内容
第一次写博客,也不知道要写点儿什么好,所以就把我在学习Python的过程中遇到的问题记录下来,以便之后查看,本人小白,写的不好,如有错误,还请大家批评指正! 中文编码问题总是让人头疼,想要用Pytho ...
- eclipse配置逆向工程
eclipse单行注释:ctrl + shfit + c 或者 Ctrl+/: 添加//注释 快速查找某个类:Ctrl+Shift +T 查找这个类的子类是ctrl+t eclips ...
- select标签操作
//遍历select标签 WebElement select = driver.findElement(By.tagName("select")); List<WebElem ...
- Sql Server免域,异地备份
--先决条件 开启xp_cmdshellEXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_c ...
- Effective C++ 笔记:条款 34 实现继承和接口继承
Differentiate between inheritance of interface and inheritance of implementation. 行为含义 声明一个pure virt ...
- su与su -的区别
su命令从普通用户切换到root用户下虽然可以切换,但是切换过后它所属的环境变量没有切换回原本属于root本身该有的环境变量,使用su - root 就可以切换会本来用户所属自身的变量
- Python Day 12
阅读目录: 内容回顾 函数默认值的细节 三元表达式 列表与字典推导式 函数对象 名称空间 函数嵌套的定义 作用域 ##内容回顾 # 字符串的比较 -- 按照从左往右比较每一个字符,通过字符对应的asc ...