2010-01-08 19 views
29

Me gustaría generar solicitud POST a un servidor que requiere autenticación. Intenté utilizar el siguiente método:Java: ¿cómo usar UrlConnection para publicar una solicitud con autorización?

private synchronized String CreateNewProductPOST (String urlString, String encodedString, String title, String content, Double price, String tags) { 

    String data = "product[title]=" + URLEncoder.encode(title) + 
       "&product[content]=" + URLEncoder.encode(content) + 
       "&product[price]=" + URLEncoder.encode(price.toString()) + 
       "&tags=" + tags; 
    try { 
     URL url = new URL(urlString); 
     URLConnection conn; 
     conn = url.openConnection(); 
     conn.setRequestProperty ("Authorization", "Basic " + encodedString); 
     conn.setDoOutput(true); 
     conn.setDoInput(true); 
     OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); 
     wr.write(data); 
     wr.flush(); 
     // Get the response 
     BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
     String line; 
     while ((line = rd.readLine()) != null) { 
      // Process line... 
      } 
     wr.close(); 
     rd.close(); 
     return rd.toString(); 
    } catch (MalformedURLException e) { 

     e.printStackTrace(); 
     return e.getMessage(); 
    } 
    catch (IOException e) { 

     e.printStackTrace(); 
     return e.getMessage(); 
    } 
} 

pero el servidor no recibe los datos de autorización. La línea que se supone que añadir los datos de autorización es el siguiente:

conn.setRequestProperty ("Authorization", "Basic " + encodedString); 

y la línea

BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 

también lanza una IOException.

De todos modos estaría muy agradecido si alguien pudiera sugerir alguna corrección de la lógica anterior para habilitar la autorización usando POST con UrlConnection.

pero, obviamente, no funciona como se supone que debe, aunque si se utiliza la misma lógica para la solicitud GET todo funciona bien.

Respuesta

38

Una multa example found here. Powerlord lo hizo bien, below, para POST necesita HttpURLConnection, en su lugar.

A continuación se muestra el código para hacer eso,

URL url = new URL(urlString); 
    URLConnection conn = url.openConnection(); 
    conn.setDoOutput(true); 
    conn.setRequestProperty ("Authorization", encodedCredentials); 

    OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); 

    writer.write(data); 
    writer.flush(); 
    String line; 
    BufferedReader reader = new BufferedReader(new 
            InputStreamReader(conn.getInputStream())); 
    while ((line = reader.readLine()) != null) { 
     System.out.println(line); 
    } 
    writer.close(); 
    reader.close(); 

Cambio URLConnection a HttpURLConnection, para que sea petición POST.

HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
    conn.setRequestMethod("POST"); 

sugerencia (... en los comentarios):

Puede que sea necesario establecer estas propiedades también,

conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); 
conn.setRequestProperty("Accept", "*/*"); 
+1

Esta es la solicitud GET, que no es un problema. –

+3

No hay una gran diferencia en términos de autorización. –

+3

