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

Posted 编程学渣ズ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android进阶:5发送post请求json数据格式以及okhttp框架的使用相关的知识,希望对你有一定的参考价值。

1、发送post请求

发送post请求的方式还是跟get有点差别,不过是多了传递表单的操作:

var name:String=et_urlname.text.toString()
        var pwd:String=et_urlpwd.text.toString()
        //3.1 发送post请求
        Thread
            var httpurl: String = "http://10.0.2.2:5000/api/login"
            var url: URL = URL(httpurl)
            var conn: HttpURLConnection = url.openConnection() as HttpURLConnection
            conn.requestMethod = "POST"
            conn.connectTimeout = 5000
            conn.readTimeout = 5000
            conn.doOutput=true
            conn.doInput=true
            conn.useCaches=true
​
            var params:String="Email="+URLEncoder.encode(name,"utf-8")
            params = params+ "&Password="+URLEncoder.encode(pwd,"utf-8")
            var byte:ByteArray=params.toByteArray()
​
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded")
            conn.setRequestProperty("Connection","Keep-Alive")
            conn.setRequestProperty("Content-Length",byte.size.toString())
            var os:OutputStream=conn.outputStream
            os.write(byte)
            os.flush()
            os.close()
​
            var code: Int = conn.responseCode
            if (code == 200) 
                var inputStream: InputStream = conn.inputStream
                var byteArray: ByteArray = ByteArray(1024)
                var length: Int=0
                var result: String = ""
​
                inputStream.use 
                    length = it.read(byteArray)
                    result = String(byteArray,0,length)
                    Log.d(TAG, "$result: ")
                    if(result.equals("true"))
                        myhanlder.sendEmptyMessage(1)
                    else
                        myhanlder.sendEmptyMessage(0)
                    
                
                inputStream.close()
​
            
​
        .start()

跟get的主要区别就是这几个项:

conn.requestMethod = "POST"
            conn.connectTimeout = 5000
            conn.readTimeout = 5000
            conn.doOutput=true
            conn.doInput=true
            conn.useCaches=true
​
            var params:String="Email="+URLEncoder.encode(name,"utf-8")
            params = params+ "&Password="+URLEncoder.encode(pwd,"utf-8")
            var byte:ByteArray=params.toByteArray()
​
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded")
            conn.setRequestProperty("Connection","Keep-Alive")
            conn.setRequestProperty("Content-Length",byte.size.toString())
            var os:OutputStream=conn.outputStream
            os.write(byte)
            os.flush()
            os.close()

我们先要将请求方式设置为POST,然

后是超时时间和允许输入输出和缓存,因为我们要提交表单,所以我们conn对象的输出流需要将表单写入到缓存里面,就当做是提交了,后面就是制作我们的表单,只需要通过字符串拼接的方式就可以了,后面我们会学习json格式数据,所以这里我们先这样做;再就是一些请求头,比如提交内容的类型Content-Type,为表单类型,链接模式是长连接Keep-Alive,传递的长度就是字节数组的长度,这里都是规定写法;

设置完成了请求头之后就可以将数据写入到缓存,也就是获取conn的输出流,然后write我们拼接好的数据,刷新关闭流就可以了;

后面获取结果的操作都是和get是一样的,这里我们有使用了handler,还是那个使用了弱引用的匿名内部类:

//创建弱引用handler
    private class MyHanlder(var wk: WeakReference<HttpPractice>):Handler(Looper.getMainLooper())
​
        override fun handleMessage(msg: Message) 
            super.handleMessage(msg)
            wk.get()?.run 
                if(msg.what==1)
                    Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show()
                else
                    Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show()
                
            
​
        
    

2、Json数据格式

android给我们提供了一个简单好用的在对象和json数据格式之间转化的工具,我们需要在项目的builder.gradle下面导入这个依赖(GSON):

implementation 'com.google.code.gson:gson:2.8.6'

然后让项目同步下载一下就可以使用gson这个工具了;json数据格式没有语言的限制,他有自己特定的格式:

又是通过字符串的方式来传递的,所以在网络通讯中有很大的用途;

来总结一下使用HttpURLConnection来访问请求的步骤:

首先我们需要给定一个httpurl也就是网址:

var httpurl: String = "http://10.0.2.2:5000/api/login"

然后就创建一个url对象:

var url: URL = URL(httpurl)

