¿Cómo enviar PUT, DELETE solicitud HTTP en HttpURLConnection?

132

Quiero saber si es posible enviar la solicitud PUT, DELETE (prácticamente) a través java.net.HttpURLConnectionde una URL basada en HTTP.

He leído tantos artículos que describen cómo enviar solicitudes GET, POST, TRACE, OPTIONS pero todavía no he encontrado ningún código de muestra que realice correctamente las solicitudes PUT y DELETE.

Matriz
fuente
2
¿Puedes mostrarnos el código que intentaste usar?
akarnokd

Respuestas:

177

Para realizar un PUT HTTP:

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();

Para realizar un DELETE HTTP:

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
fuente
1
Si. Todas estas cosas son posibles pero realmente dependen de la API admitida por su proveedor de correo / blog.
Matthew Murdoch
55
hola, estoy teniendo problemas con el delete. Cuando ejecuto este código tal como está aquí, realmente no sucede nada, la solicitud no se envía. La misma situación es cuando estoy haciendo postsolicitudes, pero allí puedo usar, por ejemplo, lo httpCon.getContent()que desencadena la solicitud. Pero el httpCon.connect()no dispara nada en mi máquina :-)
coubeatczech
77
En los ejemplos anteriores, creo que deberá llamar a httpCon.getInputStream () al final para que la solicitud se envíe realmente.
Eric Smith
3
Obtuve "java.net.ProtocolException: DELETE no admite la escritura"
Kimo_do
1
@edisusanto el recurso nombrado (indicado por la URL) son los datos que se eliminarán.
Matthew Murdoch
24

Así es como funcionó para mí:

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("DELETE");
int responseCode = connection.getResponseCode();
Eli Heifetz
fuente
11
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;
}

Luego en tu código:

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
fuente
Obteniendo 'java.io.IOException: método no compatible: put' inJ2me sdk logger
CodeToLife
8

Estoy de acuerdo con @adietisheim y el resto de personas que sugieren HttpClient.

Pasé un tiempo tratando de hacer una simple llamada al servicio de descanso con HttpURLConnection y no me convenció y después de eso intenté con HttpClient y fue realmente más fácil, comprensible y agradable.

Un ejemplo de código para hacer una llamada put put es el siguiente:

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
fuente
Solo quería decir gracias por esto. Pasado muchas horas tratando de que mi código utilizando HttpURLConnectional trabajo, pero seguía funcionando en un error extraño, en concreto: cannot retry due to server authentication, in streaming mode. Seguir tu consejo funcionó para mí. Me doy cuenta de que esto no responde exactamente la pregunta, que pide usar HttpURLConnection, pero su respuesta me ayudó.
Tom Catullo
@Deprecated usa HttpClientBuilder en su lugar
Waldemar Wosiński
3

UrlConnection es una API incómoda para trabajar. HttpClient es, con mucho, la mejor API y le ahorrará perder tiempo buscando cómo lograr ciertas cosas como esta pregunta de stackoverflow ilustra perfectamente. Escribo esto después de haber usado jdk HttpUrlConnection en varios clientes REST. Además, cuando se trata de características de escalabilidad (como agrupaciones de hilos, agrupaciones de conexiones, etc.) HttpClient es superior

adietisheim
fuente
3

Para hacer un PUT en HTML correctamente, deberá rodearlo con 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
fuente
1

Incluso la plantilla de descanso puede ser una opción:

String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?<CourierServiceabilityRequest>....";
    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
fuente
Esta es una de las mejores respuestas que he visto en SO.
thonnor
0

hay una manera simple de eliminar y poner solicitud, simplemente puede hacerlo agregando un " _method" parámetro a su solicitud de publicación y escribir " PUT" o " DELETE" por su valor.

Mohamad Rostami
fuente
-1

Recomendaría Apache HTTPClient.

Clint
fuente
9
¿Por qué recomendarías HTTPClient? Es enorme. Quiero decir, en tamaño.
jayarjo
1
@jayarjo, es parte del SDK de Android.
Zamel
9
@Zamel: ¿Dónde exactamente entra Android en la imagen?
talonx
1
@talonx: No tengo idea. Mi error. Fui enterrado en el desarrollo de Android, de ahí la confusión.
Zamel
3
Cuando el OP dijo claramente que debería usarse HttpUrlConnection, ¿por qué usar HttpClient?
No sabe mucho