Es si vino aquí buscando cómo hacer el bit de la publicación :( –

0

autorización HTTP no se diferencia entre GET y POST peticiones, por lo Primero asumiría que algo más está mal. En lugar de configurar el encabezado Authorization directamente, sugeriría usar la clase java.net.Authorization, pero no estoy seguro si resuelve su problema. ¿Tal vez su servidor está configurado de alguna manera para requerir un esquema de autorización diferente de "básico" para las solicitudes de publicación?

+0

Nifty, nunca supe de esta clase. Sin embargo, esta clase es abstracta, por lo que realmente necesitaría una clase de implementación para ello. – Powerlord

+0

Claro, debe implementar una forma específica de aplicación para obtener las credenciales. En una aplicación interactiva, puede, por ejemplo, necesita un cuadro de diálogo emergente. – jarnbjo

0

estaba buscando información acerca de cómo hacer una solicitud POST. Necesito especificar que mi solicitud es una solicitud POST porque, estoy trabajando con servicios web RESTful que solo usan métodos POST, y si la solicitud no es post, cuando intento hacer la solicitud, recibo un error HTTP 405. Aseguro que mi código no está mal al hacer lo siguiente: creo un método en mi servicio web que se llama a través de la solicitud GET y apunto mi aplicación para consumir ese método de servicio web y funciona. Mi código es el siguiente:

URL server = null; 
    URLConnection conexion = null; 
    BufferedReader reader = null; 
    server = new URL("http://localhost:8089/myApp/resources/webService"); 
    conexion = server.openConnection(); 
    reader = new BufferedReader(new InputStreamReader(server.openStream())); 
    System.out.println(reader.readLine()); 
8

no veo en cualquier parte del código que se especifica que se trata de una solicitud POST. Por otra parte, necesita un java.net.HttpURLConnection para hacer eso.

De hecho, le recomiendo usar HttpURLConnection en lugar de URLConnection, con conn.setRequestMethod("POST"); y vea si todavía le da problemas.

+0

sí correcto, es mejor si utiliza java.net.HttpURLConnection ... – AutoMEta

+0

ejemplo sería bueno ... –

+0

Esta es la respuesta correcta. No puede hacer una solicitud posterior con URLConnection. Debe usar HttpURLConnection. – Bob

2

Para enviar una llamada de solicitud POST:

 connection.setDoOutput(true); // Triggers POST. 

Si desea enviar el texto en el uso solicitud:

 java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(connection.getOutputStream()); 
     wr.write(textToSend); 
     wr.flush(); 
1

me encontré con este problema hoy y ninguna de las soluciones incluidas en este documento trabajó . Sin embargo, el código publicado here trabajaban para una solicitud dePOST:

// HTTP POST request 
private void sendPost() throws Exception { 

    String url = "https://selfsolve.apple.com/wcResults.do"; 
    URL obj = new URL(url); 
    HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); 

    //add reuqest header 
    con.setRequestMethod("POST"); 
    con.setRequestProperty("User-Agent", USER_AGENT); 
    con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 

    String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345"; 

    // Send post request 
    con.setDoOutput(true); 
    DataOutputStream wr = new DataOutputStream(con.getOutputStream()); 
    wr.writeBytes(urlParameters); 
    wr.flush(); 
    wr.close(); 

    int responseCode = con.getResponseCode(); 
    System.out.println("\nSending 'POST' request to URL : " + url); 
    System.out.println("Post parameters : " + urlParameters); 
    System.out.println("Response Code : " + responseCode); 

    BufferedReader in = new BufferedReader(
      new InputStreamReader(con.getInputStream())); 
    String inputLine; 
    StringBuffer response = new StringBuffer(); 

    while ((inputLine = in.readLine()) != null) { 
     response.append(inputLine); 
    } 
    in.close(); 

    //print result 
    System.out.println(response.toString()); 

} 

Resulta que no es la autorización que es el problema. En mi caso, fue un problema de codificación. El tipo de contenido que necesitaba era application/json pero a partir de la documentación de Java:

static String encode(String s, String enc) 
Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme. 

La función de codificación traduce la cadena en aplicación urlencoded-x-www-form/.

Ahora, si no configura un Tipo de contenido, es posible que obtenga un error 415 Tipo de soporte no admitido. Si lo configura en application/json o cualquier cosa que no sea application/x-www-form-urlencoded, obtendrá una IOException. Para resolver esto, simplemente evite el método de codificación.

Para este escenario particular, el siguiente debería funcionar:

String data = "product[title]=" + title + 
       "&product[content]=" + content + 
       "&product[price]=" + price.toString() + 
       "&tags=" + tags; 

Otra pequeña pieza de información que podría ser útil de por qué se rompe el código cuando se crea el lector tamponada se debe a que la solicitud POSTAL en realidad sólo se ejecuta cuando se llama conn.getInputStream().

4

Para realizar la autenticación OAuth para aplicación externa (Instagram) Paso 3 "obtener el token después de recibir el código" Sólo código de abajo trabajó para mí

Vale la pena señalar también que trabajó para mí el uso de algunas URL localhost con una Servlet de devolución de llamada configurado con el nombre "devolución de llamada en web.xml y devolución de llamada URL registrada: por ejemplo, localhost: 8084/MyAPP/docs/insta/callback