再然后就可以使用这个URL对象来创建一个HttpURLConnection实例:

var conn: HttpURLConnection = url.openConnection() as HttpURLConnection

这样的话就是有了一个请求实例,但是还要配置一些请求的参数:

conn.requestMethod = "POST"
conn.connectTimeout = 5000
conn.readTimeout = 5000
conn.doOutput=true
conn.doInput=true
conn.useCaches=true

这里配置了请求方法为post,请求超时和获取时间都是5秒,然后就是可以读写的操作和开启了缓存;因为post请求一般是需要写入一些数据然后读取一些数据的,比如根据用户的名称和密码我们拿到服务器返回的结果,这个都是通过的读写操作获取,而读写的空间就是缓存区;

要想将表单给服务器,我们就需要使用conn的读写操作:

conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded")
conn.setRequestProperty("Connection","Keep-Alive")
conn.setRequestProperty("Content-Length",byte.size.toString())
var os:OutputStream=conn.outputStream
os.write(byte)
os.flush()
os.close()

这里有设置了提交的数据类型,前面设置的是请求参数,这个就是提交数据的时候需要设置的;

最后拿到了数据时候我们就需要将数据通过流来存下来:

if (code == 200) 
                var inputStream: InputStream = conn.inputStream
                var byteArray: ByteArray = ByteArray(1024)
                var length: Int=0
                var result: String = ""

                inputStream.use 
                    length = it.read(byteArray)
                    result = String(byteArray,0,length)
                    Log.d(TAG, "$result: ")
                    if(result.equals("true"))
                        myhanlder.sendEmptyMessage(1)
                    else
                        myhanlder.sendEmptyMessage(0)
                    
                
                inputStream.close()

这里就是使用的conn的输入流,将数据输入到字节数组中,inputSteam.use的作用就是判断当inputStream中有数据的时候就执行;

3、okhttp请求框架

这是一个安卓很常用的网络请求框架,其实不仅仅是安卓可以,java、Python同样是可以使用这个网络框架,他主要实现的功能就是发送网络请求,不过要比安卓自带的HttpURLConnection方便得多:

Thread()
            var client:OkHttpClient= OkHttpClient()
            var request: Request=Request.Builder()
                .url("https://publicobject.com/helloworld.txt")
                .build()
            client.newCall(request).execute().use 
                response ->
                if(!response.isSuccessful)
                    throw IOException("Unexpected code$response")
                
                for((name,value) in response.headers)
                    Log.d(TAG, "okhttplogin: $name:$value")
                
                Log.d(TAG, "run: "+response.body!!.string())
            
        .start()

注意:在使用这个框架之前我们需要导入依赖,或者可以自己离线导入jar包,但是离线需要导入okhttp和okio两个jar包;

导入依赖:

implementation 'com.squareup.okhttp3:okhttp:4.9.0'

配合之前设置好的user-permssion权限就可以了;

它大概只需要三步就可以完成一个请求的发送和接收,而HttpURLConnection不仅要设置很多参数,还需使用输入输出流来进行数据的接收和发送;那么是那三步呢?

1)、创建okhttpclient客户机和request请求对象;

  var client:OkHttpClient= OkHttpClient()
  var request: Request=Request.Builder()
  .url("https://publicobject.com/helloworld.txt")
  .build()

这里默认发送的是get请求,我们还可以是表单和json:

json:

 //1.2 异步的发送json数据
 var jsonobject:JSONObject= JSONObject()
 var name:String=et_name.text.toString()
 var pwd:String=et_pwd.text.toString()
 jsonobject.put("UserName",name)
 jsonobject.put("UserPwd",pwd)
​
 var client:OkHttpClient= OkHttpClient()
 var request: Request=Request.Builder()
 .url("http://10.0.2.2:8080/api/v2/user_login")
 .post(jsonstr)
 .build()

表单:

var client:OkHttpClient= OkHttpClient()
var formBody=FormBody.Builder()
.add("Email","tt@gmail.com")
.add("Password","123456")
.build()
var request: Request=Request.Builder()
.url("http://10.0.2.2:5000//api/login")
.post(formBody)
.build()

2)、发送请求

client.newCall(request).execute().use 
                response ->
                
            

3)、接收处理数据

if(!response.isSuccessful)
    throw IOException("Unexpected code$response")

for((name,value) in response.headers)
    Log.d(TAG, "okhttplogin: $name:$value")

    Log.d(TAG, "run: "+response.body!!.string())

