Dodanie nagłówka dla HttpURLConnection

253

Próbuję dodać nagłówek dla mojego żądania przy użyciu, HttpUrlConnectionale metoda setRequestProperty()nie wydaje się działać. Strona serwera nie otrzymuje żadnych żądań z moim nagłówkiem.

HttpURLConnection hc;
    try {
        String authorization = "";
        URL address = new URL(url);
        hc = (HttpURLConnection) address.openConnection();


        hc.setDoOutput(true);
        hc.setDoInput(true);
        hc.setUseCaches(false);

        if (username != null && password != null) {
            authorization = username + ":" + password;
        }

        if (authorization != null) {
            byte[] encodedBytes;
            encodedBytes = Base64.encode(authorization.getBytes(), 0);
            authorization = "Basic " + encodedBytes;
            hc.setRequestProperty("Authorization", authorization);
        }
Minh-Ha Le
źródło
Działa dla mnie, jak powiedzieć, że nagłówek został wysłany i nie został odebrany?
Tomasz Nurkiewicz,
1
przepraszam, jeśli to brzmi głupio, ale gdzie dzwonisz connect()na URLConnection?
Vikdor
Nie jestem pewien, czy to działa, ale możesz spróbować dodać connection.setRequestMethod("GET");(lub POST lub cokolwiek chcesz)?
noobed
1
Inicjujesz authorizationpusty ciąg. Jeśli którykolwiek usernamelub passwordjest równy null, to authorizationbędzie pusty ciąg, a nie null. Dlatego finał ifzostanie wykonany, ale "Authorization"właściwość zostanie ustawiona jako pusta, wydaje mi się.
zerzevul

Odpowiedzi:

422

W przeszłości korzystałem z następującego kodu i działał on z podstawowym uwierzytelnianiem włączonym w TomCat:

URL myURL = new URL(serviceURL);
HttpURLConnection myURLConnection = (HttpURLConnection)myURL.openConnection();

String userCredentials = "username:password";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));

myURLConnection.setRequestProperty ("Authorization", basicAuth);
myURLConnection.setRequestMethod("POST");
myURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
myURLConnection.setRequestProperty("Content-Length", "" + postData.getBytes().length);
myURLConnection.setRequestProperty("Content-Language", "en-US");
myURLConnection.setUseCaches(false);
myURLConnection.setDoInput(true);
myURLConnection.setDoOutput(true);

Możesz wypróbować powyższy kod. Powyższy kod dotyczy POST i możesz go zmodyfikować, aby uzyskać GET

Cyril Beschi
źródło
15
Mały dodatek dla programistów Androida (na API> = 8 aka 2.2): android.util.Base64.encode (userCredentials.getBytes (), Base64.DEFAULT); Base64.DEFAULT nakazuje użycie RFC2045 do kodowania base64.
Denis Gladkiy
@Denis, czy mógłbyś mi powiedzieć, dlaczego należy używać nagłówków. Muszę zweryfikować niektóre dane uwierzytelniające z Androida. Używam php na Xammp. jak mam to zrobić. ponieważ nie wiem jak napisać kod php z nagłówkami
Pankaj Nimgade
11
Skąd wzięła się zmienna postDataw twoim przykładzie?
GlenPeterson
22
Dlaczego nazywają się „RequestProperty”, gdy wszyscy nazywają je Nagłówkami?
Philip Rego,
2
Jeden dodatek do wersji Java8: klasa Base64 jest nieco zmieniona. Dekodowanie powinno odbywać się przy użyciu:String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Mihailo Stupar
17

Po prostu dlatego, że nie widzę tego fragmentu informacji w powyższych odpowiedziach, powodem, dla którego pierwotnie opublikowany fragment kodu nie działa poprawnie, jest to, że encodedByteszmienna jest wartością byte[]a nie Stringwartością. Jeśli przekazać byte[]Do new String()jak poniżej fragment kodu działa doskonale.

encodedBytes = Base64.encode(authorization.getBytes(), 0);
authorization = "Basic " + new String(encodedBytes);
Joseph Cozad
źródło
11

Jeśli używasz Java 8, użyj poniższego kodu.

URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;

String basicAuth = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
httpConn.setRequestProperty ("Authorization", "Basic "+basicAuth);
Chandubabu
źródło
6

W końcu to zadziałało dla mnie

private String buildBasicAuthorizationString(String username, String password) {

    String credentials = username + ":" + password;
    return "Basic " + new String(Base64.encode(credentials.getBytes(), Base64.DEFAULT));
}
gori
źródło
2
@ d3dave. Łańcuch został utworzony z tablicy bajtów i połączony z „Basic”. Problem w kodzie OP polegał na tym, że połączył on „Basic” z bajtem [] i wysłał go jako nagłówek.
yurin
5

Twój kod jest w porządku. Możesz również użyć tego samego w ten sposób.

public static String getResponseFromJsonURL(String url) {
    String jsonResponse = null;
    if (CommonUtility.isNotEmpty(url)) {
        try {
            /************** For getting response from HTTP URL start ***************/
            URL object = new URL(url);

            HttpURLConnection connection = (HttpURLConnection) object
                    .openConnection();
            // int timeOut = connection.getReadTimeout();
            connection.setReadTimeout(60 * 1000);
            connection.setConnectTimeout(60 * 1000);
            String authorization="xyz:xyz$123";
            String encodedAuth="Basic "+Base64.encode(authorization.getBytes());
            connection.setRequestProperty("Authorization", encodedAuth);
            int responseCode = connection.getResponseCode();
            //String responseMsg = connection.getResponseMessage();

            if (responseCode == 200) {
                InputStream inputStr = connection.getInputStream();
                String encoding = connection.getContentEncoding() == null ? "UTF-8"
                        : connection.getContentEncoding();
                jsonResponse = IOUtils.toString(inputStr, encoding);
                /************** For getting response from HTTP URL end ***************/

            }
        } catch (Exception e) {
            e.printStackTrace();

        }
    }
    return jsonResponse;
}

Zwraca kod odpowiedzi 200, jeśli autoryzacja zakończy się powodzeniem

pintu
źródło
1

Z RestAssurd można również wykonać następujące czynności:

String path = baseApiUrl; //This is the base url of the API tested
    URL url = new URL(path);
    given(). //Rest Assured syntax 
            contentType("application/json"). //API content type
            given().header("headerName", "headerValue"). //Some API contains headers to run with the API 
            when().
            get(url).
            then().
            statusCode(200); //Assert that the response is 200 - OK
Eyal Sooliman
źródło
1
Czy możesz sformatować kod tutaj nieco bardziej czysto? A co given()ma być?
Nathaniel Ford
Cześć, To jest podstawowe użycie rest-Assurd (testowanie spoczynkowego interfejsu API). Dodałem wyjaśnienia do kodu.
Eyal Sooliman
-1

Krok 1: Uzyskaj obiekt HttpURLConnection

URL url = new URL(urlToConnect);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();

Krok 2: Dodaj nagłówki do HttpURLConnection przy użyciu metody setRequestProperty.

Map<String, String> headers = new HashMap<>();

headers.put("X-CSRF-Token", "fetch");
headers.put("content-type", "application/json");

for (String headerKey : headers.keySet()) {
    httpUrlConnection.setRequestProperty(headerKey, headers.get(headerKey));
}

Link referencyjny

Hari Krishna
źródło