PERO después de completar con éxito los pasos de autenticación, utilizando el mismo sitio externo" INSTAGRAM "para hacer GET de Etiquetas o MEDIA para recuperar datos JSON utilizando el método inicial no funcionó. Dentro de mi servlet para hacer OBTENER usando url como por ejemplo, api.in stagram.com/v1/tags/MYTAG/media/recent?access_token=MY_TOKEN único método encontró HERE trabajaron

Gracias a todos los contribuyentes

 URL url = new URL(httpurl); 
     HashMap<String, String> params = new HashMap<String, String>(); 
     params.put("client_id", id); 
     params.put("client_secret", secret); 
     params.put("grant_type", "authorization_code"); 
     params.put("redirect_uri", redirect); 
     params.put("code", code); // your INSTAGRAM code received 
     Set set = params.entrySet(); 
     Iterator i = set.iterator(); 
     StringBuilder postData = new StringBuilder(); 
     for (Map.Entry<String, String> param : params.entrySet()) { 
      if (postData.length() != 0) { 
       postData.append('&'); 
      } 
      postData.append(URLEncoder.encode(param.getKey(), "UTF-8")); 
      postData.append('='); 
      postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8")); 
     } 
     byte[] postDataBytes = postData.toString().getBytes("UTF-8"); 

     HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
     conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); 
     conn.setDoOutput(true); 
     conn.getOutputStream().write(postDataBytes); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); 
     StringBuilder builder = new StringBuilder(); 
     for (String line = null; (line = reader.readLine()) != null;) { 
      builder.append(line).append("\n"); 
     } 
     reader.close(); 
     conn.disconnect(); 
     System.out.println("INSTAGRAM token returned: "+builder.toString()); 
1

El API 22 El Uso De BasicNamevalue par se depricated, en lugar de utilizar el HASMAP para eso.Para saber más sobre la visita HasMap aquí more on hasmap developer.android

package com.yubraj.sample.datamanager; 

import android.content.Context; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.text.TextUtils; 
import android.util.Log; 

import com.yubaraj.sample.utilities.GeneralUtilities; 


import java.io.BufferedInputStream; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 
import java.io.UnsupportedEncodingException; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.net.URLEncoder; 
import java.util.HashMap; 
import java.util.Map; 

import javax.net.ssl.HttpsURLConnection; 

/** 
* Created by yubraj on 7/30/15. 
*/ 
public class ServerRequestHandler { 
    private static final String TAG = "Server Request"; 
    OnServerRequestComplete listener; 

