在 Android 中发送 POST 数据

Posted

技术标签:

【中文标题】在 Android 中发送 POST 数据【英文标题】:Sending POST data in Android 【发布时间】:2011-02-25 16:19:28 【问题描述】:

我对 phpjavascript 和许多其他脚本语言有经验,但对 Java 或 android 没有太多经验。

我正在寻找一种将 POST 数据发送到 PHP 脚本并显示结果的方法。

【问题讨论】:

【参考方案1】:

以下方法适用于最新的 Android 库并使用 okhttp

    OkHttpClient client = new OkHttpClient();
    RequestBody formBody = new FormBody.Builder()
            .add("key1", "value1")
            .add("key2", "value2")  //optional
            .add("key3", "value3")  //optional
            .add("key4", "value4")  //optional
            .build();


    Request request = new Request.Builder()
    .url("http://.....")   //URL
    .post(formBody)
    .build();


    client.newCall(request).enqueue(new Callback() 
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) 
            e.getStackTrace();
        

        @Override
       public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException 
            if(response.isSuccessful())
                ResponseBody responseBody = response.body();
                Log.e("TAG_", responseBody.string());
       
    

【讨论】:

【参考方案2】:

您可以使用以下命令向URL 发送HTTP-POST 请求并接收响应。我总是用这个:

try 
    AsyncHttpClient client = new AsyncHttpClient();
    // Http Request Params Object
    RequestParams params = new RequestParams();
    String u = "B2mGaME";
    String au = "gamewrapperB2M";
    // String mob = "880xxxxxxxxxx";
    params.put("usr", u.toString());
    params.put("aut", au.toString());
    params.put("uph", MobileNo.toString());
    //  params.put("uph", mob.toString());
    client.post("http://196.6.13.01:88/ws/game_wrapper_reg_check.php", params, new AsyncHttpResponseHandler() 
        @Override
        public void onSuccess(String response) 
            playStatus = response;
            //////Get your Response/////
            Log.i(getClass().getSimpleName(), "Response SP Status. " + playStatus);
        
        @Override
        public void onFailure(Throwable throwable) 
            super.onFailure(throwable);
        
    );
 catch (Exception e) 
    e.printStackTrace();

您还需要在 libs 文件夹中添加以下 Jar 文件

android-async-http-1.3.1.jar

最后,我编辑了你的 build.gradle:

dependencies 
    compile files('libs/<android-async-http-1.3.1.jar>')

在最后重建你的项目。

【讨论】:

【参考方案3】:

注意(2020 年 10 月):以下答案中使用的 AsyncTask 在 Android API 级别 30 中已被弃用。请参阅 Official documentation 或 this blog post 了解更多更新示例

更新(2017 年 6 月)答案,适用于 Android 6.0+。感谢 @Rohit Suthar、@Tamis Bolvari 和 @sudhiskr 的 cmets。

    public class CallAPI extends AsyncTask<String, String, String> 
    
        public CallAPI()
            //set context variables if required
        
    
        @Override
        protected void onPreExecute() 
            super.onPreExecute();
        
    
         @Override
         protected String doInBackground(String... params) 
            String urlString = params[0]; // URL to call
            String data = params[1]; //data to post
            OutputStream out = null;

            try 
                URL url = new URL(urlString);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                out = new BufferedOutputStream(urlConnection.getOutputStream());

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
                writer.write(data);
                writer.flush();
                writer.close();
                out.close();

                urlConnection.connect();
             catch (Exception e) 
                System.out.println(e.getMessage());
            
        
    

参考资料:

https://developer.android.com/reference/java/net/HttpURLConnection.html How to add parameters to HttpURLConnection using POST using NameValuePair

原始答案(2010 年 5 月)

注意:此解决方案已过时。它仅适用于最高 5.1 的 Android 设备。 Android 6.0 及更高版本不包括此答案中使用的 Apache http 客户端。

Apache Commons 的 Http 客户端是可行的方法。它已经包含在android中。下面是一个简单的例子,说明如何使用它进行 HTTP Post。

