You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Groovy中解析含302重定向的curl POST请求响应头?

在Groovy中解析curl命令的302重定向响应以获取响应头

我来帮你搞定这个问题!当curl触发302重定向时,默认会自动跟随跳转,导致你看不到原始的302响应头。所以首先得调整curl的参数,让它输出完整的响应信息,之后再用Groovy解析;另外,其实直接用Groovy自带的HTTP客户端处理会更优雅,不用依赖外部的curl命令,我给你两种可行方案:

方案一:curl命令配合Groovy解析

第一步:调整curl参数捕获302响应头

要拿到302的响应头,你需要告诉curl不要自动跟随重定向,并且输出响应头。可以用以下curl命令:

curl -X POST --include --max-redirs 0 "http://你的目标URL"
  • --include:让curl输出响应头和响应内容
  • --max-redirs 0:禁止curl跟随任何重定向,这样就能拿到原始的302响应

第二步:Groovy中执行curl并解析响应

在Groovy里,你可以通过执行curl命令捕获输出,然后拆分并解析响应头:

def targetUrl = "http://你的目标URL"
// 构造curl命令数组(避免字符串转义问题)
def curlCmd = ["curl", "-X", "POST", "--include", "--max-redirs", "0", targetUrl]

// 执行命令并等待完成
def process = curlCmd.execute()
process.waitFor()

// 获取命令输出和错误信息
def output = process.inputStream.text
def errorMsg = process.errorStream.text

// 检查命令是否执行成功
if (process.exitValue() != 0) {
    println "curl命令执行出错: ${errorMsg}"
    return
}

// 解析响应头:头和内容之间用空行分隔,先取空行之前的部分
def headerLines = output.split('\n').takeWhile { it.trim() != '' }
def headers = [:]

headerLines.each { line ->
    if (line.startsWith('HTTP/')) {
        // 处理状态行(比如HTTP/1.1 302 Found)
        headers['status'] = line.trim()
    } else {
        // 拆分键值对,只分一次(避免值里有冒号的情况)
        def parts = line.split(':', 2)
        if (parts.size() == 2) {
            def key = parts[0].trim()
            def value = parts[1].trim()
            headers[key] = value
        }
    }
}

// 打印结果示例
println "302状态行: ${headers['status']}"
println "重定向地址(Location头): ${headers['Location']}"
println "所有响应头: ${headers}"

方案二:直接用Groovy HTTP客户端(更推荐)

依赖外部curl命令容易遇到环境兼容问题,用Groovy自带的HTTP工具类会更可靠。这里给你两种实现方式:

方式1:原生HttpURLConnection(无额外依赖)

def targetUrl = new URL("http://你的目标URL")
def connection = targetUrl.openConnection() as HttpURLConnection

// 关键配置:禁止自动跟随重定向
connection.instanceFollowRedirects = false
connection.requestMethod = "POST"

try {
    connection.connect()
    
    // 输出状态和响应头
    println "响应状态: ${connection.responseCode} ${connection.responseMessage}"
    println "Location头: ${connection.getHeaderField('Location')}"
    println "所有响应头:"
    connection.headerFields.each { key, values ->
        if (key != null) { // 跳过状态行对应的null键
            println "${key}: ${values.join(', ')}"
        }
    }
} finally {
    // 记得关闭连接
    connection.disconnect()
}

方式2:用HTTPBuilder(更简洁,需要依赖)

HTTPBuilder是Groovy生态中常用的HTTP客户端库,代码更简洁:

// 自动拉取依赖
@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7.2')
import groovyx.net.http.RESTClient

def client = new RESTClient("http://你的目标URL")
// 禁止跟随重定向
client.followRedirects = false

// 处理302 Found响应
client.handler.found = { resp, data ->
    println "响应状态码: ${resp.status}"
    println "Location头: ${resp.headers.Location}"
    println "所有响应头:"
    resp.headers.each { header ->
        println "${header.name}: ${header.value}"
    }
    return resp
}

try {
    // 发起POST请求
    client.post()
} catch (Exception e) {
    println "请求出错: ${e.message}"
}

关键注意点

不管用哪种方案,必须禁用自动跟随重定向,否则你拿到的会是重定向后的目标页面的响应头,而不是原始的302响应头。

内容的提问来源于stack exchange,提问作者PingPong

火山引擎 最新活动