Retrofit2的使用

第一次使用Retrofit2,并没有使用RxJava,解析返回的是String字符串

在app的build.gradle中添加依赖:

compile 'com.squareup.retrofit2:retrofit:2.3.0'
//字符串解析器
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'
//Gson解析器
//compile 'com.squareup.retrofit2:converter-gson:2.3.0'

添加混淆

## ----------------------------------
##      retrofit2相关
## ----------------------------------
-dontwarn retrofit2.**
-dontwarn com.squareup.retrofit2.Platform$Java8
-dontnote com.squareup.retrofit2.Platform
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
-keep class retrofit2.** { *; }

## ----------------------------------
##      okhttp3相关
## ----------------------------------
-dontwarn okhttp3.**
-keep class okhttp3.** { *;}
-dontwarn okio.**

创建HttpUtil工具类,retrofit的创建以及一些公共参数的添加和加密都写在util类里。

retrofit的创建:

private static HttpService mService;

    /**
     * 单例
     *
     * @return HttpService对象
     */
    public static HttpService getInstance() {
        synchronized (HttpUtil.class) {
            if (mService == null) {
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl(Constants.BASE_URL)
                        .addConverterFactory(ScalarsConverterFactory.create())
                        .build();
                mService = retrofit.create(HttpService.class);
            }
        }

        return mService;
    }

Constants.BASE_URL为服务器根地址。

HttpService类,就是retrofit请求的方法类。

public interface HttpService {

    @FormUrlEncoded
    @POST("/gateway")
    Call<String> userCall(@FieldMap Map<String, String> fields);

    @Multipart
    @POST("/gateway")
    Call<String> uploadSingle(@Part List<MultipartBody.Part> partList);

    @Streaming
    @GET
    Call<ResponseBody> downloadFileWithUrlAsync(@Url String fileUrl);

    @GET("/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true")
    Call<String> getCardDetail(@Query("cardNo") String cardNo);
}

其中,userCall为我们后台的接口请求方法,请求URL相当于Constants.BASE_URL+“/gateway”,@POST后path路径不能为空,由于我们的接口请求具体方法作为参数放在请求map中,所以所有获取展示信息的接口调用的都是userCall方法(根据服务器配置的不同,可以根据功能分为多个方法,或者多个service类);uploadSingle是文件上传方法;getCardDetail是调用支付宝API银行卡校验使用的查询方法。

userCall的使用(以获取验证码为例):

showProgressDialog("获取验证码...");
startTimer();
HashMap<String, String> postParams = new HashMap<>();
postParams.put("mobile", AppUtil.replaceBlock(phone));
postParams.put("method", Constants.GET_CODE_METHOD);
postParams.put("status", "2");
codeCall = HttpUtil.getInstance()
        .userCall(HttpUtil.getParamMap(postParams, false));
codeCall.enqueue(codeCallback);
//验证码请求
private Call<String> codeCall;
//验证回调
private Callback<String> codeCallback = new Callback<String>() {
    @Override
    public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
        MyLog.e(TAG, response.body());
        hideProgressDialog();
        if (HttpUtil.httpGetCode(response)) {
            CodeBean codeBean = new Gson().fromJson(response.body(), CodeBean.class);
            if (codeBean == null) {
                MyToast.showToast(Constants.ERROR_IN_TRANSLATE);
                stopTimer();
            } else {
                int code = codeBean.code;
                if (code == 200) {
                    hasSendCode = true;
                    CodeBean.DataBean jsonData = codeBean.data;
                    sessionId = jsonData.session_id;
                    MyToast.showToast("发送成功");
                } else {
                    stopTimer();
                    String message = codeBean.message;
                    if (code == 201) {
                        MyToast.showToast(message);
                    } else {
                        MyToast.showToast(code + ":" + message);
                    }
                }
            }
        } else {
            stopTimer();
        }
    }

    @Override
    public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
        stopTimer();
        hideProgressDialog();
        if (!call.isCanceled()) {
            if ("timeout".equals(t.getLocalizedMessage())) {
                MyToast.showToast(Constants.ERROR_TIME_OUT);
            } else {
                MyToast.showToast(Constants.ERROR_REQUEST_FAILED);
            }
        }
    }
};
@Override
protected void onStop() {
    super.onStop();
    if (codeCall != null) {
        codeCall.cancel();
    }
}

其中HttpUtil.getParamMap(postParams, false)为添加公共参数和加密的方法。

uploadSingle的使用:
与userCall一样:

/**
 * 上传图片
 */
 private void uploadImage(String path) {
     HashMap<String, String> params = new HashMap<>();
     params.put("method", Constants.UPLOAD_PHOTO_METHOD);
     params.put("user_id", CacheUtil.getString(Constants.ID, "0"));
     uploadCall = HttpUtil.getInstance()
             .uploadSingle(HttpUtil.getParts(params, activity, new File(path)), true));
     showProgressDialog("图片上传中...");
     uploadCall.enqueue(uploadCallback);
 }

不同的是对传递的参数进行的操作
HttpUtil.getParts(params, activity, new File(path)), true);

/**
 * 获取上传到服务器的参数
 *
 * @return MultipartBody.Part集合
 */