public void postData() 
    // Create a new HttpClient and Post Header
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

    try 
        // Add your data
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("id", "12345"));
        nameValuePairs.add(new BasicNameValuePair("stringdata", "Hi"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
        
     catch (ClientProtocolException e) 
        // TODO Auto-generated catch block
     catch (IOException e) 
        // TODO Auto-generated catch block
    
 

【讨论】:

httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); for UTF-8 编码。 HttpClient”、“HttpPost”、“HttpResponse”、“HttpEntity”、“EntityUtils”、“NameValuePair”、“BasicNameValuePair”是已弃用。请提出其他解决方案。 另外DefaultHttpClient 已被弃用。 这个 - 更新 - 答案不会发布任何内容。是吗? 这确实NOT 显示POST 示例。编辑6.0 答案会很好。这是经过优化以显示为第一个结果的搜索引擎,这有点误导。【参考方案4】:

对于 Android = > 5

org.apache.http 类和 AndroidHttpClient 类已在 Android 5.1弃用。这些类不再维护,您应该尽快将使用这些 API 的任何应用代码迁移到 URLConnection 类。

https://developer.android.com/about/versions/android-5.1.html#http

想用 HttpUrlConnection 分享我的代码

public String  performPostCall(String requestURL,
        HashMap<String, String> postDataParams) 

    URL url;
    String response = "";
    try 
        url = new URL(requestURL);

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.setDoOutput(true);


        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));
        writer.write(getPostDataString(postDataParams));

        writer.flush();
        writer.close();
        os.close();
        int responseCode=conn.getResponseCode();

        if (responseCode == HttpsURLConnection.HTTP_OK) 
            String line;
            BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
            while ((line=br.readLine()) != null) 
                response+=line;
            
        
        else 
            response="";    

        
     catch (Exception e) 
        e.printStackTrace();
    

    return response;

...

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

你也可以发布方法:

conn.setRequestMethod("POST");

21/02/2016 更新

对于 jsonpost 请求,请参阅此示例:

public class Empty extends
        AsyncTask<Void, Void, Boolean> 

    String urlString = "http://www.yoursite.com/";

    private final String TAG = "post json example";
    private Context context;

    private int advertisementId;

    public Empty(Context contex, int advertisementId) 

        this.context = contex;
        this.advertisementId = advertisementId;
    

    @Override
    protected void onPreExecute() 
        Log.e(TAG, "1 - RequestVoteTask is about to start...");

    

    @Override
    protected Boolean doInBackground(Void... params) 
        boolean status = false;

        String response = "";
        Log.e(TAG, "2 - pre Request to response...");

        try 
            response = performPostCall(urlString, new HashMap<String, String>() 

                        private static final long serialVersionUID = 1L;

                        
                            put("Accept", "application/json");
                            put("Content-Type", "application/json");
                        
                    );
            Log.e(TAG, "3 - give Response...");
            Log.e(TAG, "4 " + response.toString());
         catch (Exception e) 
            // displayLoding(false);

            Log.e(TAG, "Error ...");
        
        Log.e(TAG, "5 - after Response...");

        if (!response.equalsIgnoreCase("")) 
            try 
                Log.e(TAG, "6 - response !empty...");
                //
                JSONObject jRoot = new JSONObject(response);
                JSONObject d = jRoot.getJSONObject("d");

                int ResultType = d.getInt("ResultType");
                Log.e("ResultType", ResultType + "");

                if (ResultType == 1) 

                    status = true;

                

             catch (JSONException e) 
                // displayLoding(false);
                // e.printStackTrace();
                Log.e(TAG, "Error " + e.getMessage());
             finally 

            
         else 
            Log.e(TAG, "6 - response is empty...");

            status = false;
        

        return status;
    

    @Override
    protected void onPostExecute(Boolean result) 
        //
        Log.e(TAG, "7 - onPostExecute ...");

        if (result) 
            Log.e(TAG, "8 - Update UI ...");

            // setUpdateUI(adv);
         else 
            Log.e(TAG, "8 - Finish ...");

            // displayLoding(false);
            // finish();
        

    

    public String performPostCall(String requestURL,
                                  HashMap<String, String> postDataParams) 

        URL url;
        String response = "";
        try 
            url = new URL(requestURL);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(context.getResources().getInteger(
                    R.integer.maximum_timeout_to_server));
            conn.setConnectTimeout(context.getResources().getInteger(
                    R.integer.maximum_timeout_to_server));
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);

            conn.setRequestProperty("Content-Type", "application/json");

            Log.e(TAG, "11 - url : " + requestURL);

            /*
             * JSON
             */

            JSONObject root = new JSONObject();
            //
            String token = Static.getPrefsToken(context);

            root.put("securityInfo", Static.getSecurityInfo(context));
            root.put("advertisementId", advertisementId);

            Log.e(TAG, "12 - root : " + root.toString());

            String str = root.toString();
            byte[] outputBytes = str.getBytes("UTF-8");
            OutputStream os = conn.getOutputStream();
            os.write(outputBytes);

            int responseCode = conn.getResponseCode();

            Log.e(TAG, "13 - responseCode : " + responseCode);

            if (responseCode == HttpsURLConnection.HTTP_OK) 
                Log.e(TAG, "14 - HTTP_OK");

                String line;
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        conn.getInputStream()));
                while ((line = br.readLine()) != null) 
                    response += line;
                
             else 
                Log.e(TAG, "14 - False - HTTP_OK");
                response = "";
            
         catch (Exception e) 
            e.printStackTrace();
        

        return response;
    


