请求接口后的日志处理,显示在app界面上,方便测试人员与后端人员对调

由于测试、后端人员要求,需要在测试的时候随时查看请求日志。故写下此配置,记录一下
class NetWorkConsoleUtil private constructor() {
    private val TAG = NetWorkConsoleUtil::class.java.simpleName
    private val OMITTED_RESPONSE: String = "response body type:"
    private val OMITTED_REQUEST: String = "request body type:"
    private val UTF8 = Charset.forName("UTF-8")
    private lateinit var netLogList: MutableList<String>
    private lateinit var sensorTrackList: MutableList<String>

    init {
        if (!this::netLogList.isInitialized) {
            netLogList = mutableListOf()
        }
        if (!this::sensorTrackList.isInitialized) {
            sensorTrackList = mutableListOf()
        }
    }

    companion object {
        val INSTANCE: NetWorkConsoleUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            NetWorkConsoleUtil()
        }
    }

    fun setSensorTrackLogInfo(trackSaId: String){
        if (this::sensorTrackList.isInitialized) {
            if (sensorTrackList.size >= 100){
                for (index in 0 until 50){
                    sensorTrackList.removeAt(index)
                }
            }
            sensorTrackList.add(trackSaId)
        }
    }

    /**
     * 尽量使用流的形式拿取请求体、响应体,避免连接被关闭
     */
    fun setNetLogsInfo(request: Request, response: Response){
        val requestBody = request.body
        var body: String? = null
        if (requestBody != null) {
            val buffer = Buffer()
            requestBody.writeTo(buffer)
            var charset: Charset? = UTF8
            val contentType = requestBody.contentType()
            if (contentType != null) {
                if (isNotFileRequest(contentType.subtype)) {
                    charset = contentType.charset(UTF8)
                    body = JsonFormaterUtil.format(buffer.readString(charset!!))
                } else {
                    body = OMITTED_REQUEST+contentType.subtype
                }
                //解决\n,\t,\r在html文本中不起作用的问题
                if (!TextUtils.isEmpty(body)) {
                    body = body?.replace("\n", "<br/>")
                    body = body?.replace("\t", "&nbsp")
                }
            }
        }
        val requestHtmlStr =
            "<b><font size=\"3\" color=\"#FF9200\">发送请求:</font></b> <br/> " +
                    "<font color=\"blue\">method: </font>${request.method} <br/> " +
                    "<font color=\"blue\">url: </font>${request.url} <br/> " +
                    "<font color=\"blue\">headers: </font>${request.headers} <br/> " +
                    "<font color=\"blue\">body: </font>${body ?: "requestBody is null"} <br/>"

        val responseBody = response.body
        var rBody: String? = null
        if (requestBody != null) {
            val source = responseBody?.source()
            source?.request(java.lang.Long.MAX_VALUE)
            val buffer = source?.buffer()
            var charset = UTF8
            val contentType = responseBody?.contentType()
            if (contentType != null) {
                if(isNotFileRequest(contentType.subtype)) {
                    try {
                        charset = contentType.charset(UTF8)
                    } catch (e: UnsupportedCharsetException) {
                        e.printStackTrace()
                    }
                    rBody = JsonFormaterUtil.format(buffer?.clone()?.readString(charset))
                } else {
                    rBody = OMITTED_RESPONSE+contentType.subtype
                }
                //解决\n,\t,\r在html文本中不起作用的问题
                if (!TextUtils.isEmpty(rBody)) {
                    rBody = rBody?.replace("\n", "<br/>")
                    rBody = rBody?.replace("\t", "&nbsp")
                }
            }

        }
        val responseHtmlStr =
            "<b><font size=\"3\" color=\"#FF9200\">收到响应:</font></b> <br/> " +
                    "<font color=\"blue\">status:</font>${response.code} " +
                    "<br/> <font color=\"blue\">body: </font>${rBody ?: "responseBody is null"}"
        if (this::netLogList.isInitialized) {
            if (netLogList.size >= 100){
                for (index in 0 until 50){
                    netLogList.removeAt(index)
                }
            }
            netLogList.add(requestHtmlStr + responseHtmlStr)
        }
    }

    /**
     * 判断是不是文件流类的传输
     * true(不是),false(是或者传输类型获取不到)
     */
    private fun isNotFileRequest(subtype: String?): Boolean {
        return subtype != null && (subtype.contains("json")
                || subtype.contains("xml")
                || subtype.contains("plain")
                || subtype.contains("html"))
    }

    fun getNetLogList(): MutableList<String> = netLogList

    fun getSensorTrackLogList(): MutableList<String> = sensorTrackList
}

NetWorkConsoleUtil就是收集以及格式化数据的帮助类,收集好后直接在需要展示的界面上展示,setNetLogsInfo(request: Request, response: Response)两个参数分别是在okhttp自定义拦截器中获取到请求体Request、响应体Response。

其中用到的JsonFormaterUtil类如下:

public class JsonFormaterUtil {
    public static String format(String jsonStr){
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(jsonStr.getBytes());
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            char ch;
            int read;
            int space=0;
            while((read = in.read()) > 0){
                ch = (char)read;
                switch (ch){
                    case '{': {
                        space = outputAndRightMove(space, ch, out);
                        break;
                    }
                    case '[': {
                        out.write(ch);
                        space += 2;
                        break;
                    }
                    case '}': {
                        space = outputAndLeftMove(space, ch, out);
                        break;
                    }
                    case ']': {
                        space = outputAndLeftMove(space, ch, out);
                        break;
                    }
                    case ',': {
                        out.write(ch);
                        outputNewline(out);
                        out.write(getBlankingStringBytes(space));
                        break;
                    }
                    default: {
                        out.write(ch);
                        break;
                    }
                }
            }
            return out.toString();
        } catch (IOException e){
            e.printStackTrace();
        }

        return null;
    }

    private static int outputAndRightMove(int space, char ch, ByteArrayOutputStream out) throws IOException {
        //换行
        outputNewline(out);
        //向右缩进
        out.write(getBlankingStringBytes(space));
        out.write(ch);
        outputNewline(out);
        space += 2;
        //再向右缩进多两个字符
        out.write(getBlankingStringBytes(space));
        return space;
    }
    private static int outputAndLeftMove(int space, char ch, ByteArrayOutputStream out) throws IOException{
        outputNewline(out);
        space -= 2;
        out.write(getBlankingStringBytes(space));
        out.write(ch);
        return space;
    }
    private static byte[] getBlankingStringBytes(int space){
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < space; i++) {
            sb.append("\t");
        }
        return sb.toString().getBytes();
    }

    private static void outputNewline(ByteArrayOutputStream out){
        out.write('\n');
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值