curl打印信息实现
flutter使用dio库打印信息
///打印curl的拦截器
class CurlInterceptor extends Interceptor {@overridevoid onRequest(RequestOptions options, RequestInterceptorHandler handler) {_printCurlCommand(options);handler.next(options);}void _printCurlCommand(RequestOptions options) {final buffer = StringBuffer('curl -X ${options.method.toUpperCase()}');buffer.write(' \'${options.uri.toString()}\'');// 1. 处理请求头(过滤冗余Header)options.headers.forEach((key, value) {if (key != Headers.contentLengthHeader &&key != Headers.contentTypeHeader) {buffer.write(' -H \'$key: $value\'');}});// 2. 核心修改:识别FormData并转换为URL编码格式if (options.data != null) {if (options.data is dio_src.FormData) {final formData = options.data as dio_src.FormData;buffer.write(' -d \'${_encodeFormData(formData)}\''); // 调用编码方法} else if (options.data is Map) {// 非FormData类型buffer.write(' -d ${convertToFormData(options.data.toString())}');} else if (options.data is String) {buffer.write(' -d \'${options.data}\'');}}Log.instance.i('╔════════ cURL Command ════════');Log.instance.i(buffer.toString());Log.instance.i('╚══════════════════════════════');}// 3. 新增方法:将FormData转换为URL编码字符串String _encodeFormData(dio_src.FormData formData) {final params = <String>[];// 处理普通字段(键值对)for (var field in formData.fields) {final encodedKey = Uri.encodeComponent(field.key);final encodedValue = Uri.encodeComponent(field.value);params.add('$encodedKey=$encodedValue'); // 格式: key=value}// 处理文件字段(保留兼容性)for (var file in formData.files) {final encodedKey = Uri.encodeComponent(file.key);params.add('$encodedKey=@${file.value.filename}');}return params.join('&'); // 拼接为 key1=value1&key2=value2}String convertToFormData(String data) {// 1. 去除首尾的大括号String content = data.substring(1, data.length - 1);// 2. 按逗号分割成键值对列表List<String> keyValuePairs = content.split(',');// 3. 处理每个键值对List<String> processedPairs = [];for (String pair in keyValuePairs) {// 去除空格String trimmedPair = pair.trim();// 按冒号分割键和值(处理可能包含冒号的值)List<String> parts = trimmedPair.split(':');if (parts.length < 2) continue; // 跳过无效格式String key = parts[0].trim();// 拼接可能被分割的value部分String value = parts.sublist(1).join(':').trim();// 4. 对值进行URL编码(处理@等特殊字符)String encodedValue = Uri.encodeComponent(value);processedPairs.add('$key=$encodedValue');}// 5. 用&连接所有键值对return processedPairs.join('&');}
}添加拦截器dio.interceptors.add(CurlInterceptor());
安卓原生使用okhttp
import okhttp3.*
import okio.Bufferclass CurlInterceptor : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {val request = chain.request()val curl = StringBuilder("curl -X ${request.method()} \"${request.url()}\"")// 修复:通过Headers的索引方法遍历,避免直接调用forEachval headers = request.headers()for (i in 0 until headers.size()) {val name = headers.name(i)val value = headers.value(i)// 过滤敏感Headerif (name.lowercase() !in setOf("authorization", "cookie", "set-cookie")) {curl.append(" -H \"$name: $value\"")}}// 处理请求Bodyrequest.body()?.let { body ->runCatching {val buffer = Buffer()body.writeTo(buffer)val bodyStr = buffer.readUtf8().replace("\"", "\\\"")if (bodyStr.isNotEmpty()) {curl.append(" -d \"$bodyStr\"")}}.onFailure {curl.append(" -d [二进制数据]")}}println("------- Curl请求: $curl")return chain.proceed(request)}
}
添加拦截器
OkHttpClientFactory.getBuilder()// 添加CurlInterceptor(关键步骤).addInterceptor(CurlInterceptor()).build()