2016 年 8 月 24 日更新

使用一些最好的库,例如:

Retrofit Volley

因为:

避免使用 HttpUrlConnection 和 HttpClient

在较低的 API 级别(主要在 Gingerbread 和 Froyo 上),HttpUrlConnection 和 HttpClient 远非完美

也避免使用 AsyncTask 他们更快 他们缓存一切

自从引入 Honeycomb (API 11) 以来,必须在与主线程不同的单独线程上执行网络操作

【讨论】:

描述你的问题 我有它的工作,但我得到这个错误:NetworkOnMainThreadException 您必须在 AsyncTask 中声明此方法,而不是在主线程中。因为您的活动主线程不支持长达 5 秒的任何进度。你可以用谷歌搜索“NetworkOnMainThreadException”。您必须使用 AsyncTask ,然后在 doInBackground 中使用我的方法。 in performPostCall() getPostData() 应替换为 getPostDataString() 对于第一种方法,考虑到您序列化数据的方式,您可能还希望添加“application/x-www-form-urlencoded”的内容类型。【参考方案5】:

使用 Square 的开源 okHttp 库。 okHttp 适用于 Android 2.3 及更高版本,并具有 Apache 2.0 license on GitHub。

发送 POST 数据就像在 AsyncTask 中添加以下内容一样简单:

OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
                      .add("email", emailString) // A sample POST field
                      .add("comment", commentString) // Another sample POST field
                      .build();
Request request = new Request.Builder()
                 .url("https://yourdomain.org/callback.php") // The URL to send the data to
                 .post(formBody)
                 .build();

okHttp 在 maven 上也有一个命名空间,因此将其添加到您的 Android Studio 项目中很简单。只需将 compile 'com.squareup.okhttp3:okhttp:3.11.0' 添加到您应用的 build.gradle 即可。

完整代码

将以下内容添加到您的活动中:

public class CallAPI extends AsyncTask<String, String, String> 

    String emailString;
    String commentString;

    public CallAPI(String email, String commnt)
           emailString = email;
           commentString = commnt;
    

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

    @Override
    protected String doInBackground(String... params) 
        OkHttpClient client = new OkHttpClient();
        RequestBody formBody = new FormBody.Builder()
                      .add("email", emailString) // A sample POST field
                      .add("comment", commentString) // Another sample POST field
                      .build();
        Request request = new Request.Builder()
                 .url("https://yourdomain.org/callback.php") // The URL to send the data to
                 .post(formBody)
                 .build();
        return "";
    

    @Override
    protected void onPostExecute(String s) 
        super.onPostExecute(s);
    

然后调用它:

new CallAPI(emailString, commentString).execute();

【讨论】:

【参考方案6】:

您可以使用 WebServer 类发布 HttpRequest 并在其侦听器接口中跟踪响应。

WebServer server=new WebServer(getApplicationContext());

server.setOnServerStatusListner(new WebServer.OnServerStatusListner() 
    @Override
    public void onServerResponded(String responce) 

    

    @Override
    public void onServerRevoked() 

    
);

现在创建一个 DataRack 来绑定你的数据

List<DataRack> racks=new ArrayList<DataRack>();
racks.add(new DataRack("name","Simon"));
racks.add(new DataRack("age","40"));
racks.add(new DataRack("location","Canada"));

现在只需使用该机架发送 POST 请求

server.connectWithPOST(MainActivity.this,"http://sangeethnandakumar.esy.es/PROJECTS/PUBLIC_SERVICE/posttest.php",racks);

为此,您需要包含我的库。文档here

【讨论】:

【参考方案7】:

我在 this 视频教程中发现了 this 有用的示例。

连接器类:

