认证android retrofit,Retrofit之项目介绍

项目介绍

官网对retrofit介绍是这是一个"类型安全(type-safe)"的Android/Java http客户端. 目前retrofit的最新正式版本为1.9.0. 2.0版本预计2015年底发布, 相较于之前版本, 2.0版本在架构上做了很大改变, 本文代码相关的内容都是基于retrofit2.0-beta2.

注: 在编程语言的语法中, type-safe通常指编译器在编译时检查变量的类型, 如果试图向 变量分配一个错误的类型,编译器就会报错.

在项目中使用retrofit

retrofit库可以在maven.org 找到. 可以直接添加到maven或gradle工程中.Maven #+BEGIN_SRC xml

com.squareup.retrofitretrofit2.0.0-beta2 #+END_EXAMPLEGradle. 如果与服务端的请求和结果都是json的话,需要gson converter进行转化, 因为要把该库也添加上. #+BEGIN_SRC xml compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' #+END_EXAMPLE

混淆配置 如果项目中使用混淆的话, 需要在混淆文件中假如如下配置-dontwarn retrofit.**-keep class retrofit.** { *; }-keepattributes Signature-keepattributes Exceptions

程序示例

一个简单的retrofit程序

场景:通过GET请求向服务器返回用户信息, 服务器通过Json格式返回一个或多个用户的信息. 基于这个例子介绍一下retrofit的使用步骤:用户类. 这段代码定义了用户类User, 每个用户包含三个基本信息:id, name, age; 通过retrofit请求用户信息时, 客户端返回用户的json信息, retrofit可以直接将json信息转化为用户类.public class User {

private int id;

private String name;

private int age;}

定义Client和GET请求接口public interface Client {

@GET("users")

Call>  getUsers();}

这段代码定义了一个接口Client, 并定义了一个GET函数getUsers(), 该函数用户向服务器发送get请求获取所有的 用户信息. 定义GET请求需要用GET注解来修饰函数, 注解的参数为uri的相对路径, 下一部分会定义URL的地址, 在 发送GET请求时, retrofit会将GET的参数和服务器拼接. 后面会在该接口中实现其他的POST和GET函数.

注: 在retrofit2.0中,要注意GET和POST注解的参数,如果参数以"/"开头,那么在跟base地址拼接时,会将base地址中 的相对地址全部覆盖掉. 举例: base地址为"http://a/b", GET参数为"/c/d", 那么最后的请求地址为"http://a/c/d", 因此,如果base地址本身已经是相对地址, 那么GET/POST的参数不能以"/"开头.

public class MainActivity {

....

public static final String SERVER_URL = "http://10.10.10.10/account";

private OkHttpClient okHttpClient = new OkHttpClient();

private Retrofit.Builder builder = new Retrofit.Builder()

.base_url(SERVER_URL)

.client(okHttpClient)

.addConvertFactory(GsonConvertFactory.create());

Retrofit retrofit = builder.build();

Client client = retrofit.create(Client.class);

Call> call = client.getUsers();

List result = call.execute().body();

....}

上述代码用来做实际的请求动作, 首先通过Retrofit Builder来基于各种参数(服务器地址, httpclient, converter) 生成一个builder对象, 让后调用builder的build()函数生成一个retrofit对象.

接着,调用retrofit的create()函数,传入上一步中定义的接口作为参数来实例化一个具体的接口对象, 然后调用 该对象的具体http请求函数(这里为getUsers())来实现http请求. 请求的结果是Json数据,会通过GsonConverter转化为具体的 对象(即User). 由于是多个对象,所以需要放到一个List中.

上述三步即为retrofit的基本使用方法.

创建一个Service generator类

如果项目中 针对同一个server地址 需要创建多个Retrofit Interface service,那么可以创建一个通用的ServiceGenerator类 来生成service实例.public class ServiceGenerator {

public static final String BASE_URL = "";

private static OkHttpClient httpClient = new OkHttpClient();

private static Retrofit.Builder builder =

new Retrofit.Builder()

.baseUrl(BASE_URL)

.addConverterFactory(GsonConverterFactory.create());

public static  T createService(Class serviceClass){

//把设置client放到这里是因为后续有对client进行配置的需求

Retrofit retrofit = builder.client(httpClient).build();

return retrofit.create(serviceClass);

}

}

这样在上一节的MainActivity中,可以直接使用ServiceGenerator来创建Client实例Client client = ServiceGenerator.create(Client.class);Client call = client.getUsers();List result = call.execute().body();

