Frage

Ich habe ziemlich einfachen Httpclient 4-Code, den HttpGet ruft HTML-Ausgabe zu erhalten. Die HTML kehrt mit Skripten und Bildstellen alle lokalen eingestellt (zB <img src="/images/foo.jpg"/>), damit ich URL müssen Aufruf diese in absolute (<img src="http://foo.com/images/foo.jpg"/>) zu machen, kommt nun das Problem - während des Gesprächs es sein kann ein oder zwei 302 leitet so die ursprüngliche URL ist entspricht nicht mehr den Standort von HTML.

Wie kann ich die aktuelle URL der zurückgegebenen Inhalt bekommen gegeben alle Umleitungen ich kann (oder auch nicht) haben?

schaute ich auf HttpGet#getAllHeaders() und HttpResponse#getAllHeaders() - nichts finden konnte

.

Editiert: HttpGet#getURI() kehrt ursprüngliche Berufung Adresse

War es hilfreich?

Lösung

Das wäre die aktuelle URL sein, die Sie durch den Aufruf bekommen

  HttpGet#getURI();

EDIT: Du hast nicht erwähnt, wie Sie Umleitung tun. Das funktioniert für uns, weil wir die 302 selbst behandeln.

Klingt wie Sie DefaultRedirectHandler verwenden. Wir nutzten das zu tun. Es ist etwas schwierig die aktuelle URL zu erhalten. Sie müssen Ihren eigenen Kontext verwenden. Hier ist der entsprechende Code-Schnipsel,

        HttpGet httpget = new HttpGet(url);
        HttpContext context = new BasicHttpContext(); 
        HttpResponse response = httpClient.execute(httpget, context); 
        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
            throw new IOException(response.getStatusLine().toString());
        HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute( 
                ExecutionContext.HTTP_REQUEST);
        HttpHost currentHost = (HttpHost)  context.getAttribute( 
                ExecutionContext.HTTP_TARGET_HOST);
        String currentUrl = (currentReq.getURI().isAbsolute()) ? currentReq.getURI().toString() : (currentHost.toURI() + currentReq.getURI());

Die Standard-Umleitung nicht funktioniert hat für uns so änderten wir aber ich habe vergessen, was das Problem war.

Andere Tipps

In Httpclient 4, wenn Sie LaxRedirectStrategy oder jede Unterklasse von DefaultRedirectStrategy verwenden, dies ist die empfohlene Methode (Quellcode DefaultRedirectStrategy e):

HttpContext context = new BasicHttpContext();
HttpResult<T> result = client.execute(request, handler, context);
URI finalUrl = request.getURI();
RedirectLocations locations = (RedirectLocations) context.getAttribute(DefaultRedirectStrategy.REDIRECT_LOCATIONS);
if (locations != null) {
    finalUrl = locations.getAll().get(locations.getAll().size() - 1);
}

Da Httpclient 4.3.x kann der obige Code vereinfacht werden:

HttpClientContext context = HttpClientContext.create();
HttpResult<T> result = client.execute(request, handler, context);
URI finalUrl = request.getURI();
List<URI> locations = context.getRedirectLocations();
if (locations != null) {
    finalUrl = locations.get(locations.size() - 1);
}
    HttpGet httpGet = new HttpHead("<put your URL here>");
    HttpClient httpClient = HttpClients.createDefault();
    HttpClientContext context = HttpClientContext.create();
    httpClient.execute(httpGet, context);
    List<URI> redirectURIs = context.getRedirectLocations();
    if (redirectURIs != null && !redirectURIs.isEmpty()) {
        for (URI redirectURI : redirectURIs) {
            System.out.println("Redirect URI: " + redirectURI);
        }
        URI finalURI = redirectURIs.get(redirectURIs.size() - 1);
    }

Eine IMHO verbesserte Art und Weise auf der Basis ZZ Coder-Lösung ist eine ResponseInterceptor zu verwenden, um einfach die letzte Umleitung Ort zu verfolgen. Auf diese Weise verlieren Sie keine Informationen zum Beispiel nach einem Hashtag. Ohne die Antwort Abfangjäger verlieren Sie den Hashtag. Beispiel: http://j.mp/OxbI23

