okhttp+Retrofit+gson实现的基于https的服务器实现范例
来源:互联网 发布:淘宝双色球在哪里 编辑:程序博客网 时间:2024/06/06 03:38
Retrofit使用
使用到的依赖库,使用的时候添加依赖:
compile 'com.google.code.gson:gson:2.7'
//retrofit->resful api
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
//httpOk
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
1. 先定义好调用的接口。
例子:
public interface RestfulServer{
//用户注册
@POST("/user")
Call<UserSession> register(@Body User user);
//用户登录
@PUT("/user/{user_name}/login")
Call<UserSession> login(@Path("user_name") String user_name,@Body User user);
//上传头像
@Multipart
@POST("/user/{user_name}/avatar")
Call<UserSession> uploadImage(@Header("token") String token,@Path("user_name") String user_name,@Part MultipartBody.Part file);
//获取用户头像
@GET("/user/{user_name}/avatar")
Call<Bitmap> getImage(@Header("token") String token,@Path("user_name") String user_name);
}
1.@后面是请求的参数:@POST
2.请求后面括号里面的是请求的数据路径:("/user")
由于正式通讯的时候建立通讯的只有一个地址,但是数据是放到服务器下面不同的地址下面的。所以这里添加详细路径。比如
Retrofit.Builder
builder = new Retrofit.Builder().baseUrl("").//前面引号的是连接的网址https;//xxxx,这里删除了
addConverterFactory(GsonConverterFactory.
create());
这个例子:建立连接的时候都是一个地址,请求方法的时候需要加上/user,代表你请求的地址是:https://xxxx/user
比如:https://baidu/nihao,代表百度下面你好的路径。
3.Call是固定的,括号里面自定义的用于gson格式的数据定义。用于调用的时候,回调调用结果的使用的
4.函数名称后面的是需要传递的参数,http请求参数有header,body等如果没有和服务器定义,是可以不用填的。
例子:
//用户注册
@POST("/user")
Call<UserSession> register(@Body User user);
这里只有body需要传递参数(user是自己定义的传递给服务器的用户对象)。
//获取用户头像
@GET("/user/{user_name}/avatar")
Call<Bitmap> getImage(@Header("token") String token,@Path("user_name") String user_name);
这里获取用户头像就带上了header的参数,说明它是需要header数据的。
上面的请求路径:/user/{user_name}/avatar包含大括号。
大括号的意思是:路径不是固定的,比如这里的是用户登录的意思,请求路劲根据用户名的不同而不同。在后面@Path("user_name") String user_name把这个不确定的参数赋值。
2. 构造Retrofit.Builder。
Retrofit.Builder builder =
new Retrofit.Builder().
baseUrl("https://api.deplink.net").
addConverterFactory(GsonConverterFactory.create());
1. 这里传入需要连接的服务器地址,(http,https区别是数据加密)这里使用https的带加密的。
2. 这里GsonConverterFactory是定义了和服务器的通讯数据形式,是json格式的。
如果我们和服务器传递的不是json的格式,那要自定义这个ConverterFactory,然后把GsonConverterFactory用你自定义的那个就行了。
下面来看看自定义ConverterFactory:
我定义一个获取png图片的ConverterFactory
public class PngConvertFactory extendsConverter.Factory{
public static PngConvertFactory create() {
return new PngConvertFactory();
}
private PngConvertFactory() {
}
@Override
publicConverter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new PngResponseBodyConverter();
}
@Override
publicConverter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
}
}
下面是接收数据的类型:
public class PngResponseBodyConverterimplements Converter<ResponseBody, Bitmap> {
private static final StringTAG="PngConverter";
@Override
publicBitmap convert(ResponseBody value) throwsIOException {
try {
return getBitmapFromByte(value.bytes());
} finally {
Log.i(TAG,"getBitmapFromByte close");
value.close();
}
}
public Bitmap getBitmapFromByte(byte[] temp){
if(temp != null){
Bitmap bitmap = BitmapFactory.decodeByteArray(temp, 0, temp.length);
return bitmap;
}else{
return null;
}
}
}
下面是请求数据的类型:
public class PngRequestBodyConverter implementsConverter<String, RequestBody> {
@Override
publicRequestBody convert(String value) throwsIOException {
return null;
}
}
可以看到只特别定义了接收数据的格式,把接收到的数据转成bitmap,对上传的数据没有处理。
3. 构造OkHttpClient.Builder。
这里使用的okhhp框架
String ca = "" //ca就是加密的秘钥,就是一串字符串。
OkHttpClient.Builder clientBuilder =
new OkHttpClient.Builder();
clientBuilder
.connectTimeout(15 * 1000, TimeUnit.MILLISECONDS)
.readTimeout(20 * 1000, TimeUnit.MILLISECONDS)
.sslSocketFactory(SslUtil.getSocketFactory(ca));
OkHttpClient okClient = clientBuilder.build();
这里是构建sslsockeet的https请求。
public static SSLSocketFactory getSocketFactory(String certificate) {
SSLSocketFactory socketFactory = null;
try {
// Loading CAs from an InputStream
CertificateFactory cf =null;
cf = CertificateFactory.getInstance("X.509");
X509Certificate ca;
InputStream cert = new ByteArrayInputStream(certificate.getBytes());
ca = (X509Certificate)cf.generateCertificate(cert);
cert.close();
// Creating a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null,null);
keyStore.setCertificateEntry("ca-certificate", ca);
// Creating a TrustManager that trusts the CAs in our KeyStore.
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Creating an SSLSocketFactory that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(),null);
socketFactory = sslContext.getSocketFactory();
} catch(Exception e) {
e.printStackTrace();
}
return socketFactory;
}
4. OkHttpClient.Builder设置给Retrofit.Builder。
builder.client(okClient);
5. 下面就是把之前定义好的服务接口(RestfulServer)给其他类使用。
private volatile static RestfulServerapiService;
(这里使用volatile关键字是数据同步需要使用)
Retrofit retrofit = builder.build();
apiService = retrofit.create(RestfulServer.class);
6. .下面把服务接口都封装到一个sdk里面。
例子;登录接口
public Call<UserSession> login(String username, String password, Callback<UserSession> cll) {
User user = new User();
user.setName(username);
user.setPassword(password);
user.setApplication_key(DeplinkSDK.getAppKey());
Call<UserSession> call = apiService.login(username, user);
if (cll != null) {
call.enqueue(cll);
}
return call;
}
这样界面activity调用的时候就需要传递参数调用。
这里可以看到,函数设计的是,调用参数,然后加上返回结果的回调。
函数体中apiService,使用之前定义好的接口调用http或者https请求。
if (cll != null) {
call.enqueue(cll);
}
如果设置了回调,就把回调给放到队列中去。
难点例子:上传图片
接口:
//上传头像
@Multipart
@POST("/user/{user_name}/avatar")
Call<UserSession> uploadImage(@Header("token") String token,@Path("user_name") String user_name,@Part MultipartBody.Part file);
调用:
public Call<UserSession> uploadImage( String imagePath, Callback<UserSession> cll) {
File file = new File(imagePath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("avatar", file.getName(), requestFile);
Call<UserSession> call = apiService.uploadImage(token,username,body);
if (cll != null) {
call.enqueue(cll);
}
return call;
}
遇到的问题:服务器端说没有传递cookies给他。
在获取到cookies数据后保存起来,然后在连接的时候设置保存的cookies。
例子:
RestfulToolsPng.getSingleton(LoginActivity.this).getCaptcha(newCallback<Bitmap>() {
@Override
public voidonResponse(Call<Bitmap> call, Response<Bitmap> response) {
int code = response.code();
String token = response.headers().get("Set-Cookie");
Log.i(TAG,"cookies=" + token);
SharedPreferences sp = LoginActivity.this.getSharedPreferences("user_login",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("token_login", token);
editor.apply();
}
@Override
public voidonFailure(Call<Bitmap> call, Throwable t) {
}
});
cookies设置给okhttp
OkHttpClient.Builder clientBuilder = newOkHttpClient.Builder().cookieJar(newCookieJar() {
@Override
public voidsaveFromResponse(HttpUrl url, List<Cookie> cookies) {
StringBuilder sb=new StringBuilder();
for(inti=0;i<cookies.size();i++){
sb.append(cookies.get(i).toString());
}
Log.i("saveFromResponse",""+sb.toString());
}
@Override
publicList<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = new ArrayList<>();
SharedPreferences sp = mContext.getSharedPreferences("user_login", Context.MODE_PRIVATE);
String token = sp.getString("token_login",null);
if (token != null) {
Cookie cookie = Cookie.parse(url, token);
cookies.add(cookie);
}
return cookies;
}
});
- okhttp+Retrofit+gson实现的基于https的服务器实现范例
- 基于OKHttp实现对Https的支持
- android Retrofit+OkHttp使用自制的证书实现https安全传输
- android Retrofit+OkHttp使用自制的证书实现https安全传输
- 基于Retrofit实现HTTPS思路
- Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用
- Android HTTPS 自制证书实现双向认证(OkHttp + Retrofit + Rxjava)
- Android HTTPS 自制证书实现双向认证(OkHttp + Retrofit + Rxjava)
- retrofit+okhttp 实现缓存
- Retrofit+OKHttp实现缓存以及遇到的问题
- 使用rxjava,retrofit,okhttp实现mvp模式的数据解析
- rxjava+retrofit+okhttp实现流行的网络请求
- 基于Rxjava+Retrofit+Okhttp的webservices访问
- SharedPreferences+okhttp+gson+picasso实现简单的离线缓存
- Retrofit(一)、Retrofit+OkHttp实现简单的Get与Post请求
- Retrofit实现HTTPS请求
- Rxjava+Retrofit+okhttp+mvp实现
- 基于Retrofit、OkHttp、Gson封装通用网络框架
- Halcon学习(八)边缘检测(一)
- Glide加载转换Bitmap
- 自定义带标尺的seekbar
- 二进制中1的个数
- [JZOJ5456]【NOIP2017提高A组冲刺11.6】奇怪的队列
- okhttp+Retrofit+gson实现的基于https的服务器实现范例
- spark性能调优(三)shuffle的map端内存缓冲reduce端内存占比
- ClassNotFoundException: org.springframework.web.util.Log4jConfigLi
- 第九周,1题目:编写一个学生类students,该类成员变量包括学号no、姓名name、性别sex、和年纪age
- TensorFlow 遇到的问题(二)
- 按日期倒序排列,为空放在最上方展示
- 小问题合集
- 说说如何实现可扩展性的大型网站架构
- 根文件系统及Busybox简介