使用OKhttp框架发送请求的时候是不一样的,他不需要设置太多参数和表头数据,一般就三步:

var client:OkHttpClient= OkHttpClient()
var request: Request=Request.Builder()
     .url("https://publicobject.com/helloworld.txt")
       .build()
client.newCall(request).execute().use 
     response ->
        if(!response.isSuccessful)
              throw IOException("Unexpected code$response")
         
         for((name,value) in response.headers)
               Log.d(TAG, "okhttplogin: $name:$value")
         
         Log.d(TAG, "run: "+response.body!!.string())

创建一个okhttpclient实例,这个实例是用来发送请求的,但是需要传递一个request参数,而我们需要在request参数创建的时候给定网址和类型,默认的就是get请求;request对象的实例是链式创建的,可以看到一般后面要跟上.build();

而且client还可以指定同步和异步请求:

//同步发送
client.newCall(request).execute().use 
                response ->
                
            
   
   
   //异步发送
client.newCall(request).enqueue(object : Callback 
            override fun onFailure(call: Call, e: IOException) 
            /*TODO("Not yet implemented")*/
            Log.d(TAG, "onFailure: 请求失败 $e.message")



override fun onResponse(call: Call, response: Response) 
            //TODO("Not yet implemented")
            if (!response.isSuccessful) 
            throw IOException("Unexpected code 请求出错")


             Log.d(TAG, "run: " + response.body?.string())
             myhanlder.sendEmptyMessage(1)

同步请求的话只需要在response后面处理数据就可以了:

 client.newCall(request).execute().use 
                response ->
                if(!response.isSuccessful)
                    throw IOException("Unexpected code$response")
                
                for((name,value) in response.headers)
                    Log.d(TAG, "okhttplogin: $name:$value")
                
                Log.d(TAG, "run: "+response.body!!.string())
            

而异步的话是具有两个函数(onFailure/onResponse)的,是实现的接口的一个是请求失败的,一个是获取到了数据的;

了解了这三步之后我们就可以发送各种请求了:

json:

var jsonobject:JSONObject= JSONObject()
        var name:String=et_name.text.toString()
        var pwd:String=et_pwd.text.toString()
        jsonobject.put("UserName",name)
        jsonobject.put("UserPwd",pwd)
        Log.d(TAG, "okdown:$name + $pwd ")
        var jsonstr=jsonobject.toString().toRequestBody("application/json;charset=utf-8".toMediaType())
        Thread()
            var client:OkHttpClient= OkHttpClient()
            var request: Request=Request.Builder()
                .url("http://10.0.2.2:8080/api/v2/user_login")
                .post(jsonstr)
                .build()
​
            client.newCall(request).enqueue(object : Callback 
                override fun onFailure(call: Call, e: IOException) 
                    /*TODO("Not yet implemented")*/
                    Log.d(TAG, "onFailure: 请求失败:$e.message")
​
                
​
                override fun onResponse(call: Call, response: Response) 
                    //TODO("Not yet implemented")
                    if (!response.isSuccessful) 
                        throw IOException("Unexpected code$response")
                    
                    var jsonObject: JSONObject = JSONObject(response.body!!.string())
                    Log.d(TAG, "onResponse: $jsonObject.get("RESULT")")
                    //Log.d(TAG, "run: " + response.body!!.string())
​
                
​
            )
        .start()

表单:

 //发送表单请求
        Thread()
            var client:OkHttpClient= OkHttpClient()
​
            var formBody=FormBody.Builder()
                .add("Email","tt@gmail.com")
                .add("Password","123456")
                .build()
            var request: Request=Request.Builder()
                .url("http://10.0.2.2:5000/api/login")
                .post(formBody)
                .build()
​
            client.newCall(request).enqueue(object : Callback 
                override fun onFailure(call: Call, e: IOException) 
                    /*TODO("Not yet implemented")*/
                    Log.d(TAG, "onFailure: 请求失败 $e.message")
​
                
​
                override fun onResponse(call: Call, response: Response) 
                    //TODO("Not yet implemented")
                    if (!response.isSuccessful) 
                        throw IOException("Unexpected code 请求出错")
                    
​
                    Log.d(TAG, "run: " + response.body?.string())
                    myhanlder.sendEmptyMessage(1)
                
​
            )
        .start()

而这两者之间最大的区别就是提交的数据格式不同:

json:

jsonobject.put("UserName",name)
jsonobject.put("UserPwd",pwd)
Log.d(TAG, "okdown:$name + $pwd ")
var jsonstr=jsonobject.toString().toRequestBody("application/json;charset=utf-8".toMediaType())

就是通过上面编码出来的json字符串放到post属性里面:

var request: Request=Request.Builder()
                .url("http://10.0.2.2:8080/api/v2/user_login")
                .post(jsonstr)
                .build()

表单操作也是一样的:

            var formBody=FormBody.Builder()
                .add("Email","tt@gmail.com")
                .add("Password","123456")
                .build()
            var request: Request=Request.Builder()
                .url("http://10.0.2.2:5000/api/login")
                .post(formBody)
                .build()

但是相比HttpURLConnection是节省了不少代码。

使用 Volley 发送带有 JSON 数据的 POST 请求

【中文标题】使用 Volley 发送带有 JSON 数据的 POST 请求【英文标题】:Send POST request with JSON data using Volley 【发布时间】:2014-06-06 21:25:52 【问题描述】:

我想发送一个新的JsonObjectRequest 请求:

我想接收 JSON 数据(来自服务器的响应):OK

我想通过这个请求向服务器发送 JSON 格式的数据

JsonObjectRequest request = new JsonObjectRequest(
    Request.Method.POST, "myurl.com", null,
    new Response.Listener<JSONObject>() 
        @Override
        public void onResponse(JSONObject response) 
            //...
        
    ,
    new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 
            //...
        
    )
    
        @Override
        protected Map<String,String> getParams() 
            // something to do here ??
            return params;
        

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError 
            // something to do here ??
            return params;
        
    ;

附:我也在我的项目中使用 GSON 库。

【问题讨论】:

【参考方案1】:

JsonObjectRequest 实际上接受 JSONObject 作为正文。

来自this blog article,

final String url = "some/url";
final JSONObject jsonBody = new JSONObject("\"type\":\"example\"");

new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>()  ... );

