Próbuję naśladować funkcjonalność tego polecenia curl w Javie:
curl --basic --user username:password -d "" http://ipaddress/test/login
Napisałem następujące rzeczy przy użyciu Commons HttpClient 3.0, ale w jakiś sposób otrzymałem 500 Internal Server Error
z serwera. Czy ktoś może mi powiedzieć, czy robię coś złego?
public class HttpBasicAuth {
private static final String ENCODING = "UTF-8";
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
HttpClient client = new HttpClient();
client.getState().setCredentials(
new AuthScope("ipaddress", 443, "realm"),
new UsernamePasswordCredentials("test1", "test1")
);
PostMethod post = new PostMethod(
"http://address/test/login");
post.setDoAuthentication( true );
try {
int status = client.executeMethod( post );
System.out.println(status + "\n" + post.getResponseBodyAsString());
} finally {
// release any connection resources used by the method
post.releaseConnection();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Później wypróbowałem Commons HttpClient 4.0.1, ale nadal ten sam błąd:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpBasicAuth {
private static final String ENCODING = "UTF-8";
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials("test1", "test1"));
HttpPost httppost = new HttpPost("http://host:post/test/login");
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response;
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
if (entity != null) {
entity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
java
http
apache-commons
Legenda
źródło
źródło
Odpowiedzi:
Czy próbowałeś tego (używając HttpClient w wersji 4):
źródło
java.util.Base64
od wersji Java 8:Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Ok, więc ten działa. Na wypadek, gdyby ktoś tego chciał, oto wersja, która działa dla mnie :)
źródło
Base64Encoder
. Jonas, czy możesz podać pełny słoik? Jaka jest w pełni kwalifikowana nazwa klasyBase64Encoder
?Base64Encoder
Spójrz tutaj . NaBase64
wygląd w świetlicy-codec-1.6.jar w 4.2.5.zip w Apache HttpComponents pobrania , doc ,import org.apache.commons.codec.binary.Base64;
String encoding = Base64.getEncoder().encodeToString("test1:test1".getBytes("utf-8"));
To jest kod z zaakceptowanej odpowiedzi powyżej, z pewnymi zmianami dotyczącymi kodowania Base64. Poniższy kod jest kompilowany.
źródło
Mała aktualizacja - mam nadzieję, że komuś przyda się - działa na mnie w moim projekcie:
Używam ładnej klasy Public Domain Base64.java od Roberta Hardera (Dzięki Robert - kod dostępny tutaj: Base64 - pobierz i umieść w swoim pakiecie).
i pobierz plik (obraz, dokument, itp.) z uwierzytelnieniem i zapisz na dysku lokalnym
Przykład:
źródło
The method encodeBytes(byte[]) is undefined for the type Base64
import org.apache.commons.codec.binary.Base64;
zgodnie z opisem w tej odpowiedzi na tej stronieOto kilka punktów:
Możesz rozważyć aktualizację do HttpClient 4 (ogólnie mówiąc, jeśli możesz, nie sądzę, aby wersja 3 była nadal aktywnie obsługiwana).
Kod statusu 500 to błąd serwera, więc warto zobaczyć, co mówi serwer (czy jest jakaś wskazówka w treści odpowiedzi, którą drukujesz?). Chociaż może to być spowodowane przez twojego klienta, serwer nie powinien zawieść w ten sposób (kod błędu 4xx byłby bardziej odpowiedni, gdyby żądanie było niepoprawne).
Myślę, że
setDoAuthentication(true)
jest to ustawienie domyślne (nie jestem pewien). Warto wypróbować uwierzytelnianie z wywłaszczaniem, które działa lepiej:W przeciwnym razie główna różnica między
curl -d ""
tym, co robisz w Javie, polega na tym, że oprócz tegoContent-Length: 0
, curl wysyłaContent-Type: application/x-www-form-urlencoded
. Zwróć uwagę, że jeśli chodzi o projekt, i tak powinieneś prawdopodobnie wysłać podmiot ze swoimPOST
żądaniem.źródło
Dzięki za wszystkie powyższe odpowiedzi, ale dla mnie nie mogę znaleźć klasy Base64Encoder, więc i tak sobie radzę.
Jeszcze jedno, też próbowałem
NIE działa, ponieważ zwraca ciąg prawie taki sam z
ale kończy się na „\ r \ n”, serwer zwróci „złe żądanie”.
Działa również poniższy kod, właściwie najpierw go rozwiązuję, ale z jakiegoś powodu NIE działa w niektórych środowiskach chmurowych (sae.sina.com.cn, jeśli chcesz wiedzieć, jest to chińska usługa w chmurze). więc musisz użyć nagłówka http zamiast poświadczeń HttpClient.
źródło
podczas korzystania z tablicy nagłówków
źródło
dla HttpClient zawsze używaj na przykład HttpRequestInterceptor
źródło
HttpBasicAuth działa dla mnie z mniejszymi zmianami
Używam zależności Mavena
Mniejsza zmiana
źródło
Łatwym sposobem logowania się za pomocą HTTP POST bez wykonywania jakichkolwiek wywołań związanych z Base64 jest użycie HTTPClient BasicCredentialsProvider
źródło