package com.tutorials.hp.mysqlinsert;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
 * Created by Oclemmy on 3/31/2016 for ProgrammingWizards Channel.
 */
public class Connector 
    /*
 1.SHALL HELP US ESTABLISH A CONNECTION TO THE NETWORK
 2. WE ARE MAKING A POST REQUEST
  */
    public static HttpURLConnection connect(String urlAddress) 
        try
        
            URL url=new URL(urlAddress);
            HttpURLConnection con= (HttpURLConnection) url.openConnection();
            //SET PROPERTIES
            con.setRequestMethod("POST");
            con.setConnectTimeout(20000);
            con.setReadTimeout(20000);
            con.setDoInput(true);
            con.setDoOutput(true);
            //RETURN
            return con;
         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
        return null;
    
 

DataPackager 类:

package com.tutorials.hp.mysqlinsert;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
/**
 * Created by Oclemmy on 3/31/2016 for ProgrammingWizards Channel.
 * 1.BASICALLY PACKS DATA WE WANNA SEND
 */
public class DataPackager 
    String name,position,team;
    /*
    SECTION 1.RECEIVE ALL DATA WE WANNA SEND
     */
    public DataPackager(String name, String position, String team) 
        this.name = name;
        this.position = position;
        this.team = team;
    
    /*
   SECTION 2
   1.PACK THEM INTO A JSON OBJECT
   2. READ ALL THIS DATA AND ENCODE IT INTO A FROMAT THAT CAN BE SENT VIA NETWORK
    */
    public String packData()
    
        JSONObject jo=new JSONObject();
        StringBuffer packedData=new StringBuffer();
        try
        
            jo.put("Name",name);
            jo.put("Position",position);
            jo.put("Team",team);
            Boolean firstValue=true;
            Iterator it=jo.keys();
            do 
                String key=it.next().toString();
                String value=jo.get(key).toString();
                if(firstValue)
                
                    firstValue=false;
                else
                
                    packedData.append("&");
                
                packedData.append(URLEncoder.encode(key,"UTF-8"));
                packedData.append("=");
                packedData.append(URLEncoder.encode(value,"UTF-8"));
            while (it.hasNext());
            return packedData.toString();
         catch (JSONException e) 
            e.printStackTrace();
         catch (UnsupportedEncodingException e) 
            e.printStackTrace();
        
        return null;
        


发件人类别:

package com.tutorials.hp.mysqlinsert;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
/**
 * Created by Oclemmy on 3/31/2016 for ProgrammingWizards Channel and Camposha.com.
 * 1.SEND DATA FROM EDITTEXT OVER THE NETWORK
 * 2.DO IT IN BACKGROUND THREAD
 * 3.READ RESPONSE FROM A SERVER
 */
public class Sender extends AsyncTask<Void,Void,String> 
    Context c;
    String urlAddress;
    EditText nameTxt,posTxt,teamTxt;
    String name,pos,team;
    ProgressDialog pd;
    /*
            1.OUR CONSTRUCTOR
    2.RECEIVE CONTEXT,URL ADDRESS AND EDITTEXTS FROM OUR MAINACTIVITY
    */
    public Sender(Context c, String urlAddress,EditText...editTexts) 
        this.c = c;
        this.urlAddress = urlAddress;
        //INPUT EDITTEXTS
        this.nameTxt=editTexts[0];
        this.posTxt=editTexts[1];
        this.teamTxt=editTexts[2];
        //GET TEXTS FROM EDITEXTS
        name=nameTxt.getText().toString();
        pos=posTxt.getText().toString();
        team=teamTxt.getText().toString();
    
    /*
   1.SHOW PROGRESS DIALOG WHILE DOWNLOADING DATA
    */
    @Override
    protected void onPreExecute() 
        super.onPreExecute();
        pd=new ProgressDialog(c);
        pd.setTitle("Send");
        pd.setMessage("Sending..Please wait");
        pd.show();
    
    /*
    1.WHERE WE SEND DATA TO NETWORK
    2.RETURNS FOR US A STRING
     */
    @Override
    protected String doInBackground(Void... params) 
        return this.send();
    
    /*
  1. CALLED WHEN JOB IS OVER
  2. WE DISMISS OUR PD
  3.RECEIVE A STRING FROM DOINBACKGROUND
   */
    @Override
    protected void onPostExecute(String response) 
        super.onPostExecute(response);
        pd.dismiss();
        if(response != null)
        
            //SUCCESS
            Toast.makeText(c,response,Toast.LENGTH_LONG).show();
            nameTxt.setText("");
            posTxt.setText("");
            teamTxt.setText("");
        else
        
            //NO SUCCESS
            Toast.makeText(c,"Unsuccessful "+response,Toast.LENGTH_LONG).show();
        
    
