2

我正在编写一个 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 库?或者,如果您知道如何使用另一种方式来做到这一点..

欢迎任何帮助!

4

4 回答 4

6

你很近。您需要 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);
        }
    }
}
于 2015-05-22T18:40:25.587 回答
3

该文档非常粗略,但我认为您需要使用RequestBuilder以下Requestjavadoc 中显示的模式:

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

(显然,这个例子不是 Basic Auth,但有一些线索可以告诉你如何去做。)


FWIW,您当前代码的一个问题是 Basic Auth 标头使用 base64 编码而不是 URL 编码;有关详细信息,请参阅RFC2617

于 2013-06-29T15:05:33.857 回答
2

基本上,这样做: 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

于 2018-06-28T17:53:03.503 回答
0

这也是添加基本授权的另一种方式,您可以使用 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();

它可能对你有用

于 2014-07-18T13:55:12.387 回答