Solve the problem of using Okhttp+Retrofit to send network request and get json is unicode

Posted by davidb on Fri, 03 Jan 2020 01:59:46 +0100

When we use Okhttp and Retrofit to send network requests, the man in the json we get is unicode code, as shown in the figure below

At this time, we need to set the network editor when Okhttp is initialized, and change the return value code to UTF-8

OKhttp previously set

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(1800, TimeUnit.SECONDS)
                .readTimeout(1800, TimeUnit.SECONDS)
                .writeTimeout(1800, TimeUnit.SECONDS)
                .addNetworkInterceptor(logging)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request().newBuilder()
                                .header("is_app", "1")
                                .build();
                        return chain.proceed(request);
                    }
                }).build();

We can implement the Logger interface in HttpLoggingInterceptor in our own way to print out the data we want. Then we can operate as follows:

1. Create a new HttpLogger class to implement the Logger of HttpLoggingInterceptor

public class HttpLogger implements HttpLoggingInterceptor.Logger {
    private StringBuilder mMessage = new StringBuilder();
    private static final String TAG = "HttpLogger";
    @Override
    public void log(String message) {
        // Request or response start
        if (message.startsWith("--> POST")) {
            mMessage.setLength(0);
        }
        // The description in the form of {} or [] is the json data of the response result, which needs to be formatted
        if ((message.startsWith("{") && message.endsWith("}"))
                || (message.startsWith("[") && message.endsWith("]"))) {
            message = JsonUtil.formatJson(JsonUtil.decodeUnicode(message));
        }
        mMessage.append(message.concat("\n"));
        // End of response, print the whole log
        if (message.startsWith("<-- END HTTP")) {
            MyLogger.d(TAG,mMessage.toString());
        }
    }
}

In this way, we have realized the way of printing log s ourselves.

2. Create a new tool class of JsonUtil, as shown below:

public class JsonUtil {
    /**
     * Format json string
     *
     * @param jsonStr json string to be formatted
     * @return Formatted json string
     */
    public static String formatJson(String jsonStr) {
        if (null == jsonStr || "".equals(jsonStr)) return "";
        StringBuilder sb = new StringBuilder();
        char last = '\0';
        char current = '\0';
        int indent = 0;
        for (int i = 0; i < jsonStr.length(); i++) {
            last = current;
            current = jsonStr.charAt(i);
            //Encountered {[wrap, indent next line
            switch (current) {
                case '{':
                case '[':
                    sb.append(current);
                    sb.append('\n');
                    indent++;
                    addIndentBlank(sb, indent);
                    break;
                //Encountered}] newline, current line indented
                case '}':
                case ']':
                    sb.append('\n');
                    indent--;
                    addIndentBlank(sb, indent);
                    sb.append(current);
                    break;
                //Encountered, line feed
                case ',':
                    sb.append(current);
                    if (last != '\\') {
                        sb.append('\n');
                        addIndentBlank(sb, indent);
                    }
                    break;
                default:
                    sb.append(current);
            }
        }
        return sb.toString();
    }

    /**
     * Add space
     *
     * @param sb
     * @param indent
     */
    private static void addIndentBlank(StringBuilder sb, int indent) {
        for (int i = 0; i < indent; i++) {
            sb.append('\t');
        }
    }
    /**
     * http Request data to return Chinese characters in json as unicode code to Chinese character transcoding
     *
     * @param theString
     * @return The result of transformation
     */
    public static String decodeUnicode(String theString) {
        char aChar;
        int len = theString.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len; ) {
            aChar = theString.charAt(x++);
            if (aChar == '\\') {
                aChar = theString.charAt(x++);
                if (aChar == 'u') {
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = theString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed   \\uxxxx   encoding.");
                        }

                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't')
                        aChar = '\t';
                    else if (aChar == 'r')
                        aChar = '\r';
                    else if (aChar == 'n')
                        aChar = '\n';
                    else if (aChar == 'f')
                        aChar = '\f';
                    outBuffer.append(aChar);
                }
            } else
                outBuffer.append(aChar);
        }
        return outBuffer.toString();
    }

}

It has two ways: a makes the printed data clearer; b changes the unicode code to utf-8

3. Add the new HttpLogger to the network request interceptor

        HttpLogger httpLogger = new HttpLogger();
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(httpLogger);
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(1800, TimeUnit.SECONDS)
                .readTimeout(1800, TimeUnit.SECONDS)
                .writeTimeout(1800, TimeUnit.SECONDS)
                .addNetworkInterceptor(logging)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request().newBuilder()
                                .header("is_app", "1")
                                .build();
                        return chain.proceed(request);
                    }
                }).build();HttpLogger httpLogger = new HttpLogger();
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(httpLogger);
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(1800, TimeUnit.SECONDS)
                .readTimeout(1800, TimeUnit.SECONDS)
                .writeTimeout(1800, TimeUnit.SECONDS)
                .addNetworkInterceptor(logging)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request().newBuilder()
                                .header("is_app", "1")
                                .build();
                        return chain.proceed(request);
                    }
                }).build();

The blue font is the new code compared with the above. The yellow font represents adding the network request interceptor.

The printed data is clear:

{
                                                           	"success":true,
                                                           	"description":"Success",
                                                           	"biz":{
                                                           		"goods_info":{
                                                           			"real_payment":"100.00",
                                                           			"goods_name":"Sweater",
                                                           			"mailcode":"3912691654392",
                                                           			"mailcode_company":"yunda",
                                                           			"status":100,
                                                           			"goods_images":"https://img.kaishiqianbao.com/2018-05-08/shop_goods5af1315d7fba6376811.jpeg"
                                                           		},
                                                           		"logistics":{
                                                           			"message":"ok",
                                                           			"nu":"3912691654392",
                                                           			"ischeck":"1",
                                                           			"condition":"F00",
                                                           			"com":"yunda",
                                                           			"status":"200",
                                                           			"state":"3",
                                                           			"data":[
                                                           				{
                                                           					"time":"2017-12-28 18:51:24",
                                                           					"ftime":"2017-12-28 18:51:24",
                                                           					"context":"[
                                                           						//Changping rongzejiayuan Service Department of Beijing main city company
                                                           					]Express has been signed in",
                                                           					"location":"Changping rongzejiayuan Service Department of Beijing main city company"
                                                           				},
                                                           				{
                                                           					"time":"2017-12-28 18:46:54",
                                                           					"ftime":"2017-12-28 18:46:54",
                                                           					"context":"[
                                                           						//Changping rongzejiayuan Service Department of Beijing main city company
                                                           					]Carry out dispatch scanning; dispatch salesman: Lei Senhao; Tel: 17610460722",
                                                           					"location":"Changping rongzejiayuan Service Department of Beijing main city company"
                                                           				}
                                                           			]
                                                           		}
                                                           	}
                                                           }

 

Topics: JSON network OkHttp Retrofit