这里是source code and JavaDoc (@param jsonRequest):

/**
 * Creates a new request.
 * @param method the HTTP method to use
 * @param url URL to fetch the JSON from
 * @param jsonRequest A @link JSONObject to post with the request. Null is allowed and
 *   indicates no parameters will be posted along with request.
 * @param listener Listener to receive the JSON response
 * @param errorListener Error listener, or null to ignore errors.
 */
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
        Listener<JSONObject> listener, ErrorListener errorListener) 
    super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
                errorListener);

【讨论】:

HashMap 在您的示例中有点多余。您可以将“令牌”直接放入JSONObject,而无需中间映射。 @shkschneider 我在 jsonBody 上遇到类型不兼容的错误。是否需要将 String 转换为 JSONObject ? @KarthikeyanVe 你是对的,改用new JSONObject("\"type\":\"example\"")——我的错。【参考方案2】:

我知道这个帖子已经很老了,但是我遇到了这个问题,我想出了一个很酷的解决方案,它对许多人来说非常有用,因为它在许多方面纠正/扩展了 Volley 库。

我发现了一些不受支持的开箱即用 Volley 功能:

这个JSONObjectRequest 并不完美:您必须在结尾处期待JSON(请参阅Response.Listener&lt;JSONObject&gt;)。 Empty Responses(只有 200 状态)呢? 如果我想直接从ResponseListener 获取我的 POJO,我该怎么办?