帐号密码认证的ServiceGenerator类

帐号密码是一种常见的认证方式, 通常将其加密后以放入到http头部的Authorization中 进行请求认证.通过对OkHttpClient进行配置可以在retrofit中实现该方式.public static  T createService(Class serviceClass){

createService(serviceClass, null, null);}pubic static  T createService(Class serviceCls, String userName, String passWord)  {

if (userName != null && passWord != null) {

//对用户名和密码进行加密(不同的需求加密方式不一样, 这里只提供参考)

String credentials = userName + ":" + passWord;

final String base64Str = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);

httpClient.interceptors().clear();

httpClient.interceptors().add(new Interceptor() {

@Override

public Response intercept(Interceptor.Chain chain) throws IOException {

Request original = chain.request();

Request.Builder requestBuilder = original.newBuilder()

.header("Authorization", basic);

.header("Accept", "applicaton/json");

.method(original.method(), original.body());

Request request = requestBuilder.build();

return chain.proceed(request);

}

});

}

Retrofit retrofit = builder.client(httpClient).build();

return retrofit.create(serverClass);}

上述代码通过修改OkHttpClient的相关参数来修改API请求的头部, 讲加密后的帐号和密码放入到 Authorization中实现验证.

注: Interceptors是属于OkHttp的相关内容, 这部分在后面学习OkHttp时会介绍.

OAuth认证接口的ServiceGenerator类

整合过第三方API的同学肯定对OAuth接口不陌生, 大部分情况下你都需要去第三方开发者 平台注册你的app去获取一个id和secret, 这样才可以访问第三方的接口.

注: 关于oauth的介绍可以参考阮一峰老师的文章 理解OAuth2.0.

基于前面的代码, 重新写一个OAuth相关的createService()函数.public static  T createService(Class serviceClass, AccessToken token) {

if (token != null) {

httpClient.interceptors().clear();

httpClient.interceptors().add(new Interceptor() {

@Override

public Response intercept(Interceptor.Chain chain) throws IOException {

Request original = chain.request();

Request.Builder builder2 = original.newBuilder()

.header("Accept", "application/json")

.header("Authorization", token.getTokenType()+ " " + token.getAccessToken())

.method(original.method(), original.body());

Request request = builder2.build();

return chain.proceed(request);

}

});

Retrofit retrofit = builder.client(httpClient).build();

return retrofit.create(serverClass);

}}

上面的代码通过创建一个定制的 RequestInterceptor 对象来配置httpClient, 在定制的对象中将token信息 添加到Http表头的Authorization域. 不过一般情况下, Access Token并不是直接可以从服务器获取的, 下面就会讲解一下获取Access Token的常用方法.

场景: 假设你已经在第三方网站注册了你的app, 获取了一个clientId 和 secret, 你使用这个帐号来想注册服务器获取 授权码(一般是跳转到一个网页, 点击允许操作), 然后再通过授权码获取Access Token, 下面是主要流程.获取授权码 授权码的获取一般需要跳转到第三方api的一个相关的网页,网页中会询问用户是否允许用户 app获取其在该网站的信息.如果用户点击允许, 第三方服务器就会生成一个授权码返回给用户. 第一步先创建程序主界面:public class LoginActivity extends Activity {

//在第三方平台注册应用获取的clientId和secret

private final String clientId = "your-client-id";

private final String clientSecret = "your-client-secret";

//获取跳转码后的跳转url, 在申请授权码时需要一并传给第三方服务器

private final String redirectUri = "your://redirecturi";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_login);

Button loginButton (Button) findViewById(R.id.loginbutton);

loginButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(

Intent.ACTION_VIEW,

Uri.parse(ServiceGenerator.API_BASE_URL + "/login" + "?client_id=" + clientId + "&redirect_uri=" + redirectUri));

startActivity(intent);

}

});

}}

上述代码定义了一个基本的Android界面, 界面只有一个按钮, 点击按钮会请求授权码(一般会跳转到一个授权界面). 在请求中传入一个了回调地址, 如果用户授权一般第三方服务器带着授权码会跳到这个地址, 所以必须在请求授权码 时传入回调地址. 这在Android中会表现发送回调Uri的广播,并将授权码通过intent传递出去. 所以app中需要在注册一个可以接受该intent的界面,这里还是使用主界面. 在AndroidMainfest.xml中设置intent-filter #+BEGIN_SRC xml

#+END_EXAMPLE