/*
SEND DATA OVER THE NETWORK
RECEIVE AND RETURN A RESPONSE
 */
    private String send()
    
        //CONNECT
        HttpURLConnection con=Connector.connect(urlAddress);
        if(con==null)
        
            return null;
        
        try
        
            OutputStream os=con.getOutputStream();
            //WRITE
            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));
            bw.write(new DataPackager(name,pos,team).packData());
            bw.flush();
            //RELEASE RES
            bw.close();
            os.close();
            //HAS IT BEEN SUCCESSFUL?
            int responseCode=con.getResponseCode();
            if(responseCode==con.HTTP_OK)
            
                //GET EXACT RESPONSE
                BufferedReader br=new BufferedReader(new InputStreamReader(con.getInputStream()));
                StringBuffer response=new StringBuffer();
                String line;
                //READ LINE BY LINE
                while ((line=br.readLine()) != null)
                
                    response.append(line);
                
                //RELEASE RES
                br.close();
                return response.toString();
            else
            
            
         catch (IOException e) 
            e.printStackTrace();
        
        return null;
    


主活动:

package com.tutorials.hp.mysqlinsert;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/*
1.OUR LAUNCHER ACTIVITY
2.INITIALIZE SOME UI STUFF
3.WE START SENDER ON BUTTON CLICK
 */
public class MainActivity extends AppCompatActivity 
    String urlAddress="http://10.0.2.2/android/poster.php";
    EditText nameTxt,posTxt,teamTxt;
    Button saveBtn;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //INITIALIZE UI FIELDS
        nameTxt= (EditText) findViewById(R.id.nameEditTxt);
        posTxt= (EditText) findViewById(R.id.posEditTxt);
        teamTxt= (EditText) findViewById(R.id.teamEditTxt);
        saveBtn= (Button) findViewById(R.id.saveBtn);
        saveBtn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                //START ASYNC TASK
                Sender s=new Sender(MainActivity.this,urlAddress,nameTxt,posTxt,teamTxt);
                s.execute();
            
        );
    

ContentMain.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tutorials.hp.mysqlinsert.MainActivity"
    tools:showIn="@layout/activity_main">
    <TextView
        android:layout_
        android:layout_
        android:text="Hello World!" />
    <LinearLayout
        android:layout_
        android:layout_
        android:layout_marginTop="?attr/actionBarSize"
        android:orientation="vertical"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="50dp">
        <android.support.design.widget.TextInputLayout
            android:id="@+id/nameLayout"
            android:layout_
            android:layout_>
            <EditText
                android:id="@+id/nameEditTxt"
                android:layout_
                android:layout_
                android:singleLine="true"
                android:hint= "Name" />
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/teamLayout"
            android:layout_
            android:layout_>
            <EditText
                android:id="@+id/teamEditTxt"
                android:layout_
                android:layout_
                android:hint="Description" />
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/posLayout"
            android:layout_
            android:layout_>
            <EditText
                android:id="@+id/posEditTxt"
                android:layout_
                android:layout_
                android:hint="Position" />
            <!--android:inputType="textPassword"-->
        </android.support.design.widget.TextInputLayout>
        <Button android:id="@+id/saveBtn"
            android:layout_
            android:layout_
            android:text="Save"
            android:clickable="true"
            android:background="@color/colorAccent"
            android:layout_marginTop="40dp"
            android:textColor="@android:color/white"/>
    </LinearLayout>
</RelativeLayout>

【讨论】:

【参考方案8】:

这是一个如何在不使用外部 Apache 库的情况下发布多部分数据的示例:

byte[] buffer = getBuffer();

