Java - sending HTTP parameters via POST method easily

前端 未结 17 1655
借酒劲吻你
借酒劲吻你 2020-11-21 05:54

I am successfully using this code to send HTTP requests with some parameters via GET method

void sendRequest(String request)
{
            


        
相关标签:
17条回答
  • 2020-11-21 06:32

    I find HttpURLConnection really cumbersome to use. And you have to write a lot of boilerplate, error prone code. I needed a lightweight wrapper for my Android projects and came out with a library which you can use as well: DavidWebb.

    The above example could be written like this:

    Webb webb = Webb.create();
    webb.post("http://example.com/index.php")
            .param("param1", "a")
            .param("param2", "b")
            .param("param3", "c")
            .ensureSuccess()
            .asVoid();
    

    You can find a list of alternative libraries on the link provided.

    0 讨论(0)
  • 2020-11-21 06:32

    I had the same issue. I wanted to send data via POST. I used the following code:

        URL url = new URL("http://example.com/getval.php");
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("param1", param1);
        params.put("param2", param2);
    
        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String,Object> 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"));
        }
        String urlParameters = postData.toString();
        URLConnection conn = url.openConnection();
    
        conn.setDoOutput(true);
    
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
    
        writer.write(urlParameters);
        writer.flush();
    
        String result = "";
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    
        while ((line = reader.readLine()) != null) {
            result += line;
        }
        writer.close();
        reader.close()
        System.out.println(result);
    

    I used Jsoup for parse:

        Document doc = Jsoup.parseBodyFragment(value);
        Iterator<Element> opts = doc.select("option").iterator();
        for (;opts.hasNext();) {
            Element item = opts.next();
            if (item.hasAttr("value")) {
                System.out.println(item.attr("value"));
            }
        }
    
    0 讨论(0)
  • 2020-11-21 06:33

    I took Boann's answer and used it to create a more flexible query string builder that supports lists and arrays, just like php's http_build_query method:

    public static byte[] httpBuildQueryString(Map<String, Object> postsData) throws UnsupportedEncodingException {
        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String,Object> param : postsData.entrySet()) {
            if (postData.length() != 0) postData.append('&');
    
            Object value = param.getValue();
            String key = param.getKey();
    
            if(value instanceof Object[] || value instanceof List<?>)
            {
                int size = value instanceof Object[] ? ((Object[])value).length : ((List<?>)value).size();
                for(int i = 0; i < size; i++)
                {
                    Object val = value instanceof Object[] ? ((Object[])value)[i] : ((List<?>)value).get(i);
                    if(i>0) postData.append('&');
                    postData.append(URLEncoder.encode(key + "[" + i + "]", "UTF-8"));
                    postData.append('=');            
                    postData.append(URLEncoder.encode(String.valueOf(val), "UTF-8"));
                }
            }
            else
            {
                postData.append(URLEncoder.encode(key, "UTF-8"));
                postData.append('=');            
                postData.append(URLEncoder.encode(String.valueOf(value), "UTF-8"));
            }
        }
        return postData.toString().getBytes("UTF-8");
    }
    
    0 讨论(0)
  • 2020-11-21 06:34

    For those having trouble receiving the request on a php page using $_POST because you expect key-value pairs:

    While all the answers where very helpful, I lacked some basic understanding on which string actually to post, since in the old apache HttpClient I used

    new UrlEncodedFormEntity(nameValuePairs); (Java)
    

    and then could use $_POST in php do get the key-value pairs.

    To my understanding now one has build that string manually before posting. So the string needs to look like

    val data = "key1=val1&key2=val2"
    

    but instead just adding it to the url it is posted (in the header).

    The alternative would be to use a json-string instead:

    val data = "{\"key1\":\"val1\",\"key2\":\"val2\"}" // {"key1":"val1","key2":"val2"}
    

    and pull it in php without $_POST:

    $json_params = file_get_contents('php://input');
    // echo_p("Data: $json_params");
    $data = json_decode($json_params, true);
    

    Here you find a sample code in Kotlin:

    class TaskDownloadTest : AsyncTask<Void, Void, Void>() {
        override fun doInBackground(vararg params: Void): Void? {
            var urlConnection: HttpURLConnection? = null
    
            try {
    
                val postData = JsonObject()
                postData.addProperty("key1", "val1")
                postData.addProperty("key2", "val2")
    
                // reformat json to key1=value1&key2=value2
                // keeping json because I may change the php part to interpret json requests, could be a HashMap instead
                val keys = postData.keySet()
                var request = ""
                keys.forEach { key ->
                    // Log.i("data", key)
                    request += "$key=${postData.get(key)}&"
                }
                request = request.replace("\"", "").removeSuffix("&")
                val requestLength = request.toByteArray().size
                // Warning in Android 9 you need to add a line in the application part of the manifest: android:usesCleartextTraffic="true"
                // https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted
                val url = URL("http://10.0.2.2/getdata.php")
                urlConnection = url.openConnection() as HttpURLConnection
                // urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") // apparently default
                // Not sure what these are for, I do not use them
                // urlConnection.setRequestProperty("Content-Type", "application/json")
                // urlConnection.setRequestProperty("Key","Value")
                urlConnection.readTimeout = 5000
                urlConnection.connectTimeout = 5000
                urlConnection.requestMethod = "POST"
                urlConnection.doOutput = true
                // urlConnection.doInput = true
                urlConnection.useCaches = false
                urlConnection.setFixedLengthStreamingMode(requestLength)
                // urlConnection.setChunkedStreamingMode(0) // if you do not want to handle request length which is fine for small requests
    
                val out = urlConnection.outputStream
                val writer = BufferedWriter(
                    OutputStreamWriter(
                        out, "UTF-8"
                    )
                )
                writer.write(request)
                // writer.write("{\"key1\":\"val1\",\"key2\":\"val2\"}") // {"key1":"val1","key2":"val2"} JsonFormat or just postData.toString() for $json_params=file_get_contents('php://input'); json_decode($json_params, true); in php
                // writer.write("key1=val1&key2=val2") // key=value format for $_POST in php
                writer.flush()
                writer.close()
                out.close()
    
                val code = urlConnection.responseCode
                if (code != 200) {
                    throw IOException("Invalid response from server: $code")
                }
    
                val rd = BufferedReader(
                    InputStreamReader(
                        urlConnection.inputStream
                    )
                )
                var line = rd.readLine()
                while (line != null) {
                    Log.i("data", line)
                    line = rd.readLine()
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                urlConnection?.disconnect()
            }
    
            return null
        }
    }
    
    0 讨论(0)
  • 2020-11-21 06:37

    Hello pls use this class to improve your post method

    public static JSONObject doPostRequest(HashMap<String, String> data, String url) {
    
        try {
            RequestBody requestBody;
            MultipartBuilder mBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
    
            if (data != null) {
    
    
                for (String key : data.keySet()) {
                    String value = data.get(key);
                    Utility.printLog("Key Values", key + "-----------------" + value);
    
                    mBuilder.addFormDataPart(key, value);
    
                }
            } else {
                mBuilder.addFormDataPart("temp", "temp");
            }
            requestBody = mBuilder.build();
    
    
            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();
    
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            String responseBody = response.body().string();
            Utility.printLog("URL", url);
            Utility.printLog("Response", responseBody);
            return new JSONObject(responseBody);
    
        } catch (UnknownHostException | UnsupportedEncodingException e) {
    
            JSONObject jsonObject=new JSONObject();
    
            try {
                jsonObject.put("status","false");
                jsonObject.put("message",e.getLocalizedMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
            Log.e(TAG, "Error: " + e.getLocalizedMessage());
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject jsonObject=new JSONObject();
    
            try {
                jsonObject.put("status","false");
                jsonObject.put("message",e.getLocalizedMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
            Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
        }
        return null;
    }
    
    0 讨论(0)
  • 2020-11-21 06:39

    In a GET request, the parameters are sent as part of the URL.

    In a POST request, the parameters are sent as a body of the request, after the headers.

    To do a POST with HttpURLConnection, you need to write the parameters to the connection after you have opened the connection.

    This code should get you started:

    String urlParameters  = "param1=a&param2=b&param3=c";
    byte[] postData       = urlParameters.getBytes( StandardCharsets.UTF_8 );
    int    postDataLength = postData.length;
    String request        = "http://example.com/index.php";
    URL    url            = new URL( request );
    HttpURLConnection conn= (HttpURLConnection) url.openConnection();           
    conn.setDoOutput( true );
    conn.setInstanceFollowRedirects( false );
    conn.setRequestMethod( "POST" );
    conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded"); 
    conn.setRequestProperty( "charset", "utf-8");
    conn.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
    conn.setUseCaches( false );
    try( DataOutputStream wr = new DataOutputStream( conn.getOutputStream())) {
       wr.write( postData );
    }
    
    0 讨论(0)
提交回复
热议问题