    public ServerRequestHandler(){ 

    } 
    public void doServerRequest(HashMap<String, String> parameters, String url, int requestType, OnServerRequestComplete listener){ 

     debug("ServerRequest", "server request called, url = " + url); 
     if(listener != null){ 
      this.listener = listener; 
     } 
     try { 
      new BackgroundDataSync(getPostDataString(parameters), url, requestType).execute(); 
      debug(TAG , " asnyc task called"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
    public void doServerRequest(HashMap<String, String> parameters, String url, int requestType){ 
     doServerRequest(parameters, url, requestType, null); 
    } 

    public interface OnServerRequestComplete{ 
     void onSucess(Bundle bundle); 
     void onFailed(int status_code, String mesage, String url); 
    } 

    public void setOnServerRequestCompleteListener(OnServerRequestComplete listener){ 
     this.listener = listener; 
    } 

    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException { 
     StringBuilder result = new StringBuilder(); 
     boolean first = true; 
     for(Map.Entry<String, String> entry : params.entrySet()){ 
      if (first) 
       first = false; 
      else 
       result.append("&"); 

      result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); 
      result.append("="); 
      result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); 
     } 

     return result.toString(); 
    } 

    class BackgroundDataSync extends AsyncTask<String, Void , String>{ 
     String params; 
     String mUrl; 
     int request_type; 

     public BackgroundDataSync(String params, String url, int request_type){ 
      this.mUrl = url; 
      this.params = params; 
      this.request_type = request_type; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected String doInBackground(String... urls) { 
      debug(TAG, "in Background, urls = " + urls.length); 
      HttpURLConnection connection; 
       debug(TAG, "in Background, url = " + mUrl); 
       String response = ""; 
       switch (request_type) { 
        case 1: 
         try { 
          connection = iniitializeHTTPConnection(mUrl, "POST"); 
          OutputStream os = connection.getOutputStream(); 
          BufferedWriter writer = new BufferedWriter(
            new OutputStreamWriter(os, "UTF-8")); 
          writer.write(params); 
          writer.flush(); 
          writer.close(); 
          os.close(); 
          int responseCode = connection.getResponseCode(); 
          if (responseCode == HttpsURLConnection.HTTP_OK) { 
          /* String line; 
          BufferedReader br=new BufferedReader(new InputStreamReader(connection.getInputStream())); 
          while ((line=br.readLine()) != null) { 
           response+=line; 
          }*/ 
           response = getDataFromInputStream(new InputStreamReader(connection.getInputStream())); 
          } else { 
           response = ""; 
          } 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
         break; 
        case 0: 
         connection = iniitializeHTTPConnection(mUrl, "GET"); 

         try { 
          if (connection.getResponseCode() == connection.HTTP_OK) { 
           response = getDataFromInputStream(new InputStreamReader(connection.getInputStream())); 
          } 
         } catch (Exception e) { 
          e.printStackTrace(); 
          response = ""; 
         } 
         break; 
       } 
       return response; 


     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      if(TextUtils.isEmpty(s) || s.length() == 0){ 
       listener.onFailed(DbConstants.NOT_FOUND, "Data not found", mUrl); 
      } 
      else{ 
       Bundle bundle = new Bundle(); 
       bundle.putInt(DbConstants.STATUS_CODE, DbConstants.HTTP_OK); 
       bundle.putString(DbConstants.RESPONSE, s); 
       bundle.putString(DbConstants.URL, mUrl); 
       listener.onSucess(bundle); 
      } 
      //System.out.println("Data Obtained = " + s); 
     } 

     private HttpURLConnection iniitializeHTTPConnection(String url, String requestType) { 
      try { 
       debug("ServerRequest", "url = " + url + "requestType = " + requestType); 
       URL link = new URL(url); 
       HttpURLConnection conn = (HttpURLConnection) link.openConnection(); 
       conn.setRequestMethod(requestType); 
       conn.setDoInput(true); 
       conn.setDoOutput(true); 
       return conn; 
      } 
      catch(Exception e){ 
       e.printStackTrace(); 
      } 
      return null; 
     } 

    } 
    private String getDataFromInputStream(InputStreamReader reader){ 
     String line; 
     String response = ""; 
     try { 

      BufferedReader br = new BufferedReader(reader); 
      while ((line = br.readLine()) != null) { 
       response += line; 

       debug("ServerRequest", "response length = " + response.length()); 
      } 
     } 
     catch (Exception e){ 
      e.printStackTrace(); 
     } 
     return response; 
    } 

    private void debug(String tag, String string) { 
     Log.d(tag, string); 
    } 
} 

y sólo llamar a la función cuando se necesitaba para obtener los datos desde un servidor o bien por correo postal o conseguir como esto

HashMap<String, String>params = new HashMap<String, String>(); 
        params.put("action", "request_sample"); 
        params.put("name", uname); 
        params.put("message", umsg); 
        params.put("email", getEmailofUser()); 
        params.put("type", "bio"); 
dq.doServerRequest(params, "your_url", DbConstants.METHOD_POST); 
        dq.setOnServerRequestCompleteListener(new ServerRequestHandler.OnServerRequestComplete() { 
         @Override 
         public void onSucess(Bundle bundle) { 
          debug("data", bundle.getString(DbConstants.RESPONSE)); 
                } 

         @Override 
         public void onFailed(int status_code, String mesage, String url) { 
          debug("sample", mesage); 

         } 
        }); 

Ahora es complete.Enjoy !!! Coméntelo si encuentra algún problema.

Cuestiones relacionadas