public static List<MultipartBody.Part> getParts(HashMap<String, String> postParams, Activity activity, File logoFile, boolean sso) {
    MultipartBody.Builder builder = new MultipartBody.Builder()
            .setType(MultipartBody.FORM);//表单类型
    Iterator<Map.Entry<String, String>> iterator = getParamMap(postParams, sso).entrySet().iterator();
//        添加参数
    while (iterator.hasNext()) {
        Map.Entry<String, String> next = iterator.next();
        String key = next.getKey();
        String value = next.getValue();
        builder.addFormDataPart(key, value);
    }
    File file = logoFile;
    if (logoFile.length() > 500 * 1024) {
        try {
            file = new Compressor(activity)
                    .setMaxWidth(300)
                    .setMaxHeight(300)
                    .setCompressFormat(Bitmap.CompressFormat.PNG)
                    .compressToFile(logoFile);

            MyLog.e(TAG, "图片大小" + android.text.format.Formatter.formatFileSize(activity, file.length()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
    builder.addFormDataPart("pic", "logo.png", imageBody);//imgfile 后台接收图片流的参数名
    return builder.build().parts();
}

此处为了使图片大小不超过500k,对图片进行了压缩,压缩添加依赖compile ‘id.zelory:compressor:2.1.0’;
builder.addFormDataPart(“pic”, “logo.png”, imageBody);
这句代码中pic为上传图片后台需要的参数名,logo.png为图片名。

downloadFileWithUrlAsync的使用

HttpUtil.getInstance()
                .downloadFileWithUrlAsync(downUrl)
                .enqueue(downloadCallback);

下载大文件,为避免将整个文件读进内存,需要添加@Streaming注解

//下载回调
    private Callback<ResponseBody> downloadCallback = new Callback<ResponseBody>() {
        @Override
        public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
            if (!response.isSuccessful()) {
                try {
                    if (response.errorBody() == null) {
                        MyToast.showToast(response.code() + ":" + response.message());
                    } else {
                        MyToast.showToast(response.errorBody().string());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else if (response.body() == null) {
                MyToast.showToast(Constants.ERROR_NO_DATA);
            } else {
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        downloadFileFromServer(response);
                    }
                }.start();

            }

        }

        @Override
        public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
            handler.sendEmptyMessage(UPDATE_END_CODE);
            MyToast.showToast("下载更新包失败");
            if (!"0".equals(type)) {
                finish();
                System.exit(0);
            }
        }
    };

getCardDetail的使用

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://ccdcapi.alipay.com")
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();
HttpService mService = retrofit.create(HttpService.class);
cardDetailCall = mService.getCardDetail(cardNo);
cardDetailCall.enqueue(cardDetailCallback);

这里因为调用的是支付宝的接口,baseUrl不一致,所以retrofit的创建没使用统一的HttpUtil中的实例。
对比HttpService中的getCardDetail方法:

@GET("/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true")
Call<String> getCardDetail(@Query("cardNo")String cardNo);

支付宝接口请求的url为:

http://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true&cardNo=输入的银行卡号

@Query(“cardNo”)注解表示传入的字符串为查询参数cardNo的值;

也可以使用@Url注解,重新定义接口地址,将地址以参数的形式传入。

@GET
Call<String> getCardDetail(@Url String url);

调用时:

Call<List<Activity>> call = HttpUtil.getInstance()
                .getCardDetail(
                "http://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true&cardNo="+cardNo);

注解中还有:
@QueryMap表示传入多个查询参数;
@Path(“test”)表示传入的参数作为路径(如:@GET(“/{test}”)),方法中可传入多个
@Body CommentBody body 表示传入的参数为CommentBody对象
@Field 表示POST请求传入单个字段,使用@Field时记得添加@FormUrlEncoded

Spring Boot可以使用Retrofit2和RestTemplate来进行网络请求。 首先,我们来看如何使用Retrofit2。首先,你需要在你的`pom.xml`文件中添加Retrofit2的依赖: ```xml <dependency> <groupId>com.squareup.retrofit2</groupId> <artifactId>retrofit</artifactId> <version>2.9.0</version> </dependency> ``` 接下来,创建一个Retrofit的实例,并定义一个接口来描述你的API: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); interface MyApi { @GET("endpoint") Call<MyResponse> getData(); } ``` 然后,你可以使用该接口来发起网络请求: ```java MyApi myApi = retrofit.create(MyApi.class); Call<MyResponse> call = myApi.getData(); call.enqueue(new Callback<MyResponse>() { @Override public void onResponse(Call<MyResponse> call, Response<MyResponse> response) { // 处理响应 if (response.isSuccessful()) { MyResponse myResponse = response.body(); // 处理成功的响应 } else { // 处理错误的响应 } } @Override public void onFailure(Call<MyResponse> call, Throwable t) { // 处理请求失败 } }); ``` 接下来,我们来看如何使用RestTemplate。首先,你需要在你的`pom.xml`文件中添加Spring Web的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 然后,在你的代码中创建一个RestTemplate实例,并使用它来发送HTTP请求: ```java RestTemplate restTemplate = new RestTemplate(); MyResponse response = restTemplate.getForObject("http://api.example.com/endpoint", MyResponse.class); ``` 以上就是使用Retrofit2和RestTemplate进行网络请求的基本步骤。你可以根据具体的需求进行适当的配置和定制化。 注意,在使用Retrofit2时,你需要定义一个接口来描述API,并使用注解来标记请求的方法和参数。而在使用RestTemplate时,你可以直接调用其提供的方法来发送请求,并将响应转换为你需要的对象类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值