【问题标题】:Get URL content with Basic Authentication with Java and async-http-client通过 Java 和 async-http-client 的基本身份验证获取 URL 内容
【发布时间】:2013-06-27 04:08:56
【问题描述】:

我正在编写一个 Java 库,需要执行一个对 URL 的请求——目前使用来自 ning 的async-http-client——并获取它的内容。所以我有一个返回字符串的get 方法 获取的文档的内容。但是,为了能够获得它,我必须执行 HTTP 基本身份验证,而我在 Java 代码中没有成功:

public String get(String token) throws IOException {
    String fetchURL = "https://www.eventick.com.br/api/v1/events/492";

    try {
        String encoded = URLEncoder.encode(token + ":", "UTF-8");
        return this.asyncClient.prepareGet(fetchURL)
        .addHeader("Authorization", "Basic " + encoded).execute().get().getResponseBody();
    }
}

代码没有返回错误,只是没有获取 URL,因为身份验证标头未正确设置,不知何故。

使用 curl -u 选项我可以轻松获得我想要的:

curl https://www.eventick.com.br/api/v1/events/492 -u 'xxxxxxxxxxxxxxx:'

返回:

{"events":[{"id":492,"title":"Festa da Bagaceira","venue":"Mangueirão de Paulista",
"slug":"bagaceira-fest", "start_at":"2012-07-29T16:00:00-03:00",
"links":{"tickets":[{"id":738,"name":"Normal"}]}}]}

如何在 Java 中做到这一点?使用 async-http-client 库?或者,如果您知道如何使用另一种方式来做到这一点..

欢迎任何帮助!

【问题讨论】:

    标签: java asynchttpclient


    【解决方案1】:

    你已经接近了。您需要 base 64 编码而不是 URL 编码。也就是说,你需要

    String encoded = Base64.getEncoder().encodeToString((user + ':' + password).getBytes(StandardCharsets.UTF_8));
    

    而不是

    String encoded = URLEncoder.encode(token + ":", "UTF-8");
    

    (请注意,为了他人的利益,由于我是在 2 年后回答的,所以在我的回答中,我使用的是更标准的 "user:password",而您的问题是 "token:"。如果您需要的是 "token:" ,然后坚持下去。但也许这也是问题的一部分?)

    这是一个简短的、独立的、正确的例子

    package so17380731;
    
    import com.ning.http.client.AsyncHttpClient;
    import java.nio.charset.StandardCharsets;
    import java.util.Base64;
    import javax.ws.rs.core.HttpHeaders;
    
    public class BasicAuth {
    
        public static void main(String... args) throws Exception {
            try(AsyncHttpClient asyncClient = new AsyncHttpClient()) {
                final String user = "StackOverflow";
                final String password = "17380731";
                final String fetchURL = "https://www.eventick.com.br/api/v1/events/492";
                final String encoded = Base64.getEncoder().encodeToString((user + ':' + password).getBytes(StandardCharsets.UTF_8));
                final String body = asyncClient
                    .prepareGet(fetchURL)
                    .addHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded)
                    .execute()
                    .get()
                    .getResponseBody(StandardCharsets.UTF_8.name());
                System.out.println(body);
            }
        }
    }
    

    【讨论】:

    • 而且,说到 2 年后,最初的问题是在我 40 岁生日时提出的。啊。时光飞逝
    • 非常感谢!我花了 3 个小时尝试大概 20 种不同的解决方案。它不仅工作正常,而且比我发现的任何其他东西都简单得多。谢谢!
    【解决方案2】:

    文档非常粗略,但我认为您需要按照Request javadoc 中显示的模式使用RequestBuilder

    Request r = new RequestBuilder().setUrl("url")
        .setRealm((new Realm.RealmBuilder()).setPrincipal(user)
        .setPassword(admin)
        .setRealmName("MyRealm")
        .setScheme(Realm.AuthScheme.DIGEST).build());
    r.execute();
    

    (显然,此示例不是基本身份验证,但有一些线索可以告诉您如何操作。)


    FWIW,您当前代码的一个问题是 Basic Auth 标头使用 base64 编码而不是 URL 编码;详情请见RFC2617

    【讨论】:

      【解决方案3】:

      基本上,这样做: BoundRequestBuilder request = asyncHttpClient .preparePost(getUrl()) .setHeader("Accept", "application/json") .setHeader("Content-Type", "application/json") .setRealm(org.asynchttpclient.Dsl.basicAuthRealm(getUser(), getPassword())) // ^^^^^^^^^^^-- this is the important part .setBody(json);

      测试可以在这里找到: https://github.com/AsyncHttpClient/async-http-client/blob/master/client/src/test/java/org/asynchttpclient/BasicAuthTest.java

      【讨论】:

        【解决方案4】:

        这也是另一种添加基本授权的方式, 您可以使用 AsyncHttpClient、HttpClient 两个类中的任何一个,在这种情况下,我将使用 AsyncHttpClient

        AsyncHttpClient client=new AsyncHttpClient();           
                Request request = client.prepareGet("https://www.eventick.com.br/api/v1/events/492").
                    setHeader("Content-Type","application/json")
                    .setHeader("Authorization","Basic b2pAbml1LXR2LmNvbTpnMGFRNzVDUnhzQ0ZleFQ=")
                    .setBody(jsonObjectRepresentation.toString()).build();
        

        添加标题部分后

                    ListenableFuture<Response> r = null;
                    //ListenableFuture<Integer> f= null;
                    try{
                    r = client.executeRequest(request);
                    System.out.println(r.get().getResponseBody());
                    }catch(IOException e){
        
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                    client.close();
        

        可能对你有用

        【讨论】:

        猜你喜欢
        • 2013-11-09
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        • 2011-11-08
        • 2018-01-02
        相关资源
        最近更新 更多