改造 2:即使有也没有请求正文

Posted

技术标签:

【中文标题】改造 2:即使有也没有请求正文【英文标题】:Retrofit 2 : NO Request Body even there is 【发布时间】:2018-06-05 16:13:21 【问题描述】:

你遇到过这个问题吗?我使用改造 2 发出了一个 Post 请求,但请求正文不会提供给服务器。上次我检查提要时它是空的,这就是它无法通过 IF 语句的原因。这是我的代码:

 Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    Retrofit newAccountRetro = new Retrofit.Builder()
            .baseUrl("http://192.168.1.8/waterdistrict/")
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

    RetrofitAPI retroAPI = newAccountRetro.create(RetrofitAPI.class);

我的请求正文:

    NewFormRequest nfr = new NewFormRequest();
    nfr.setFname(fname);
    nfr.setMname(mname);
    nfr.setLname(lname);
    nfr.setUsern(usern);
    nfr.setPs(ps);
    nfr.setContact(contact);
    nfr.setAdd(add);
    nfr.setEmail(email);

    rs = new Presenter(context);
    //TODO:Fix null response of Retrofit

这就是我传递请求正文的方式

   Call<NewFormResponse> nfResponse = retroAPI.newAccount((NewFormRequest) nfr);
    nfResponse.enqueue(new Callback<NewFormResponse>() 
        @Override
        public void onResponse(Call<NewFormResponse> call, Response<NewFormResponse> response) 
            Log.d(getClass().toString(), response.code()+"-"+new Gson().toJson(response.body())
                    +"-"+call.request().toString()+" - "+call.request().headers().toString());
            if(response.code() == 200)
                rs.nfResponse(response.body().getCode(), response.body().getMessage());
                rs.switchProgress();
            
        ;

        @Override
        public void onFailure(Call<NewFormResponse> call, Throwable t) 
            rs.switchProgress();
            Log.d(getClass().toString(), t.toString());

        
    );

端点:

 @POST("addClients.php")
Call<NewFormResponse> newAccount (@Body NewFormRequest newFormRequest);

新表单响应:

public class NewFormResponse 
@SerializedName("code")
@Expose
private Integer code;
@SerializedName("message")
@Expose
private String message;

public Integer getCode() 
    return code;


public void setCode(Integer code) 
    this.code = code;


public String getMessage() 
    return message;


public void setMessage(String message) 
    this.message = message;


newFormRequest 类

public class NewFormRequest 
private String fname;
private String mname;
private String lname;
private String usern;
private String ps;
private String contact;
private String add;
private String email;

public String getFname() 
    return fname;


public void setFname(String fname) 
    this.fname = fname;


public String getMname() 
    return mname;


public void setMname(String mname) 
    this.mname = mname;


public String getLname() 
    return lname;


public void setLname(String lname) 
    this.lname = lname;


public String getUsern() 
    return usern;


public void setUsern(String usern) 
    this.usern = usern;


public String getPs() 
    return ps;


public void setPs(String ps) 
    this.ps = ps;


public String getContact() 
    return contact;


public void setContact(String contact) 
    this.contact = contact;


public String getAdd() 
    return add;


public void setAdd(String add) 
    this.add = add;


public String getEmail() 
    return email;


public void setEmail(String email) 
    this.email = email;

 

PHP 代码

<?php
include "connection.php";

if(mysqli_connect_errno())
    $response["code"] = 0;
    $response["message"] = "failed to connect with the database";
    echo json_encode($response);
 else
        if(isset($_POST['fname'], $_POST['mname'], $_POST['lname'], $_POST['usern'], $_POST['ps'], $_POST['contact'], $_POST['add'], $_POST['email']))
            $fname = $_POST['fname'];
            $mname = $_POST['mname'];
            $lname = $_POST['lname'];
            $contactnum = $_POST['contact'];
            $address = $_POST['add'];
            $email = $_POST['email'];
            $usern = $_POST['usern'];
            $password = $_POST['ps'];
            $approval = 0;

            try
                $conni = new PDO("mysql:host=localhost;dbname=wddatabase","root","");
                $conni->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $sql_insert = "INSERT INTO clients (fname, mname, lname,  uname, password, contact_num, address, email, approved) 
                    VALUES ('$fname', '$mname', '$lname', '$usern', '$password', '$contactnum', '$address', '$email', '$approval')";
                $conni->exec($sql_insert);
                $response['code']= 1;
                $response['message']='New Record Created';
                echo json_encode($response);
            catch(PDOException $e)
                $response['code']= 0;
                $response['message']=$e;
                echo json_encode($response);
            
         else
            $response['code']= 0;
                $response['message']="Error";
                echo json_encode($response);
        


?>

//结果

200-"code":0,"message":"Error"-Requestmethod=POST, url=http://192.168.1.8/waterdistrict/addClients.php, tag=null - 

【问题讨论】:

对不起我的英语不好 我尝试使用邮递员,它成功地提供了请求正文,但是当我尝试在 android 中实现它时,我无法通过 If 语句,因为即使我尝试发出请求也没有任何内容身体和我在邮递员做的一样。 【参考方案1】:

在 php 中,你应该在 echo json 结果之前将 header 设置为 json:

 header('Content-Type: application/json');
 echo $json;

【讨论】:

我可以在 Postman 中进行 Post,但是当我在 Android 上实现它时它就不起作用了。【参考方案2】:

来自Javadocs,用于 Body 注释的改造。

对象将使用 Retrofit 实例 Converter 进行序列化 并将结果直接设置为请求正文。

我会说转换器在将您的 NewFormRequest 类转换为 HTTP 时遇到问题

如果您将 NewFormRequest 类放在 OkHttp3 RequestBody 中,则可以进行转换。

如果您正在使用(或愿意使用)JSON 作为 RequestBody 的 MediaType,这应该可以。

端点:

    @POST("addClients.php")
    Call<NewFormResponse> newAccount (@Body RequestBody newFormRequest);

和调用代码:

    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("myJsonTag", nfr);
    String jsonString = new Gson().toJson(jsonObject);

    RequestBody nfrBody = RequestBody.create(MediaType.parse(CONTENT_JSON), jsonString);

    Call<NewFormResponse> nfResponse = retroAPI.newAccount(nfrBody);
    nfResponse.enqueue(new Callback<NewFormResponse>() ...

【讨论】:

以上是关于改造 2:即使有也没有请求正文的主要内容,如果未能解决你的问题,请参考以下文章

如何在改造请求的正文中发布原始的整个 JSON?

使用基本 HTTP 身份验证改造 POST 请求:“无法重试流式 HTTP 正文”

柱体改造 2 包括大括号

即使我使用 API Post 请求发送数据,为啥 req 正文是 [重复]

Chrome浏览器请求时长“内容下载”时间,没有响应正文

如何在改造 2 中按标签取消请求?