it-swarm.com.de

Java: Wie kann ich mit UrlConnection Anfragen mit Autorisierung posten?

Ich möchte eine POST -Anforderung an einen Server generieren, der eine Authentifizierung erfordert. Ich habe versucht, die folgende Methode zu verwenden:

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

der Server erhält jedoch keine Berechtigungsdaten. Die Zeile, die Berechtigungsdaten hinzufügen soll, lautet wie folgt:

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

und die Linie 

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

löst auch eine IOException aus.

Trotzdem wäre ich sehr dankbar, wenn jemand eine Korrektur der obigen Logik vorschlagen könnte, um die Autorisierung über POST mit UrlConnection zu aktivieren.

aber offensichtlich funktioniert es nicht so, wie es soll, obwohl alles funktioniert, wenn dieselbe Logik für die GET-Anfrage verwendet wird.

31
Niko Gamulin

Ein gutes Beispiel hier . Powerlord hat es richtig gemacht, unter , für POST benötigt man stattdessen HttpURLConnection .

Unten ist der Code, um das zu tun,

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

Ändern Sie URLConnection in HttpURLConnection, um die Anforderung POST auszuführen.

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

Vorschlag (... in Kommentaren):

Sie müssen möglicherweise auch diese Eigenschaften festlegen.

conn.setRequestProperty( "Content-type", "application/x-www-form-urlencoded");
conn.setRequestProperty( "Accept", "*/*" );
40
Adeel Ansari

Ich sehe im Code nirgendwo, wo Sie angeben, dass dies eine POST Anforderung ist. Dann brauchen Sie noch einen Java.net.HttpURLConnection , um das zu tun. 

In der Tat empfehle ich dringend, HttpURLConnection anstelle von URLConnection mit conn.setRequestMethod("POST"); zu verwenden und zu sehen, ob es immer noch Probleme gibt.

9
Powerlord

OAuth-Authentifizierung für eine externe App (INSTAGRAM) durchführen Schritt 3 "Holen Sie sich das Token, nachdem Sie den Code erhalten haben" Nur der folgende Code hat für mich funktioniert

Zu erwähnen ist auch, dass es für mich funktioniert hat, wenn ich einige localhost-URLs mit einem Callback-Servlet mit dem Namen "callback in web.xml" und "callback-URL" verwendet habe, z

ABER nach erfolgreich abgeschlossenen Authentifizierungsschritten und Verwenden derselben externen Site "INSTAGRAM", um GET von Tags oder MEDIA auszuführen, um JSON-Daten abzurufen, wobei die anfängliche Methode nicht funktioniert hat. In meinem Servlet GET verwenden, indem URL wie .__ verwendet wird, z. api.instagram.com/v1/tags/MYTAG/media/recent?access_token=MY_TOKEN Nur Methode gefunden HIER hat funktioniert 

Vielen Dank an alle Mitwirkenden

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

So senden Sie einen POST - Anforderungsaufruf:

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

Wenn Sie Text in der Anfrage senden möchten, verwenden Sie:

        Java.io.OutputStreamWriter wr = new Java.io.OutputStreamWriter(connection.getOutputStream());
        wr.write(textToSend);
        wr.flush();
2
Dimitris

Bei Verwendung von API 22 wird das Use of BasicNamevalue-Paar missbraucht. Mehr über den HasMap-Besuch erfahren Sie hier mehr zu 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);
    }
}

rufen Sie einfach die Funktion auf, wenn Sie die Daten entweder per Post vom Server abrufen oder so abrufen müssen

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

                        }
                    });

Jetzt ist es fertig. Kommentieren Sie es, wenn Sie ein Problem finden.

1
yubaraj poudel

Ich bin heute auf dieses Problem gestoßen und keine der hier veröffentlichten Lösungen hat funktioniert. Der Code, der hier geschrieben wurde, hat jedoch für eine POST - Anfrage funktioniert:

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

}

Es stellt sich heraus, dass nicht die Autorisierung das Problem ist. In meinem Fall war es ein Codierungsproblem. Der benötigte Inhaltstyp war application/json, aber aus der Java-Dokumentation:

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

Die encode-Funktion übersetzt den String in application/x-www-form-urlencoded.

Wenn Sie jetzt keinen Inhaltstyp festlegen, wird möglicherweise ein nicht unterstützter Medientypfehler angezeigt. Wenn Sie application/json oder etwas anderes festlegen, das nicht application/x-www-form-urlencoded ist, erhalten Sie eine IOException. Um dies zu lösen, vermeiden Sie einfach die Kodierungsmethode. 

Für dieses spezielle Szenario sollte Folgendes funktionieren:

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

Eine weitere kleine Information, die hilfreich sein kann, warum der Code beim Erstellen des gepufferten Lesegeräts bricht, besteht darin, dass die Anforderung POST tatsächlich nur ausgeführt wird, wenn conn.getInputStream () aufgerufen wird.

1
Harvinder

ich habe nach Informationen gesucht, wie eine POST -Anfrage ausgeführt werden kann. Ich muss angeben, dass die mi-Anfrage eine POST -Anforderung ist, weil ich mit RESTful-Webdiensten arbeite, die nur POST -Methoden verwenden, und wenn die Anfrage nicht post ist, wenn ich versuche, die request Ich erhalte einen HTTP-Fehler 405. Ich versichere, dass mein Code beim nächsten Mal nicht falsch ist: Ich erstelle eine Methode in meinem Web-Service, die über GET-Request aufgerufen wird, und zeige, dass meine Anwendung diese Web-Service-Methode verwendet, und es funktioniert. Mein Code ist der nächste:

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

Die HTTP-Autorisierung unterscheidet sich nicht zwischen GET- und POST -Anfragen, daher würde ich zunächst davon ausgehen, dass etwas anderes falsch ist. Anstatt den Authorization-Header direkt festzulegen, würde ich vorschlagen, die Java.net.Authorization-Klasse zu verwenden. Ich bin mir jedoch nicht sicher, ob er Ihr Problem löst. Vielleicht ist Ihr Server so konfiguriert, dass er ein anderes Autorisierungsschema als "basic" für Postanfragen benötigt?

0
jarnbjo