Retrofit2拦截器在Android中将特殊字符转换为问号

时间:2019-01-08 14:53:43

标签: java android encryption aes retrofit2

诸如(“”,')之类的特殊字符被转换为?。申请时 Retrofit2中的拦截器。从Retrofit2获得响应时,我得到特殊字符,但拦截器将特殊字符更改为?和显示?代替特殊字符

在拦截器中添加改造:

 CustomRequestInterceptor requestInterceptor = newCustomRequestInterceptor();
 HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
 logging.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : 
 HttpLoggingInterceptor.Level.NONE);
 OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
 httpClient.addInterceptor(requestInterceptor);
 httpClient.addInterceptor(logging);

用于Retrofit2的拦截器类(CustomRequestInterceptor.java):

public class CustomRequestInterceptor implements Interceptor {

    private static String newToken;
    private String bodyString;

    private final String TAG = getClass().getSimpleName();


    @Override
    public Response intercept(Chain chain) throws IOException {


        String token = "";
        Request request = chain.request();
        RequestBody oldBody = request.body();

        Buffer buffer = new Buffer();
        oldBody.writeTo(buffer);

        String strOldBody = buffer.readUtf8();
        Log.i(TAG, "original req " + strOldBody);
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        JSONObject jsonObject = new JSONObject();
        String decodedStr = decoder(strOldBody.replace("data=", ""));
        try {

            if (decodedStr != null && decodedStr.equalsIgnoreCase("")) {
                token = getRandomNumber();
                jsonObject.put("auth_token", token);
            } else {
                jsonObject = new JSONObject(decodedStr);
                token = getRandomNumber();
                jsonObject.put("auth_token", token);
            }

        } catch (Exception e) {
            Log.e(AppConstants.TAG, "Exception", e);
        }

        Log.i(AppConstants.TAG, "Request JSONObject " + jsonObject.toString());
        String strNewBody = "data=" + URLEncoder.encode(Encryption.encryptString(jsonObject.toString()));


        Log.i(TAG, "strNewBody " + strNewBody);
        RequestBody body = RequestBody.create(mediaType, strNewBody);

        Log.i(TAG, "content type is " + body.contentType().toString());
        Log.i(TAG, "content length is " + String.valueOf(body.contentLength()));
        Log.i(TAG, "method is " + request.method());

        request = request.newBuilder().header("Content-Type", body.contentType().toString())
                .header("Content-Length", String.valueOf(body.contentLength()))
                .method(request.method(), body).build();


        Response response = chain.proceed(request);
        String responseString = new String(response.body().bytes());
        Log.i(TAG, "Response: " + responseString);
        String newResponseString = Encryption.decryptString(responseString);
        Log.i(TAG, "Response edited: " + URLDecoder.decode(newResponseString));
        JSONObject res_JsonObject = new JSONObject();
        if (newResponseString.startsWith("{")) {
            try {
                res_JsonObject = new JSONObject(newResponseString);
                String response_token = res_JsonObject.getString("auth_token");
                if (response_token.equalsIgnoreCase("" + token)) {

                } else {
                    res_JsonObject.put("status", false);
                    res_JsonObject.put("message", "Authentication Failed");
                    Toast.makeText(new AppController().getApplicationContext(), "Authentication Failed", Toast.LENGTH_LONG).show();
                }

            } catch (Exception e) {
                Log.e(AppConstants.TAG, "Exception", e);
            }
        }

        byte[] ptext = res_JsonObject.toString().getBytes(ISO_8859_1);
        String value = new String(ptext, UTF_16);

        return response.newBuilder()
                .body(ResponseBody.create(response.body().contentType(), value))
                .build();
    }

    public String decoder(String encodedStr) {
        try {
            return URLDecoder.decode(encodedStr);

        } catch (Exception e) {

            Log.e(AppConstants.TAG, "Exception", e);
            return encodedStr;
        }
    }
}

预期输出:

{
  "comment": "“hello”"
}

实际输出:

{
  "comment": "?hello?"
}

1 个答案:

答案 0 :(得分:2)

问题出在拦截方法的return语句中,     当我们调用ResponseBody.create()时,responsebody类将数据转换为UTF-8格式,而UTF-8不支持诸如(“,”)之类的字符,因此它给我们“?”符号,因为我们已经给出了response.body()。contentType(),所以它转换为默认的UTF-8。     解决方案是不要将response.body()。contentType()传递给create()并提供自己的contentType。 这是更新的类。

public class CustomRequestInterceptor implements Interceptor {

    private static String newToken;
    private String bodyString;

    private final String TAG = getClass().getSimpleName();


    @Override
    public Response intercept(Chain chain) throws IOException {


        String token = "";
        Request request = chain.request();
        RequestBody oldBody = request.body();

        Buffer buffer = new Buffer();
        oldBody.writeTo(buffer);

        String strOldBody = buffer.readUtf8();
        Log.i(TAG, "original req " + strOldBody);
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        JSONObject jsonObject = new JSONObject();
        String decodedStr = decoder(strOldBody.replace("data=", ""));
        try {

            if (decodedStr != null && decodedStr.equalsIgnoreCase("")) {
                token = getRandomNumber();
                jsonObject.put("auth_token", token);
            } else {
                jsonObject = new JSONObject(decodedStr);
                token = getRandomNumber();
                jsonObject.put("auth_token", token);
            }

        } catch (Exception e) {
            Log.e(AppConstants.TAG, "Exception", e);
        }

        Log.i(AppConstants.TAG, "Request JSONObject " + jsonObject.toString());
        String strNewBody = "data=" + URLEncoder.encode(Encryption.encryptString(jsonObject.toString()));


        Log.i(TAG, "strNewBody " + strNewBody);
        RequestBody body = RequestBody.create(mediaType, strNewBody);

        Log.i(TAG, "content type is " + body.contentType().toString());
        Log.i(TAG, "content length is " + String.valueOf(body.contentLength()));
        Log.i(TAG, "method is " + request.method());

        request = request.newBuilder().header("Content-Type", body.contentType().toString())
                .header("Content-Length", String.valueOf(body.contentLength()))
                .method(request.method(), body).build();


        Response response = chain.proceed(request);
        String responseString = new String(response.body().bytes());
        Log.i(TAG, "Response: " + responseString);
        String newResponseString = Encryption.decryptString(responseString);
        JSONObject res_JsonObject = new JSONObject();
        if (newResponseString.startsWith("{")) {
            try {
                res_JsonObject = new JSONObject(newResponseString);
                String response_token = res_JsonObject.getString("auth_token");
                if (response_token.equalsIgnoreCase("" + token)) {

                } else {
                    res_JsonObject.put("status", false);
                    res_JsonObject.put("message", "Authentication Failed");
                    Toast.makeText(new AppController().getApplicationContext(), "Authentication Failed", Toast.LENGTH_LONG).show();
                }

            } catch (Exception e) {
                Log.e(AppConstants.TAG, "Exception", e);
            }
        }

        MediaType contentType = MediaType.parse(response.body().contentType() + "; charset=utf-32");

        return response.newBuilder()
                .body(ResponseBody.create(contentType, newResponseString.getBytes()))
                .build();
    }

    public String decoder(String encodedStr) {
        try {
            return URLDecoder.decode(encodedStr);

        } catch (Exception e) {

            Log.e(AppConstants.TAG, "Exception", e);
            return encodedStr;
        }
    }

}