private static HttpClient createHttpClient() throws NoSuchAlgorithmException, KeyManagementException {
    SSLContext sslContext = SSLContext.getInstance("SSL");
    TrustManager[] trustAllCerts = new TrustManager[] { new TrustAllTrustManager() };
    sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

    SSLSocketFactory sslSocketFactory = new SSLSocketFactory(sslContext);
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("https", 443, sslSocketFactory));
    schemeRegistry.register(new Scheme("http", 80, new PlainSocketFactory()));

    HttpParams params = new BasicHttpParams();
    ClientConnectionManager cm = new org.apache.http.impl.conn.SingleClientConnManager(schemeRegistry);

    // some pages require a user agent
    AbstractHttpClient httpClient = new DefaultHttpClient(cm, params);
    HttpProtocolParams.setUserAgent(httpClient.getParams(), "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1");

    httpClient.setRedirectStrategy(new RedirectStrategy());

    httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
        @Override
        public void process(HttpResponse response, HttpContext context)
                throws HttpException, IOException {
            if (response.containsHeader("Location")) {
                Header[] locations = response.getHeaders("Location");
                if (locations.length > 0)
                    context.setAttribute(LAST_REDIRECT_URL, locations[0].getValue());
            }
        }
    });

    return httpClient;
}

private String getUrlAfterRedirects(HttpContext context) {
    String lastRedirectUrl = (String) context.getAttribute(LAST_REDIRECT_URL);
    if (lastRedirectUrl != null)
        return lastRedirectUrl;
    else {
        HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
        HttpHost currentHost = (HttpHost)  context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
        String currentUrl = (currentReq.getURI().isAbsolute()) ? currentReq.getURI().toString() : (currentHost.toURI() + currentReq.getURI());
        return currentUrl;
    }
}

public static final String LAST_REDIRECT_URL = "last_redirect_url";

verwenden Sie es wie ZZ Coder-Lösung:

HttpResponse response = httpClient.execute(httpGet, context);
String url = getUrlAfterRedirects(context);

Ich fand dies auf Httpcomponents-Client-Dokumentation

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet("http://localhost:8080/");
CloseableHttpResponse response = httpclient.execute(httpget, context);
try {
    HttpHost target = context.getTargetHost();
    List<URI> redirectLocations = context.getRedirectLocations();
    URI location = URIUtils.resolve(httpget.getURI(), target, redirectLocations);
    System.out.println("Final HTTP location: " + location.toASCIIString());
    // Expected to be an absolute URI
} finally {
    response.close();
}

Ich denke, einfache Art und Weise letzte URL zu finden ist DefaultRedirectHandler zu verwenden.

package ru.test.test;

import java.net.URI;

import org.apache.http.HttpResponse;
import org.apache.http.ProtocolException;
import org.apache.http.impl.client.DefaultRedirectHandler;
import org.apache.http.protocol.HttpContext;

public class MyRedirectHandler extends DefaultRedirectHandler {

    public URI lastRedirectedUri;

    @Override
    public boolean isRedirectRequested(HttpResponse response, HttpContext context) {

        return super.isRedirectRequested(response, context);
    }

    @Override
    public URI getLocationURI(HttpResponse response, HttpContext context)
            throws ProtocolException {

        lastRedirectedUri = super.getLocationURI(response, context);

        return lastRedirectedUri;
    }

}

-Code diese Prozedur zu verwenden:

  DefaultHttpClient httpclient = new DefaultHttpClient();
  MyRedirectHandler handler = new MyRedirectHandler();
  httpclient.setRedirectHandler(handler);

  HttpGet get = new HttpGet(url);

  HttpResponse response = httpclient.execute(get);

  HttpEntity entity = response.getEntity();
  lastUrl = url;
  if(handler.lastRedirectedUri != null){
      lastUrl = handler.lastRedirectedUri.toString();
  }

In der Version 2.3 Android noch nicht unterstützen folgende Umleitung (HTTP-Code 302). Ich habe gerade Location-Header lesen und herunterladen wieder:

if (statusCode != HttpStatus.SC_OK) {
    Header[] headers = response.getHeaders("Location");

    if (headers != null && headers.length != 0) {
        String newUrl = headers[headers.length - 1].getValue();
        // call again the same downloading method with new URL
        return downloadBitmap(newUrl);
    } else {
        return null;
    }
}

Kein Kreis umleitet Schutz hier so vorsichtig sein. Mehr auf von Blog 302 Folgen Umleitungen mit AndroidHttpClient

Dies ist, wie ich es geschafft, die Umleitungs-URL zu erhalten:

Header[] arr = httpResponse.getHeaders("Location");
for (Header head : arr){
    String whatever = arr.getValue();
}

Oder, wenn Sie sicher sind, dass es nur eine Umleitung Lage ist, dies zu tun:

httpResponse.getFirstHeader("Location").getValue();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top