if(buffer.length > 0) 
   String lineEnd = "\r\n"; 
   String twoHyphens = "--"; 
   String boundary =  "RQdzAAihJq7Xp1kjraqf"; 

   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   DataOutputStream dos = new DataOutputStream(baos);

   // Send parameter #1
   dos.writeBytes(twoHyphens + boundary + lineEnd); 
   dos.writeBytes("Content-Disposition: form-data; name=\"param1\"" + lineEnd);
   dos.writeBytes("Content-Type: text/plain; charset=US-ASCII" + lineEnd);
   dos.writeBytes("Content-Transfer-Encoding: 8bit" + lineEnd);
   dos.writeBytes(lineEnd);
   dos.writeBytes(myStringData + lineEnd);

   // Send parameter #2
   //dos.writeBytes(twoHyphens + boundary + lineEnd); 
   //dos.writeBytes("Content-Disposition: form-data; name=\"param2\"" + lineEnd + lineEnd);
   //dos.writeBytes("foo2" + lineEnd);

   // Send a binary file
   dos.writeBytes(twoHyphens + boundary + lineEnd); 
   dos.writeBytes("Content-Disposition: form-data; name=\"param3\";filename=\"test_file.dat\"" + lineEnd); 
   dos.writeBytes("Content-Type: application/octet-stream" + lineEnd);
   dos.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
   dos.writeBytes(lineEnd); 
   dos.write(buffer);
   dos.writeBytes(lineEnd); 
   dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 
   dos.flush(); 
   dos.close();

   ByteArrayInputStream content = new ByteArrayInputStream(baos.toByteArray());
   BasicHttpEntity entity = new BasicHttpEntity();
   entity.setContent(content);

   HttpPost httpPost = new HttpPost(myURL);
   httpPost.addHeader("Connection", "Keep-Alive");
   httpPost.addHeader("Content-Type", "multipart/form-data; boundary="+boundary);

   //MultipartEntity entity = new MultipartEntity();
   //entity.addPart("param3", new ByteArrayBody(buffer, "test_file.dat"));
   //entity.addPart("param1", new StringBody(myStringData));

   httpPost.setEntity(entity);

   /*
   String httpData = "";
   ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
   entity.writeTo(baos1);
   httpData = baos1.toString("UTF-8");
   */

   /*
   Header[] hdrs = httpPost.getAllHeaders();
   for(Header hdr: hdrs) 
     httpData += hdr.getName() + " | " + hdr.getValue() + " |_| ";
   
   */

   //Log.e(TAG, "httpPost data: " + httpData);
   response = httpClient.execute(httpPost);

【讨论】:

使用apache库有什么问题吗?我是 android 应用程序的初学者,不知道原因背景 - 抱歉可能是愚蠢的问题:-) 没有,哈哈。 httpClient 和 httpPost 是 apache。 如何同时发送 JSONObject 和 doc 文件? @lubosdz 因为android sdk下没有MultipartEntity,你必须为此包含外部jars【参考方案9】:

这样我们就可以用http post方法发送数据并得到结果

     public class MyHttpPostProjectActivity extends Activity implements OnClickListener 

    private EditText usernameEditText;
    private EditText passwordEditText;
    private Button sendPostReqButton;
    private Button clearButton;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        usernameEditText = (EditText) findViewById(R.id.login_username_editText);
        passwordEditText = (EditText) findViewById(R.id.login_password_editText);

        sendPostReqButton = (Button) findViewById(R.id.login_sendPostReq_button);
        sendPostReqButton.setOnClickListener(this);

        clearButton = (Button) findViewById(R.id.login_clear_button);
        clearButton.setOnClickListener(this);        
    

    @Override
    public void onClick(View v) 

        if(v.getId() == R.id.login_clear_button)
            usernameEditText.setText("");
            passwordEditText.setText("");
            passwordEditText.setCursorVisible(false);
            passwordEditText.setFocusable(false);
            usernameEditText.setCursorVisible(true);
            passwordEditText.setFocusable(true);
        else if(v.getId() == R.id.login_sendPostReq_button)
            String givenUsername = usernameEditText.getEditableText().toString();
            String givenPassword = passwordEditText.getEditableText().toString();

            System.out.println("Given username :" + givenUsername + " Given password :" + givenPassword);

            sendPostRequest(givenUsername, givenPassword);
           
    

    private void sendPostRequest(String givenUsername, String givenPassword) 

        class SendPostReqAsyncTask extends AsyncTask<String, Void, String>

            @Override
            protected String doInBackground(String... params) 

                String paramUsername = params[0];
                String paramPassword = params[1];

                System.out.println("*** doInBackground ** paramUsername " + paramUsername + " paramPassword :" + paramPassword);

                HttpClient httpClient = new DefaultHttpClient();

                // In a POST request, we don't pass the values in the URL.
                //Therefore we use only the web page URL as the parameter of the HttpPost argument
                HttpPost httpPost = new HttpPost("http://www.nirmana.lk/hec/android/postLogin.php");

                // Because we are not passing values over the URL, we should have a mechanism to pass the values that can be
                //uniquely separate by the other end.
                //To achieve that we use BasicNameValuePair             
                //Things we need to pass with the POST request
                BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("paramUsername", paramUsername);
                BasicNameValuePair passwordBasicNameValuePAir = new BasicNameValuePair("paramPassword", paramPassword);

                // We add the content that we want to pass with the POST request to as name-value pairs
                //Now we put those sending details to an ArrayList with type safe of NameValuePair
                List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
                nameValuePairList.add(usernameBasicNameValuePair);
                nameValuePairList.add(passwordBasicNameValuePAir);

                try 
                    // UrlEncodedFormEntity is an entity composed of a list of url-encoded pairs. 
                    //This is typically useful while sending an HTTP POST request. 
                    UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairList);

                    // setEntity() hands the entity (here it is urlEncodedFormEntity) to the request.
                    httpPost.setEntity(urlEncodedFormEntity);

                    try 
                        // HttpResponse is an interface just like HttpPost.
                        //Therefore we can't initialize them
                        HttpResponse httpResponse = httpClient.execute(httpPost);

                        // According to the JAVA API, InputStream constructor do nothing. 
                        //So we can't initialize InputStream although it is not an interface
                        InputStream inputStream = httpResponse.getEntity().getContent();

                        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

                        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                        StringBuilder stringBuilder = new StringBuilder();

                        String bufferedStrChunk = null;

                        while((bufferedStrChunk = bufferedReader.readLine()) != null)
                            stringBuilder.append(bufferedStrChunk);
                        

                        return stringBuilder.toString();

                     catch (ClientProtocolException cpe) 
                        System.out.println("First Exception caz of HttpResponese :" + cpe);
                        cpe.printStackTrace();
                     catch (IOException ioe) 
                        System.out.println("Second Exception caz of HttpResponse :" + ioe);
                        ioe.printStackTrace();
                    

                 catch (UnsupportedEncodingException uee) 
                    System.out.println("An Exception given because of UrlEncodedFormEntity argument :" + uee);
                    uee.printStackTrace();
                

                return null;
            

            @Override
            protected void onPostExecute(String result) 
                super.onPostExecute(result);

                if(result.equals("working"))
                    Toast.makeText(getApplicationContext(), "HTTP POST is working...", Toast.LENGTH_LONG).show();
                else
                    Toast.makeText(getApplicationContext(), "Invalid POST req...", Toast.LENGTH_LONG).show();
                
                       
        

        SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
        sendPostReqAsyncTask.execute(givenUsername, givenPassword);     
    

【讨论】:

【参考方案10】:

@primpop 回答我将添加如何将响应转换为字符串:

HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) 
    InputStream instream = entity.getContent();

    String result = RestClient.convertStreamToString(instream);
    Log.i("Read from server", result);

Here is an example of convertStramToString.

【讨论】:

HttpClient”、“HttpPost”、“HttpResponse”、“HttpEntity”、“EntityUtils”、“NameValuePair”、“BasicNameValuePair”是已弃用。请提出其他解决方案。【参考方案11】:

如果您只想将数据附加到 Url,您可以使用 HttpUrlConnection 来完成,因为 HttpClient 现在已被弃用。 更好的方法是使用类似的库-

凌空抽射 改造

