Java 解析 cURL(bash) 命令

1. 主要用于解析从浏览器复制来的 cURL(bash)

在这里插入图片描述

curl 'https://eva2.csdn.net/v3/06981375190026432f77c01bfca33e32/lts/groups/dadde766-b087-42da-8e67-d2499a520ee7/streams/a0119567-bf91-4314-ab75-f683ba6c0c0a/logs' \
  -H 'authority: eva2.csdn.net' \
  -H 'accept: */*' \
  -H 'accept-language: zh-CN,zh;q=0.9' \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'lts-sdk-request-id: 6c6b1e6bc1b5482fad39fd89e1be7e04' \
  -H 'lts-sdk-version: 1.0.15' \
  -H 'origin: https://so.csdn.net' \
  -H 'pragma: no-cache' \
  -H 'referer: https://so.csdn.net/so/search?q=java&t=blog&u=jx520' \
  -H 'sec-ch-ua: "Not-A.Brand";v="24", "Chromium";v="14"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "Windows"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-site' \
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36' \
  -H 'x-sdk-date: 20231014T001112Z' \
  --data-raw '{"labels":{},"logs":[{"contents":[{"pid":"so","ref":"https://blog.csdn.net/jx520/?type=blog","curl":"https://so.csdn.net/so/search?q=java&t=blog&u=jx520","spm":"1018.2226","disabled":"true","extra":"{\"x\":763,\"y\":72,\"ev\":\"move\"}","tos":3,"adb":0,"cCookie":"c_ins_um=-;c_ins_fref=-;c_ins_fpage=/;c_ins_prid=1695268703975_658854;c_ins_rid=1695735575959_588639;c_dl_prid=1696211031774_715058;c_dl_rid=1696416086259_366423;c_dl_fref=https://blog.csdn.net/m0_46365130/article/details/122106794;c_dl_fpage=/download/z18813048784/10697308;c_dl_um=-;c_utm_source=wwwtab;c_session_id=10_1697241559533.454757;c_segment=5;c_sid=1c05424b88433722b9b201b4d2024577;c_first_ref=default;c_utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-114031899-blog-109717731.235%5Ev38%5Epc_relevant_default_base;c_utm_relevant_index=2;c_pref=default;c_first_page=https%3A//blog.csdn.net/jx520/;c_dsid=11_1697242179555.095819;c_page_id=default;c_ref=https%3A//blog.csdn.net/jx520/%3Ftype%3Dblog;","t":1697242273,"screen":"1920*1080","urn":"1697242263003-f4828940-1336-41c0-8a4d-ba464f4a65e1","vType":"U010000","log_id":"56","sign":"7b1e61a11f5c4647a7f7fad1c85bdc70","userAgent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36","cid":"10_18489767550-1694529713132-118469","uid":"jx520","sid":"10_1697241559533.454757","dc_sid":"1c05424b88433722b9b201b4d2024577","did":"10_18489767550-1694529713132-118469","utm":"","un":"jx520","__client_time__":1697242272521}]}]}' \
  --compressed

2. 废话不多说,都在🍻代码里了。

CUrlUtil.java

package com.jerry.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;

/**
 * 解析 cURL(bash) 命令
 */
@Slf4j
public class CUrlUtil {
    /**
     * 解析 curl 命令
     *
     * @param curlCmd curl 命令
     * @return
     */
    public static CurlEntity parserCurl(String curlCmd) {
        String[] cmdParams;             // curl 命令按行切成的数组
        String url;                     // 请求地址
        Map<String, String> headers;    // 请求头 map
        String body;                    // 请求体

        // 把 curl 命令按行切成数组
        cmdParams = curlCmd.split("\n");

        // 取请求地址
        url = StrUtil.trimByChar(cmdParams[0], "'");
        // log.info("url = {}", url);

        // 将请求头、请求体分开
        Map<String, List<String>> headerAndBody = Stream.of(cmdParams)
                .collect(groupingBy((String str) -> str.trim().startsWith("-H") ? "header" : "body"));

        // 提取请求头 map
        headers = headerAndBody.get("header").stream()
                .map(str -> StrUtil.trimByChar(str, "'").split(": "))
                .collect(Collectors.toMap(strArr -> strArr[0], strArr -> strArr[1]));
        // headers.put("Content-Encoding","gzip"); // compress gzip 补上压缩参数。让服务器如果支持就返回压缩结果
        // log.info("headers = {}", headers);

        // 提取请求体
        body = headerAndBody.get("body").stream()
                .filter(str -> str.trim().startsWith("--data-raw"))
                .map(str -> StrUtil.trimByChar(str, "'", "' \\"))
                .collect(Collectors.joining());
        // log.info("body = {}", body);

        // 返回一个 curl 实体对象。包含:请求地址、请求头、请求体
        return new CurlEntity(url, headers, body);
    }

