Android实战----Android Retrofit2.1.0直接发送Json字符串到服务器

Posted Herman-Hong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战----Android Retrofit2.1.0直接发送Json字符串到服务器相关的知识,希望对你有一定的参考价值。

可以用@body注解(将数据添加到requestbody中)、设置retrofit requestbody的编码格式为json

一、接口类

public interface IHttpService 

    /**
     * 
     * @param params
     * @return
     */
    @POST("ad/getAds.do")
    Call<Ads> getAds(@Body Map<String, Object>params);


二、retrofit配置

public class RetrofitHttpRequest 
    /**
     * 超时时间60s
     */
    private static final long DEFAULT_TIMEOUT = 60;
    private volatile static RetrofitHttpRequest mInstance;
    public Retrofit mRetrofit;
    public IHttpService mHttpService;

    private RetrofitHttpRequest() 
        mRetrofit = new Retrofit.Builder()
                .baseUrl(UrlConfig.ROOT_URL)
                .client(genericClient())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        mHttpService = mRetrofit.create(IHttpService.class);
    

    public static RetrofitHttpRequest getInstance() 
        if (mInstance == null) 
            synchronized (RetrofitHttpRequest.class) 
                if (mInstance == null)
                    mInstance = new RetrofitHttpRequest();
            
        
        return mInstance;
    

    /**
     * 添加统一header,超时时间,http日志打印
     * body采用UTF-8编码
     *
     * @return
     */
    public static OkHttpClient genericClient() 
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() 
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException 
                        Request request = chain.request();
                        Request.Builder requestBuilder = request.newBuilder();
                        request = requestBuilder
                                .addHeader("Content-Type", "application/json;charset=UTF-8")   
                                .post(RequestBody.create(MediaType.parse("application/json;charset=UTF-8"),
                                        bodyToString(request.body())))//关键部分,设置requestBody的编码格式为json
                                .build();
                        return chain.proceed(request);
                    
                )
                .addInterceptor(logging)
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .build();
        return httpClient;
    


    /**
     * 将call加入队列并实现回调
     *
     * @param call             调入的call
     * @param retrofitCallBack 回调
     * @param method           调用方法标志,回调用
     * @param <T>              泛型参数
     */
    public static <T> void addToEnqueue(Call<T> call, final RetrofitCallBack retrofitCallBack, final int method) 
        final Context context = MyApplication.getContext();
        call.enqueue(new Callback<T>() 
            @Override
            public void onResponse(Call<T> call, Response<T> response) 
                LogUtil.d("retrofit back code ====" + response.code());
                if (null != response.body()) 
                    if (response.code() == 200) 
                        LogUtil.d("retrofit back body ====" + new Gson().toJson(response.body()));
                        retrofitCallBack.onResponse(response, method);
                     else 
                        LogUtil.d("toEnqueue, onResponse Fail:" + response.code());
                        ToastUtil.makeShortText(context, "网络连接错误" + response.code());
                        retrofitCallBack.onFailure(response, method);
                    
                 else 
                    LogUtil.d("toEnqueue, onResponse Fail m:" + response.message());
                    ToastUtil.makeShortText(context, "网络连接错误" + response.message());
                    retrofitCallBack.onFailure(response, method);
                
            

            @Override
            public void onFailure(Call<T> call, Throwable t) 
                LogUtil.d("toEnqueue, onResponse Fail unKnown:" + t.getMessage());
                t.printStackTrace();
                ToastUtil.makeShortText(context, "网络连接错误" + t.getMessage());
                retrofitCallBack.onFailure(null, method);
            
        );
    

    private static String bodyToString(final RequestBody request) 
        try 
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if (copy != null)
                copy.writeTo(buffer);
            else
                return "";
            return buffer.readUtf8();
         catch (final IOException e) 
            return "did not work";
        
    


三、使用

private void getAds()
        showWaitDialog();
        Map<String, Object> signMap = new HashMap<String, Object>();
        signMap.put("channelId", "洪海亮");
        signMap.put("position", 1);
        signMap.put("status", "1");
        Map<String, Map<String, Object>> reqMap = SignUtil.jsonMd5(signMap);
        RetrofitHttpRequest.addToEnqueue(RetrofitHttpRequest.getInstance().mHttpService.getAds(reqMap.get("req")),
                this, HttpStaticApi.HTTP_GETADS);
    

jsonMd5实现

/**
     * 使用md5对字符串加密加密
     * @param signMap
     * @return
     */
    public static Map<String, Map<String, Object>> jsonMd5(Map<String, Object> signMap)
        String signData = new Gson().toJson(signMap);
        signData = signData + "&" + UrlConfig.APPKEY;
        String signDataA = StringUtil.md5(signData);
        Map<String, Object> datamap = new HashMap<String, Object>();
        datamap.put("reqData", signMap);
        datamap.put("token",signDataA);
        Map<String, Map<String, Object>> reqMap = new HashMap<String, Map<String, Object>>();
        reqMap.put("req", datamap);
        LogUtil.d("reqMap=====" + reqMap.toString());
        return reqMap;
    


请求json串为

D/OkHttp: --> POST http://xxx/ad/getAds.do http/1.1
D/OkHttp: Content-Type: application/json;charset=UTF-8
D/OkHttp: Content-Length: 106
D/OkHttp: "reqData":"position":1,"status":"1","channelId":"洪海亮","token":"e75ec317dc97138af6b20caf614ecc7c"
D/OkHttp: --> END POST (106-byte body)


以上是关于Android实战----Android Retrofit2.1.0直接发送Json字符串到服务器的主要内容,如果未能解决你的问题,请参考以下文章

android实战网址

Android项目实战Android开发进阶学习

okhttp文件上传失败,居然是Android Studio背锅?

Android实战技巧:ViewStub的应用

Android实战Android中处理崩溃异常

Android开发实战(二十一):浅谈android:clipChildren属性