首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HTTP Builder/Groovy -丢失302 (重定向)处理?

HTTP Builder/Groovy -丢失302 (重定向)处理?
EN

Stack Overflow用户
提问于 2010-06-04 23:24:43
回答 3查看 6.2K关注 0票数 6

我在这里读到http://groovy.codehaus.org/modules/http-builder/doc/handlers.html“在响应发送重定向状态代码的情况下,这是由Apache HttpClient内部处理的,默认情况下,Apache会简单地通过将请求重新发送到新的URL来跟踪重定向。你不需要做任何特殊的事情来跟踪302响应。”

当我简单地使用get()或post()方法而不使用闭包时,这似乎工作得很好。

然而,当我使用闭包时,我似乎失去了302的处理能力。有没有什么办法让我自己处理?谢谢

附注:下面是我的日志输出,显示它是一个302响应

代码语言:javascript
运行
复制
 [java] FINER: resp.statusLine: "HTTP/1.1 302 Found"

相关代码如下:

代码语言:javascript
运行
复制
// Copyright (C) 2010 Misha Koshelev. All Rights Reserved.
package com.mksoft.fbbday.main

import groovyx.net.http.ContentType

import java.util.logging.Level
import java.util.logging.Logger

class HTTPBuilder {
  def dataDirectory
  HTTPBuilder(dataDirectory) {
    this.dataDirectory=dataDirectory
  }

  // Main logic
  def logger=Logger.getLogger(this.class.name)
  def closure={resp,reader->
    logger.finer("resp.statusLine: \"${resp.statusLine}\"")
    if (logger.isLoggable(Level.FINEST)) {
      def respHeadersString='Headers:';
      resp.headers.each() { header->respHeadersString+="\n\t${header.name}=\"${header.value}\"" }
      logger.finest(respHeadersString)
    }

    def text=reader.text
    def lastHtml=new File("${dataDirectory}${File.separator}last.html")
    if (lastHtml.exists()) {
      lastHtml.delete()
    }
    lastHtml<<text
    new XmlSlurper(new org.cyberneko.html.parsers.SAXParser()).parseText(text)          
  }
  def processArgs(args) {
    if (logger.isLoggable(Level.FINER)) {
      def argsString='Args:';
      args.each() { arg->argsString+="\n\t${arg.key}=\"${arg.value}\"" }
      logger.finer(argsString)
    }
    args.contentType=groovyx.net.http.ContentType.TEXT
    args
  }

  // HTTPBuilder methods
  def httpBuilder=new groovyx.net.http.HTTPBuilder ()
  def get(args) {
    httpBuilder.get(processArgs(args),closure)
  }
  def post(args) {
    args.contentType=groovyx.net.http.ContentType.TEXT
    httpBuilder.post(processArgs(args),closure) 
  }
}

下面是一个特定的测试器:

代码语言:javascript
运行
复制
#!/usr/bin/env groovy

import groovyx.net.http.HTTPBuilder
import groovyx.net.http.Method
import static groovyx.net.http.ContentType.URLENC

import java.util.logging.ConsoleHandler
import java.util.logging.Level
import java.util.logging.Logger

// MUST ENTER VALID FACEBOOK EMAIL AND PASSWORD BELOW !!!
def email=''
def pass=''

// Remove default loggers
def logger=Logger.getLogger('')
def handlers=logger.handlers
handlers.each() { handler->logger.removeHandler(handler) }

// Log ALL to Console
logger.setLevel Level.ALL
def consoleHandler=new ConsoleHandler()
consoleHandler.setLevel Level.ALL
logger.addHandler(consoleHandler)

// Facebook - need to get main page to capture cookies
def http = new HTTPBuilder()
http.get(uri:'http://www.facebook.com')

// Login
def html=http.post(uri:'https://login.facebook.com/login.php?login_attempt=1',body:[email:email,pass:pass])
assert html==null

// Why null?
html=http.post(uri:'https://login.facebook.com/login.php?login_attempt=1',body:[email:email,pass:pass]) { resp,reader->
  assert resp.statusLine.statusCode==302

  // Shouldn't we be redirected???
  // http://groovy.codehaus.org/modules/http-builder/doc/handlers.html
  // "In cases where a response sends a redirect status code, this is handled internally by Apache HttpClient, which by default will simply follow the redirect by re-sending the request to the new URL. You do not need to do anything special in order to follow 302 responses. "
}

相关日志如下:

代码语言:javascript
运行
复制
FINE: Receiving response: HTTP/1.1 302 Found
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << HTTP/1.1 302 Found
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Expires: Sat, 01 Jan 2000 00:00:00 GMT
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Location: http://www.facebook.com/home.php?
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << P3P: CP="DSP LAW"
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Pragma: no-cache
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Set-Cookie: datr=1275687438-9ff6ae60a89d444d0fd9917abf56e085d370277a6e9ed50c1ba79; expires=Sun, 03-Jun-2012 21:37:24 GMT; path=/; domain=.facebook.com
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Set-Cookie: lxe=koshelev%40post.harvard.edu; expires=Tue, 28-Sep-2010 15:24:04 GMT; path=/; domain=.facebook.com; httponly
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Set-Cookie: lxr=deleted; expires=Thu, 04-Jun-2009 21:37:23 GMT; path=/; domain=.facebook.com; httponly
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Set-Cookie: pk=183883c0a9afab1608e95d59164cc7dd; path=/; domain=.facebook.com; httponly
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Content-Type: text/html; charset=utf-8
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << X-Cnection: close
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Date: Fri, 04 Jun 2010 21:37:24 GMT
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.DefaultClientConnection receiveResponseHeader
FINE: << Content-Length: 0
Jun 4, 2010 4:37:22 PM org.apache.http.client.protocol.ResponseProcessCookies processCookies
FINE: Cookie accepted: "[version: 0][name: datr][value: 1275687438-9ff6ae60a89d444d0fd9917abf56e085d370277a6e9ed50c1ba79][domain: .facebook.com][path: /][expiry: Sun Jun 03 16:37:24 CDT 2012]". 
Jun 4, 2010 4:37:22 PM org.apache.http.client.protocol.ResponseProcessCookies processCookies
FINE: Cookie accepted: "[version: 0][name: lxe][value: koshelev%40post.harvard.edu][domain: .facebook.com][path: /][expiry: Tue Sep 28 10:24:04 CDT 2010]". 
Jun 4, 2010 4:37:22 PM org.apache.http.client.protocol.ResponseProcessCookies processCookies
FINE: Cookie accepted: "[version: 0][name: lxr][value: deleted][domain: .facebook.com][path: /][expiry: Thu Jun 04 16:37:23 CDT 2009]". 
Jun 4, 2010 4:37:22 PM org.apache.http.client.protocol.ResponseProcessCookies processCookies
FINE: Cookie accepted: "[version: 0][name: pk][value: 183883c0a9afab1608e95d59164cc7dd][domain: .facebook.com][path: /][expiry: null]". 
Jun 4, 2010 4:37:22 PM org.apache.http.impl.client.DefaultRequestDirector execute
FINE: Connection can be kept alive indefinitely
Jun 4, 2010 4:37:22 PM groovyx.net.http.HTTPBuilder doRequest
FINE: Response code: 302; found handler: post302$_run_closure2@7023d08b
Jun 4, 2010 4:37:22 PM groovyx.net.http.HTTPBuilder doRequest
FINEST: response handler result: null
Jun 4, 2010 4:37:22 PM org.apache.http.impl.conn.SingleClientConnManager releaseConnection
FINE: Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@605b28c9

你可以清楚地看到这里有一个位置参数。

谢谢你,米莎

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-16 16:48:28

在我意识到the HTTP/1.1 spec states:之前,我也遇到过同样的HTTPBuilder问题

重定向3xx

。。这类状态代码指示需要执行进一步的操作

由用户代理采取,以满足请求。动作

当且仅当在第二请求中使用的方法是GET或HEAD时,用户代理可以在不与用户交互的情况下执行请求。

找到302个

。。如果接收到302状态代码以响应GET或HEAD以外的请求,则用户代理不能自动重定向请求,除非用户可以确认它,因为这可能会改变发出请求的条件。

本质上,这意味着POST和302重定向之后的请求不会自动工作,如果HTTP/1.1规范后面跟着字母,则需要用户干预。并不是所有的Http客户端都遵循这种做法,事实上大多数浏览器都不遵循这种做法。但是,Apache Http客户端(这是HttpBuilder的底层Http客户端) is spec compliant。有一个issue in the Apache Http Client bugtracker,其中包含更多信息和问题的可能解决方案。

票数 11
EN

Stack Overflow用户

发布于 2016-09-21 19:14:53

代码语言:javascript
运行
复制
void test_myPage_shouldRedirectToLogin() {
  def baseURI = "http://servername"
  def httpBuilder = new HTTPBuilder(baseURI)
  // Make sure that HttpClient doesn't perform a redirect
  def dontHandleRedirectStrategy = [
    getRedirect : { request, response, context -> null},
    isRedirected : { request, response, context -> false}
  ]
  httpBuilder.client.setRedirectStrategy(dontHandleRedirectStrategy as RedirectStrategy)

  // Execute a GET request and expect a redirect
  httpBuilder.request(Method.GET, ContentType.TEXT) {
    req ->
      uri.path = '/webapp/de/de/myPage'
      response.success = { response, reader ->
        assertThat response.statusLine.statusCode, is(302)
        assertThat response.headers['Location'].value, startsWith("${baseURI}/webapp/login")
      }
      response.failure = { response, reader ->
        fail("Expected redirect but received ${response.statusLine} \n ${reader}")
      }
    }
  }

302状态即将到来,因为在任何链接上执行操作后,重定向的"RedirectStrategy"不会跟在HttpBuilder后面,所以我们需要显式地添加url。

票数 1
EN

Stack Overflow用户

发布于 2010-06-05 03:00:39

在处理302响应时,您还会看到哪些其他报头?如果你打开了http client logging,你会期望看到HttpClient处理302响应,并自动请求Location头中的URL。当您处理该URL时,您看到了什么?它对任何URL都有效吗?

试试http://www.sun.com (它现在会重定向到Oracle )。我只是想知道你正在使用的服务器是否正在做一些不稳定的事情,比如发送一个没有Location报头的302。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2975515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档