我或多或少在一个大的泛型类中编译了很多解决方案,以便为我引用的所有问题找到解决方案。

  /**
  * Created by laurentmeyer on 25/07/15.
  */
 public class GenericRequest<T> extends JsonRequest<T> 

     private final Gson gson = new Gson();
     private final Class<T> clazz;
     private final Map<String, String> headers;
     // Used for request which do not return anything from the server
     private boolean muteRequest = false;

     /**
      * Basically, this is the constructor which is called by the others.
      * It allows you to send an object of type A to the server and expect a JSON representing a object of type B.
      * The problem with the #JsonObjectRequest is that you expect a JSON at the end.
      * We can do better than that, we can directly receive our POJO.
      * That's what this class does.
      *
      * @param method:        HTTP Method
      * @param classtype:     Classtype to parse the JSON coming from the server
      * @param url:           url to be called
      * @param requestBody:   The body being sent
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      */
     private GenericRequest(int method, Class<T> classtype, String url, String requestBody,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) 
         super(method, url, requestBody, listener,
                 errorListener);
         clazz = classtype;
         this.headers = headers;
         configureRequest();
     

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) 
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, headers);
     

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (without header and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener) 
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, new HashMap<String, String>());
     

     /**
      * Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param requestBody:   String to be sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      */
     public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
                           Response.Listener<T> listener, Response.ErrorListener errorListener) 
         this(method, classtype, url, requestBody, listener,
                 errorListener, new HashMap<String, String>());
     

     /**
      * Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (Without header)
      *
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      */
     public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener) 
         this(Request.Method.GET, url, classtype, "", listener, errorListener);
     

     /**
      * Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (With headers)
      *
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      */
     public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) 
         this(Request.Method.GET, classtype, url, "", listener, errorListener, headers);
     

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      * @param mute:          Muted (put it to true, to make sense)
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers, boolean mute) 
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, headers);
         this.muteRequest = mute;
     

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (without header and muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param mute:          Muted (put it to true, to make sense)
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) 
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, new HashMap<String, String>());
         this.muteRequest = mute;

     

     /**
      * Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param requestBody:   String to be sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param mute:          Muted (put it to true, to make sense)
      */
     public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) 
         this(method, classtype, url, requestBody, listener,
                 errorListener, new HashMap<String, String>());
         this.muteRequest = mute;

     


     @Override
     protected Response<T> parseNetworkResponse(NetworkResponse response) 
         // The magic of the mute request happens here
         if (muteRequest) 
             if (response.statusCode >= 200 && response.statusCode <= 299) 
                 // If the status is correct, we return a success but with a null object, because the server didn't return anything
                 return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
             
          else 
             try 
                 // If it's not muted; we just need to create our POJO from the returned JSON and handle correctly the errors
                 String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                 T parsedObject = gson.fromJson(json, clazz);
                 return Response.success(parsedObject, HttpHeaderParser.parseCacheHeaders(response));
              catch (UnsupportedEncodingException e) 
                 return Response.error(new ParseError(e));
              catch (JsonSyntaxException e) 
                 return Response.error(new ParseError(e));
             
         
         return null;
     

     @Override
     public Map<String, String> getHeaders() throws AuthFailureError 
         return headers != null ? headers : super.getHeaders();
     

     private void configureRequest() 
         // Set retry policy
         // Add headers, for auth for example
         // ...
     
 

这似乎有点矫枉过正,但拥有所有这些构造函数非常酷,因为您拥有所有案例:

(虽然可以直接使用主构造函数,但它当然是可能的)。

    请求的响应解析为 POJO/标头手动设置/POJO 发送 响应解析为 POJO/POJO 以发送的请求 响应解析为 POJO/要发送的字符串的请求 响应解析为 POJO (GET) 的请求 响应解析为 POJO (GET) 的请求/手动设置的标头 请求无响应(200 - 空正文)/手动设置标头/要发送的 POJO 没有响应的请求(200 - 空正文)/要发送的 POJO 没有响应的请求(200 - 空正文)/要发送的字符串

当然,为了让它工作,你必须有谷歌的 GSON Lib;只需添加:

compile 'com.google.code.gson:gson:x.y.z'

到您的依赖项(当前版本是2.3.1)。

【讨论】:

好答案,感谢分享。我只需将 toBeSent 参数的类型从 Object 更改为 T 以提高类型安全性。 是的,好主意,随时编辑!这是社区的东西:D(我目前在移动) 我也在尝试做类似的事情,但它比我要创建的要好得多...... 好一个适合客户端服务器通信中的所有场景。 很好的答案。如果您为此创建一些教程非常好【参考方案3】:
final String URL = "/volley/resource/12";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");

JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
       new Response.Listener<JSONObject>() 
           @Override
           public void onResponse(JSONObject response) 
               try 
                   VolleyLog.v("Response:%n %s", response.toString(4));
                catch (JSONException e) 
                   e.printStackTrace();
               
           
       , new Response.ErrorListener() 
           @Override
           public void onErrorResponse(VolleyError error) 
               VolleyLog.e("Error: ", error.getMessage());
           
       );

// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);

refer

【讨论】:

【参考方案4】:

创建RequestQueue 类的对象。

RequestQueue queue = Volley.newRequestQueue(this);

