2010-01-08 5 views
29

Je voudrais générer une requête POST à ​​un serveur qui nécessite une authentification. J'ai essayé d'utiliser la méthode suivante:Java: comment utiliser UrlConnection pour publier une demande avec autorisation?

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

mais le serveur ne reçoit pas les données d'autorisation. La ligne qui est censé ajouter des données d'autorisation est la suivante:

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

et la ligne

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

jette également un IOException.

De toute façon, je serais très reconnaissant si quelqu'un pouvait suggérer n'importe quelle solution de la logique ci-dessus afin de permettre l'autorisation en utilisant POST avec UrlConnection.

mais de toute évidence, cela ne fonctionne pas comme prévu, mais si la même logique est utilisée pour la requête GET, tout fonctionne correctement.

Répondre

38

Une amende example found here. Powerlord le droit, below, pour POST vous avez besoin de HttpURLConnection, à la place.

est Ci-dessous le code pour le faire,

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

changement URLConnection-HttpURLConnection, pour en faire la demande POST.

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

Suggestion (... dans les commentaires):

Vous pourriez avoir besoin de définir ces propriétés aussi,

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

C'est une demande GET qui n'est pas un problème. –

+3

Pas une grosse différence en termes d'autorisation. –

+3

C'est si vous êtes venu ici pour savoir comment faire le bit de post :( –

0

autorisation HTTP ne diffère pas entre les requêtes GET et POST? Je suppose d'abord que quelque chose d'autre est faux. Au lieu de définir l'en-tête Authorization directement, je suggère d'utiliser la classe java.net.Authorization, mais je ne suis pas sûr que cela résoudra votre problème. Peut-être que votre serveur est configuré pour exiger un schéma d'autorisation différent de "basic" pour les demandes de publication?

+0

Nifty, je n'ai jamais entendu parler de cette classe. Cependant, cette classe est abstraite, il aurait donc besoin d'une classe d'implémentation pour cela. – Powerlord

+0

Bien sûr, vous devez implémenter une méthode spécifique à l'application pour obtenir les informations d'identification. Dans une application interactive, vous pouvez, par exemple, besoin d'une boîte de dialogue contextuelle. – jarnbjo

0

Je cherchais des informations sur la façon de faire une demande POST. Je dois spécifier que la requête mi est une requête POST parce que je travaille avec les services web RESTful qui utilisent seulement les méthodes POST, et si la requête n'est pas postée, quand j'essaye de faire la requête je reçois une erreur HTTP 405. Je m'assure que mon code n'est pas faux faire le suivant: Je crée une méthode dans mon service Web qui est appelée via la requête GET et je pointe mon application pour consommer cette méthode de service Web et cela fonctionne. Mon code est le suivant:

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

Je ne vois nulle part dans le code où vous indiquez que ceci est une requête POST. Là encore, vous avez besoin d'un java.net.HttpURLConnection pour le faire.

En fait, je recommande fortement d'utiliser HttpURLConnection au lieu de URLConnection, avec conn.setRequestMethod("POST"); et de voir si cela vous donne toujours des problèmes.

+0

oui correct, c'est mieux si vous utilisez java.net.HttpURLConnection ... – AutoMEta

+0

exemple serait bien ... –

+0

Ceci est la bonne réponse. Vous ne pouvez pas faire une demande de publication avec URLConnection. Vous devez utiliser HttpURLConnection. – Bob

2

Pour envoyer un appel de requête POST:

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

Si vous voulez envoyer du texte dans l'utilisation de la demande:

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

je suis tombé sur ce problème aujourd'hui et aucune des solutions publiées ici a travaillé . Cependant, le code affiché here travaillé pour une demande POST:

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

} 

Il se trouve que ce n'est pas l'autorisation qui est le problème. Dans mon cas, c'était un problème d'encodage. Le type de contenu que je avais besoin était l'application /JSON mais de la documentation Java:

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

La fonction encode se traduit par la chaîne en application/x-www-form-urlencoded. Maintenant, si vous ne définissez pas de type de contenu, vous pouvez obtenir une erreur 415 Type de support non pris en charge. Si vous le définissez sur application/json ou sur tout ce qui n'est pas application/x-www-form-urlencoded, vous obtenez une IOException. Pour résoudre ce problème, évitez simplement la méthode d'encodage.

Pour ce scénario, ce qui suit devrait fonctionner:

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

Une autre petite information qui pourrait être utile à pourquoi les pauses de code lors de la création du BufferedReader est parce que le POST demande en fait seulement est exécuté lorsque conn.getInputStream() est appelée.

4

Pour faire l'authentification OAuth à l'application externe (INSTAGRAM) Étape 3 « obtenir le jeton après avoir reçu le code » Seul le code ci-dessous a fonctionné pour moi

Worth à dire que cela a fonctionné pour moi en utilisant une URL localhost avec un callback configuré avec le nom "callback dans web.xml et callback URL enregistré: par exemple localhost: 8084/MyAPP/docs/insta/callback

MAIS après avoir réussi les étapes d'authentification, en utilisant le même site externe" INSTAGRAM "pour faire GET de Les balises ou MEDIA pour récupérer des données JSON en utilisant la méthode initiale ne fonctionnaient pas Dans mon servlet pour faire GET en utilisant l'URL comme eg api.in stagram.com/v1/tags/MYTAG/media/recent?access_token=MY_TOKEN seule méthode trouvé HERE travaillé

Merci à tous les contributeurs

 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

Sur API 22 L'utilisation de BasicNamevalue paire est depricated, utilisez plutôt le HASMAP pour cela.Pour en savoir plus sur la visite de HasMap ici 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); 
    } 
} 

et appelez simplement la fonction lorsque vous avez besoin pour obtenir les données du serveur, soit par la poste ou obtenir comme celui-ci

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

         } 
        }); 

Maintenant, il est complete.Enjoy !!! Commentez-le si vous trouvez un problème.

Questions connexes