在onResume处理接受到的Intent. 这里假设授权码在intent中传递并且key值为code(第三方平台的回调方式需要参考他们的文档).@Overrideprotected void onResume() {

super.onResume();

Uri uri = getIntent().getData();

if (uri != null && uri.toString().startsWith(redirectUri)) {

String code = uri.getQueryParameter("code");

if (code != null) {

//处理授权码

} else if (uri.getQueryParameter("error") != null) {

//处理错误

}

}}

好, 到此为止,我们就已经获取到了授权码,下一步就是通过授权码获取Access Token.获取Access Token 上一步获取到授权码后, 就可以向第三方的Access Token服务器发送请求获取token. 我们可以写一个retrofit服务 来实现这个功能.public interface LoginService {

@POST("/token")

Call getAccessToken(

@Query("code") String code,

@Query("grant_type") String grantType);}

这里的code就是上一步获取的授权码, grantType是授权类型. 然后用下面的代码加入到onResume获取成功的代码段中if (code != null) {

// get access token

LoginService loginService =

ServiceGenerator.createService(LoginService.class, clientId, clientSecret);

Call call = loginService.getAccessToken(code, "authorization_code");

AccessToken accessToken = call.execute().body();}

以上都是示例, 代码具体写法请参考相关第三方文档.

同步请求 vs 异步请求

Retrofit支持同步和异步请求, 不过Retrofit2的同步/异步架构功能与1有 很大不同, 具体请参考相关文档.同步请求 直接调用execute()函数, 本文中的实例就是同步请求的例子.

注意事项:不要在Android的主线程中调用execute(),有可能报错或导致ANR.

异步请求 异步请求的话调用enque()函数, 并向enque()传入一个Callback的参数. 并需要要实现Callback的onSuccess和onFailure函数.

请求结果Response类

当调用execute()或enqueue()函数时, 会返回一个Reponse对象表示请求结果. 该请求结果包含了以下信息:结果码: 调用code()函数获得

结果对象: 调用body()函数获得, 如示例所示.

头部: 调用headers

原始返回结果: 调用rawResponse()函数, 返回一个OkHttp的Response对象.

Tips请求失败, body()返回值为null

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396008.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

层次聚类算法 算法_聚类算法简介

层次聚类算法 算法Take a look at the image below. It’s a collection of bugs and creepy-crawlies of different shapes and sizes. Take a moment to categorize them by similarity into a number of groups.看看下面的图片。 它是各种形状和大小的错误和令人毛骨悚然的爬…

.h .dll .lib

.h为对一个函数的声明引用,include就是声明某个文件里的函数(内只有声明函数被引用了),编译时使用 .lib为链接时用的,存放的是对于DLL里函数的位置信息等,这样不必把所有dll里函数都加载到内存里&#xff0…

《机器人学经典教程》——2.2 控制论

本节书摘来异步社区《机器人学经典教程》一书中的第2章,第2.2节,作者:【美】Maja J. Matarić(马娅•马塔里奇),更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.2 控制论 随着控制理论的不断发展…

哔哩哔哩网站前端源码_分享一个仿制哔哩哔哩镜子网站源码

我老婆非常喜欢看哔哩哔哩,前些天她兴奋地和我说哔哩哔哩网站有个隐藏的彩蛋,传送门http://www.ilidilid.com/,我看了下,相当于把镜子中的网站样子弄出来了。于是,我寻思着,把自己的博客也弄个这样的彩蛋&a…

promise-async-await

通常而言,这3个关键字 都是用来「优雅」的处理ajax异步请求的 //es6的时候promise诞生,很好的解决了嵌套回调地狱,改良方案为链式回调。// es2017的时候诞生了async、await,这下异步直接没有回调了,像同步一样爽//没有…

第一冲刺阶段博客检查

我们检查的团队是:红鸟 ①团队博客: 该团队将所有的站立会议均写到了4月28日的一篇博客中,并且其中任务看板和燃尽图不全。 ②团队成员个人博客: 1>张晓晨: 没有每天个人工作总结。 2>王晓思: 从4.19…

netcore 编译 html,Asp.Net Core中的@ Html.Action

小编典典更新:从2.2.2版本开始,HttpContextAccessor将上下文保留在一个对象中(据说是为了防止请求之间的混淆),这会影响当前解决方案…因此,您需要为IHttpContextAccessor(旧版本)提供以下实现并进行注册作为一个单例:…

《CCIE路由和交换认证考试指南(第5版) (第1卷)》——1.6节虚拟交换系统