创建一个带有响应和错误侦听器的StringRequest

 StringRequest sr = new StringRequest(Request.Method.POST,"http://api.someservice.com/post/comment", new Response.Listener<String>() 
    @Override
    public void onResponse(String response) 
        mPostCommentResponse.requestCompleted();
    
, new Response.ErrorListener() 
    @Override
    public void onErrorResponse(VolleyError error) 
        mPostCommentResponse.requestEndedWithError(error);
    
)
    @Override
    protected Map<String,String> getParams()
        Map<String,String> params = new HashMap<String, String>();
        params.put("user",userAccount.getUsername());
        params.put("pass",userAccount.getPassword());
        params.put("comment", Uri.encode(comment));
        params.put("comment_post_ID",String.valueOf(postId));
        params.put("blogId",String.valueOf(blogId));

        return params;
    

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError 
        Map<String,String> params = new HashMap<String, String>();
        params.put("Content-Type","application/x-www-form-urlencoded");
        return params;
    
;

将您的请求添加到RequestQueue

queue.add(jsObjRequest);

创建PostCommentResponseListener 界面,以便您可以看到它。这是异步请求的简单委托。

public interface PostCommentResponseListener 
public void requestStarted();
public void requestCompleted();
public void requestEndedWithError(VolleyError error);

AndroidManifest.xml 文件中包含 INTERNET 权限。

<uses-permission android:name="android.permission.INTERNET"/>

【讨论】:

不回答问题。 Not 是真正的 json 请求,请求体中没有发送数据。 这很有帮助。 tnx 这是一个 POST 数据请求,而不是 JSON 请求。否决票。根本不回答问题。【参考方案5】:
    final String url = "some/url";

代替:

    final JSONObject jsonBody = "\"type\":\"example\"";

你可以使用:

  JSONObject jsonBody = new JSONObject();
    try 
        jsonBody.put("type", "my type");
     catch (JSONException e) 
        e.printStackTrace();
    
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>()  ... );

【讨论】:

【参考方案6】:

您还可以通过覆盖JsonObjectRequest 类的getBody() 方法来发送数据。如下图。

    @Override
    public byte[] getBody()
    

        JSONObject jsonObject = new JSONObject();
        String body = null;
        try
        
            jsonObject.put("username", "user123");
            jsonObject.put("password", "Pass123");

            body = jsonObject.toString();
         catch (JSONException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        

        try
        
            return body.toString().getBytes("utf-8");
         catch (UnsupportedEncodingException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        return null;
    

【讨论】:

【参考方案7】:
final Map<String,String> params = new HashMap<String,String>();
        params.put("email", customer.getEmail());
        params.put("password", customer.getPassword());
        String url = Constants.BASE_URL+"login";

doWebRequestPost(url, params);


public void doWebRequestPost(String url, final Map<String,String> json)
        getmDialogListener().showDialog();

    StringRequest post = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() 
        @Override
        public void onResponse(String response) 
            try 
                getmDialogListener().dismissDialog();
                response....

             catch (Exception e) 
                e.printStackTrace();
            
        
    , new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 
            Log.d(App.TAG,error.toString());
            getmDialogListener().dismissDialog();

        
    )
        @Override
        protected Map<String, String> getParams() throws AuthFailureError 
            Map<String,String> map = json;

            return map;
        
    ;
    App.getInstance().getRequestQueue().add(post);


【讨论】:

这不会在正文中添加参数作为 JSON 数据【参考方案8】:
protected Map<String, String> getParams() 
   Map<String, String> params = new HashMap<String, String>();

   JSONObject JObj = new JSONObject();

   try 
           JObj.put("Id","1");
           JObj.put("Name", "abc");

    catch (Exception e) 
       e.printStackTrace();
   

   params.put("params", JObj.toString());
   // Map.Entry<String,String>
   Log.d("Parameter", params.toString());
   return params;

【讨论】:

请澄清您的问题 @AlexFilatov 哪个问题?

以上是关于Android进阶:5发送post请求json数据格式以及okhttp框架的使用的主要内容,如果未能解决你的问题,请参考以下文章

从 Android 发送 JSON HTTP POST 请求

如何在 Android 中使用 HTTPClient 以 JSON 格式发送 POST 请求?

Django---进阶8

Django---进阶8

如何在 Android 中使用 Retrofit 发送 JSON POST 请求,并接收字符串响应

如何以 JSON 格式发送 POST 请求?