我们可以使用通过AsyncTask类执行的代码将数据发布到php脚本并获取结果并显示它。

    private class LongOperation  extends AsyncTask<String, Void, Void> 

    // Required initialization


    private String Content;
    private String Error = null;
    private ProgressDialog Dialog = new ProgressDialog(Login.this);
    String data ="";
    int sizeData = 0;



    protected void onPreExecute() 
        // NOTE: You can call UI Element here.

        //Start Progress Dialog (Message)

        Dialog.setMessage("Please wait..");
        Dialog.show();
        Dialog.setCancelable(false);
        Dialog.setCanceledOnTouchOutside(false);

        try
            // Set Request parameter
            data +="&" + URLEncoder.encode("username", "UTF-8") + "="+edittext.getText();



         catch (UnsupportedEncodingException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        

    

    // Call after onPreExecute method
    protected Void doInBackground(String... urls) 

        /************ Make Post Call To Web Server ***********/
        BufferedReader reader=null;

        // Send data
        try
        

            // Defined URL  where to send data
            URL url = new URL(urls[0]);

            // Send POST data request

            URLConnection conn = url.openConnection();

            conn.setConnectTimeout(5000);//define connection timeout 
            conn.setReadTimeout(5000);//define read timeout
            conn.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write( data );
            wr.flush();

            // Get the server response

            reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line = null;



            // Read Server Response
            while((line = reader.readLine()) != null)
            
                // Append server response in string
                sb.append(line + " ");
            

            // Append Server Response To Content String
            Content = sb.toString();


        
        catch(Exception ex)
        
            Error = ex.getMessage();
        
        finally
        
            try
            

                reader.close();
            

            catch(Exception ex) 
        


        return null;
    

    protected void onPostExecute(Void unused) 
        // NOTE: You can call UI Element here.

        // Close progress dialog
        Dialog.dismiss();

        if (Error != null) 

                Toast.makeText(getApplicationContext(),"Error encountered",Toast.LENGTH_LONG).show();



        
        else 




            try 

                JSONObject jsonRootObject = new JSONObject(Content);


                JSONObject json2 =jsonRootObject.getJSONObject("jsonkey");//pass jsonkey here


                String id =json2.optString("id").toString();//parse json to string through parameters


     //the result is stored in string id. you can display it now


             catch (JSONException e) e.printStackTrace();


        

    


但是使用诸如 volley 或 retrofit 之类的库是更好的选择,因为 Asynctask 类和 HttpurlConnection 与库相比要慢得多。该库还将获取所有内容,并且速度也更快。

【讨论】:

【参考方案12】:

您可以将URLConnectionsetDoOutput(true)getOutputStream()(用于发送数据)、 getInputStream()(用于接收)一起使用。 Sun 有an example正是为了这个

【讨论】:

仅供参考,与 HttpClient 4.x 库相比,URLConnection 的性能相当差。 我更喜欢纯 URLConnection,因为它似乎比 Apache Commons HttpClient 更快。【参考方案13】:

对我来说接下来的作品:

 private sendData() 
     JSONObject jsonObject = new JSONObject();
     jsonObject.accumulate("key1", value1);
     jsonObject.accumulate("key2", value2);

     boolean success = sendPost(SERVER_URL + "/v1/auth", jsonObject);
 

 private boolean sendPost(String url, JSONObject parameters) 
        boolean requestResult = false;
        InputStream inputStream = null;
        String result = "";
        try 

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            String json = "";

            json = parameters.toString();

            StringEntity se = new StringEntity(json);
            httpPost.setEntity(se);

            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            HttpResponse httpResponse = httpclient.execute(httpPost);

            inputStream = httpResponse.getEntity().getContent();

            if (inputStream != null) 
                result = convertInputStreamToString(inputStream);
                requestResult = true;
             else 
                result = "Did not work!";
                requestResult = false;
            
            System.out.println(result);
         catch (Exception e) 
            Log.d("InputStream", e.getLocalizedMessage());
            requestResult = false;
        
        return requestResult;
    

【讨论】:

【参考方案14】:

在较新版本的 Android 中,您必须将所有 Web I/O 请求放入一个新线程中。 AsyncTask 最适合小请求。

【讨论】:

虽然很有价值,但这不是问题的答案,应该作为评论。【参考方案15】:

将数据作为 HTTP 请求发布的方法,

public static InputStream callPostService(String Url,
        List<NameValuePair> data) 
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(Url);
    try 
        httppost.setEntity(new UrlEncodedFormEntity(data));
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        return entity.getContent();
     catch (ClientProtocolException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
    
    return null;

【讨论】:

HttpClient”、“HttpPost”、“HttpResponse”、“HttpEntity”、“EntityUtils”、“NameValuePair”、“BasicNameValuePair”是已弃用。请提出其他解决方案。 @Rohit Suthar,不推荐用于新的 Android 版本,而不是旧版本。所以停止垃圾邮件【参考方案16】:

最好使用 Apache Commons HttpClient,它也包含在 android 中。 看一下 Android Developer: Apache HTTP Client Package Summary 获取一般 api 信息。

【讨论】:

以上是关于在 Android 中发送 POST 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用异步http post从android studio发送数据到xampp并在真实设备中运行?

android中Post方式发送HTTP请求

将 POST 数据从 Android 应用程序发送到 PHP MySQL

Android Kotlin Retrofit Post Request 输入的数据未发送

将 $_POST 数据发送到 Android Webview

Android进阶:5发送post请求json数据格式以及okhttp框架的使用