    @Data
    @AllArgsConstructor
    public static class CurlEntity {
        String url;                     // 请求地址
        Map<String, String> headers;    // 请求头 map
        String body;                    // 请求体
    }
}

StrUtil.java

这个用到了 hutool

package com.jerry.trafficassistant.utils;

import java.nio.charset.StandardCharsets;

public class StrUtil extends cn.hutool.core.util.StrUtil {
    /**
     * 将字符串切成三段
     * @param input 原字符串
     * @param start 切分一二段的字符(取它最后一个字符的索引位置,包含在第一段中)
     * @param end   切分二三段的字符(取它第一个字符的索引位置,包含在第二段中)
     * @return
     */
    public static String[] split3(String input, String start, String end) {
        if (cn.hutool.core.util.StrUtil.isBlank(input)  || cn.hutool.core.util.StrUtil.isBlank(start)  || cn.hutool.core.util.StrUtil.isBlank(end) ) {
            throw new IllegalArgumentException("Invalid input parameters");
        }

        int startIndex = input.indexOf(start) + start.length();
        int endIndex = input.lastIndexOf(end) + 1;

        String segment1 = input.substring(0, startIndex);
        String segment2 = input.substring(startIndex, endIndex);
        String segment3 = input.substring(endIndex);

        return new String[]{segment1, segment2, segment3};
    }

    /**
     * 从字符串 str 中截取 两个 ch 间的部分
     * @param str   原字符串
     * @param ch    两头的符号(不包含)
     * @return
     */
    public static String trimByChar(String str, String ch) {
        return trimByChar(str, ch, false);
    }
    /**
     * 从字符串 str 中截取 两个 ch 间的部分
     * @param str   原字符串
     * @param ch    两头的符号
     * @param include   是否包含头尾符号
     * @return
     */
    public static String trimByChar(String str, String ch, boolean include) {
        return trimByChar(str, ch, ch, include);
    }
    /**
     * 在字符串 str 中截取 start 和 end 间的部分
     * @param str   原字符串
     * @param start 开头的符号(不包含)
     * @param end   结尾的符号(不包含)
     * @return
     */
    public static String trimByChar(String str, String start, String end) {
        return trimByChar(str, start, end, false);
    }

    /**
     * 在字符串 str 中截取 start 和 end 间的部分
     * @param str       原字符串
     * @param start     开头的符号
     * @param end       结尾的符号
     * @param include   是否包含头尾符号
     * @return
     */
    public static String trimByChar(String str, String start, String end, boolean include) {
        return str.substring(str.indexOf(start) + ( include ? 0 : start.length() ) , str.lastIndexOf(end) + ( include ? end.length() : 0 ) );
    }

    /**
     * 字符串转乱码
     * @param str 源字符串
     * @return
     */
    public static String messyString(String str){
        return new String(str.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
    }

    public static void main(String[] args) {
        String str = "  --data-raw '{\"query\":\"地\",\"cookies\":\"\",\"longitude\":109.69811248779297,\"latitude\":28.262439727783203,\"timestamp\":\"1697098589374\",\"_log_finder_uin\":\"\",\"_log_finder_id\":\"v2_060000231003b20faec8c6e08a10c5ddcd03ec37b0779fd099cb7359364bc0bc23a807742754@finder\",\"rawKeyBuff\":null,\"pluginSessionId\":null,\"scene\":7,\"reqScene\":7}' \\\n" +
                "  --compressed";
        String[] strings = split3(str, "--data-raw '", "}");
        for (int i = 0; i < strings.length; i++) {
            System.out.println("行:" + strings[i]);
        }
    }
}

参考资料

curl 命令在线执行
在线:curl 命令转成其他语言

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值