如何在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