本节书摘来自异步社区《CCIE路由和交换认证考试指南(第5版) (第1卷)》一书中的第1章,第1.6节虚拟交换系统,作者 【美】Narbik Kocharians(那比克 科查理安) , 【斯洛伐克】Peter Pal…

机器学习 美股_我如何使用机器学习来探索英美文学之间的差异

机器学习 美股by Sofia Godovykh索非亚戈多维克(Sofia Godovykh) 我如何使用机器学习来探索英美文学之间的差异 (How I used machine learning to explore the differences between British and American literature) As I delved further into English literature to further…

远程执行漏洞修复方案_请马上修复!SaltStack远程命令执行漏洞

【漏洞预警】SaltStack远程命令执行漏洞(CVE-2020-11651、CVE-2020-11652)2020年5月3日,阿里云应急响应中心监测到近日国外某安全团队披露了SaltStack存在认证绕过致命令执行漏洞以及目录遍历漏洞。漏洞描述SaltStack是基于Python开发的一套C/S架构配置管理工具。国…

kafka部分重要参数配置-broker端参数

broker端参数主要在config/server.properties目录下设置: 启动命令:nohup ./kafka-server-start.sh -daemon ../config/server.properties & broker.id参数:Kafka使用唯一的一个整数来标识每个broker,全局唯一,默认…

JS正则表达式大全(整理详细且实用)

JS正则表达式大全(整理详细且实用) 作者: 字体:[增加 减小] 类型:转载 时间:2013-11-14 我要评论 JS正则表达式大全(整理详细且实用)。需要的朋友可以过来参考下,希望对大家有所帮助正则表达式中的特殊字符 字符 含意…

html设置模块宽度为200像素,css 宽度(CSS width)

DIV CSS宽度width样式属性CSS 宽度是指通过CSS 样式设置对应div宽度,以下我们了解传统html宽度、宽度自适应百分比、固定宽度等宽度知识。传统Html 宽度属性单词:width 如width"300";CSS 宽度属性单词:width 如width:300px;一、Wid…

我从Stack Overflow对64,000名开发人员的大规模调查中学到的东西

Today Stack Overflow released the results of their 2017 survey of more than 64,000 developers.今天,Stack Overflow发布了他们对64,000多名开发人员的2017年调查结果。 Just like in 2016, I’ve combed through these results and summarized them for you.…

《Node应用程序构建——使用MongoDB和Backbone》一第 1 章 介绍与总览1.1 打造一个社交网络...

本节书摘来自异步社区《Node应用程序构建——使用MongoDB和Backbone》一书中的第1章,第1.1节,作者【美】Mike Wilson,更多章节内容可以访问云栖社区“异步社区”公众号查看 第 1 章 介绍与总览 Node应用程序构建——使用MongoDB和Backbone互…

jquery 样式获取设置值_jQuery获取样式中的背景颜色属性值/颜色值

天使用jQuery获取样式中的background-color的值时发现在获取到的颜色值在IE中与Chrome、Firefox显示的格式不一样,IE中是以HEX格式显示#ffff00,而Chrome、Firefox中则是以GRB格式显示rgb(255,0,0),由于需要将颜色值存储到数据库中&#xff0c…

计算机专业做产品,非计算机专业如何做产品经理?

《硅谷产品实战》学习笔记 32课这节课中讲了计算机专业背景对产品经理的帮助:第一印象;判断项目复杂度;了解技术可否实现,有何限制?对于没有计算机专业背景的产品如何弥补专业不足?关于如何判断项目复杂度在…

_UICreateCGImageFromIOSurface 使用API

上传的时候,苹果发送邮件 Non-public API usage: The app references non-public symbols in DUO-LINK 4: _UICreateCGImageFromIOSurfaceIf method names in your source code match the private Apple APIs listed above, altering your method names will help …

匹配一个字符串的开头和结尾_我如何构建一个应用程序来展示精彩小说的开头和结尾

匹配一个字符串的开头和结尾I know sentences. In my decade as a print journalist, I’ve written hundreds of articles for dozens of publications. I’ve dished out more sentences than Judge Judy. But I didn’t study writing or journalism, at least not formally…

python 社区网络转化_python-将numpy打开网格转换为坐标

方法1使用np.meshgrid,然后堆叠-r,c np.meshgrid(*m)out np.column_stack((r.ravel(F), c.ravel(F) ))方法2或者,使用np.array()然后进行转置,重塑-np.array(np.meshgrid(*m)).T.reshape(-1,len(m))对于np.ix_中使用的通用数组数目的通用情况,这里是需要进行的修改-p np.r_[…