Jak wysłać żądanie PUT, DELETE HTTP w HttpURLConnection?

133

Chcę wiedzieć, czy możliwe jest wysłanie żądania PUT, DELETE (praktycznie) przez java.net.HttpURLConnectionadres URL oparty na HTTP.

Przeczytałem tak wiele artykułów opisujących, jak wysyłać żądania GET, POST, TRACE, OPTIONS, ale nadal nie znalazłem żadnego przykładowego kodu, który pomyślnie wykonuje żądania PUT i DELETE.

Matryca
źródło
2
Czy możesz pokazać nam kod, którego próbowałeś użyć?
akarnokd

Odpowiedzi:

179

Aby wykonać HTTP PUT:

URL url = new URL("http://www.example.com/resource");
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(
    httpCon.getOutputStream());
out.write("Resource content");
out.close();
httpCon.getInputStream();

Aby wykonać HTTP DELETE:

URL url = new URL("http://www.example.com/resource");
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestProperty(
    "Content-Type", "application/x-www-form-urlencoded" );
httpCon.setRequestMethod("DELETE");
httpCon.connect();
Matthew Murdoch
źródło
1
Tak. Wszystkie te rzeczy są możliwe, ale tak naprawdę zależą od API obsługiwanego przez dostawcę poczty / bloga.
Matthew Murdoch
5
witam mam problemy z delete. Kiedy uruchamiam ten kod tak, jak jest tutaj, tak naprawdę nic się nie dzieje, żądanie nie jest wysyłane. Taka sama sytuacja jest, gdy wykonuję postżądania, ale mogę użyć na przykład tego, httpCon.getContent()który wyzwala żądanie. Ale to httpCon.connect()nic nie uruchamia w mojej maszynie :-)
coubeatczech
7
W powyższych przykładach uważam, że będziesz musiał wywołać httpCon.getInputStream () na końcu, aby żądanie zostało faktycznie wysłane.
Eric Smith
3
Otrzymałem „java.net.ProtocolException: DELETE nie obsługuje pisania”
Kimo_do
1
@edisusanto nazwany zasób (wskazany przez adres URL) to dane, które zostaną usunięte.
Matthew Murdoch,
24

Tak to działało u mnie:

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("DELETE");
int responseCode = connection.getResponseCode();
Eli Heifetz
źródło
12
public  HttpURLConnection getHttpConnection(String url, String type){
        URL uri = null;
        HttpURLConnection con = null;
        try{
            uri = new URL(url);
            con = (HttpURLConnection) uri.openConnection();
            con.setRequestMethod(type); //type: POST, PUT, DELETE, GET
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setConnectTimeout(60000); //60 secs
            con.setReadTimeout(60000); //60 secs
            con.setRequestProperty("Accept-Encoding", "Your Encoding");
            con.setRequestProperty("Content-Type", "Your Encoding");
        }catch(Exception e){
            logger.info( "connection i/o failed" );
        }
        return con;
}

Następnie w swoim kodzie:

public void yourmethod(String url, String type, String reqbody){
    HttpURLConnection con = null;
    String result = null;
    try {
        con = conUtil.getHttpConnection( url , type);
    //you can add any request body here if you want to post
         if( reqbody != null){  
                con.setDoInput(true);
                con.setDoOutput(true);
                DataOutputStream out = new  DataOutputStream(con.getOutputStream());
                out.writeBytes(reqbody);
                out.flush();
                out.close();
            }
        con.connect();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String temp = null;
        StringBuilder sb = new StringBuilder();
        while((temp = in.readLine()) != null){
            sb.append(temp).append(" ");
        }
        result = sb.toString();
        in.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        logger.error(e.getMessage());
    }
//result is the response you get from the remote side
}
Benjamin Twilight
źródło
Uzyskiwanie wyjątku „java.io.IOException: nieobsługiwana metoda: put” inJ2me sdk logger
CodeToLife
9

Zgadzam się z @adietisheim i resztą osób, które sugerują HttpClient.

Spędziłem czas próbując wykonać proste połączenie z usługą odpoczynku za pomocą HttpURLConnection i nie przekonało mnie to, a potem próbowałem z HttpClient i było to naprawdę łatwiejsze, zrozumiałe i przyjemne.

Przykład kodu do wykonania wywołania put http jest następujący:

DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPut putRequest = new HttpPut(URI);

StringEntity input = new StringEntity(XML);
input.setContentType(CONTENT_TYPE);

putRequest.setEntity(input);
HttpResponse response = httpClient.execute(putRequest);
Alvaro
źródło
Chciałem tylko podziękować za to. Spędził wiele godzin próbując dostać mój kod używając HttpURLConnectiondo pracy, ale biegł do nieparzystej błędów, w szczególności: cannot retry due to server authentication, in streaming mode. Postępowanie zgodnie z twoją radą zadziałało dla mnie. Zdaję sobie sprawę, że to nie do końca odpowiada na pytanie, które prosi o użycie HttpURLConnection, ale Twoja odpowiedź mi pomogła.
Tom Catullo
@Deprecated zamiast tego użyj HttpClientBuilder
Waldemar Wosiński
3

UrlConnection to niezręczny interfejs API do pracy. HttpClient jest zdecydowanie lepszym interfejsem API i pozwoli ci zaoszczędzić czas na szukaniu sposobów osiągnięcia pewnych rzeczy, takich jak to pytanie o przepływie stosu, które doskonale ilustruje. Piszę to po użyciu jdk HttpUrlConnection w kilku klientach REST. Ponadto, jeśli chodzi o funkcje skalowalności (takie jak pule wątków, pule połączeń itp.) HttpClient jest lepszy

adietisheim
źródło
3

Aby poprawnie wykonać PUT w HTML, musisz otoczyć go try / catch:

try {
    url = new URL("http://www.example.com/resource");
    HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
    httpCon.setDoOutput(true);
    httpCon.setRequestMethod("PUT");
    OutputStreamWriter out = new OutputStreamWriter(
        httpCon.getOutputStream());
    out.write("Resource content");
    out.close();
    httpCon.getInputStream();
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (ProtocolException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
Carlos Sirvent
źródło
1

Nawet szablon odpoczynku może być opcją:

String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?<RequestDAO>....";
    RestTemplate rest = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/xml");
    headers.add("Accept", "*/*");
    HttpEntity<String> requestEntity = new HttpEntity<String>(payload, headers);
    ResponseEntity<String> responseEntity =
            rest.exchange(url, HttpMethod.PUT, requestEntity, String.class);

     responseEntity.getBody().toString();
Gloria Rampur
źródło
To jedna z najlepszych odpowiedzi, jakie widziałem w SO.
thonnor
0

istnieje prosty sposób na usunięcie i umieszczenie żądania, możesz to po prostu zrobić, dodając _methodparametr " " do żądania wiadomości i wpisując " PUT" lub " DELETE" dla jego wartości!

Mohamad Rostami
źródło
-1

Poleciłbym Apache HTTPClient.

Clint
źródło
9
Dlaczego miałbyś polecać HTTPClient? To jest ogromne. Mam na myśli - rozmiar.
jayarjo
1
@jayarjo, jest częścią zestawu Android SDK.
Zamel
9
@Zamel: Gdzie dokładnie Android pojawia się na obrazku?
talonx
1
@talonx: Nie mam pojęcia. Mój błąd. Byłem pochowany w rozwoju Androida, stąd zamieszanie.
Zamel
3
Kiedy OP powiedział wyraźnie, że należy użyć HttpUrlConnection, to po co używać HttpClient?
Nie wie dużo