Retrofit 2 从 android 客户端空请求正文发送到 spring 在具有 200 状态的服务器中启动,而在邮递员中它工作正常

Retrofit 2 sending from android client empty request body to spring boot in server with 200 status whereas in postman it works fine

我一直在努力从 android 客户端向服务器发送一个带有一个参数的请求正文,成功时状态为 200,但请求正文为空。它在邮递员中一切正常,交易成功。

API 下面是我调用的

@POST("user/loginwithotp")
@Headers({
        "Content-Type: application/json;charset=UTF-8"
})
Call<ResponseAPI> saveMobile(@Body AuthenticationVO authenticationVO);

下面是retrofit client的代码

                     public static Retrofit getClient() {
        String baseUrl = "http://192.168.xx.xx:8080/dmp/";


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

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new   OkHttpClient.Builder().addInterceptor(interceptor).build();

      Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl) //if all api base url is same only add here. If not same then add url as string in “getClient()” method and then pass that here
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();
        return retrofit;
    }

 public static VuAPIServices geVuAPIServices() {
        VuAPIServices vuAPIServices = getClient().create(VuAPIServices.class);
        return vuAPIServices;
    }

}

Activity 下面的代码

    public AuthenticationVO createRequest(){
        customLoader.show();
      AuthenticationVO authenticationVO = new AuthenticationVO ();
          authenticationVO.setMobileNumber(mobileNumber);
        return authenticationVO;

    }
    public void saveMobile(AuthenticationVO authenticationVO){

        Call<ResponseAPI> responseAPICall = ApiClient.geVuAPIServices().saveMobile (authenticationVO);
        responseAPICall.enqueue(new Callback<ResponseAPI>() {
            @Override
            public void onResponse(Call<ResponseAPI> call, retrofit2.Response<ResponseAPI> response) {
                customLoader.dismiss();
                if (response.isSuccessful()) {
                    Log.d("response", "code = " + response.code());
                    Log.d("response", "code = " + response.body());

//                    sessionManager.setLogin(true);
//                    sessionManager.setLoginMobile(mobileNumber);
//                    Intent home = new Intent(getApplicationContext(), VU_OTPHandler.class);
//                    home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
//                    startActivity(home);
//                    finish();
                } else {
                    Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show();
         }
                Toast.makeText(VuLogin.this, "saved successfully", Toast.LENGTH_LONG).show();
            }
            @Override
            public void onFailure(Call<ResponseAPI> call, Throwable t) {
                Toast.makeText(VuLogin.this, "Request Failed "+t.getLocalizedMessage(), Toast.LENGTH_LONG).show();

            }
        });

邮差图片

这是我在服务器端写的下面的控制器

 @PostMapping(path = ENDPOINT_MOBILE_OTP)
    public AuthenticationVO signInWithOTP(@Valid @RequestBody AuthenticationVO authenticationVO){
        System.out.println("login request is:-"+authenticationVO.toString());
        try {
        if (authenticationVO != null && authenticationVO.getMobileNumber()!=null) {
            MultitenantUtility.request = httpRequest;
            String tenantId = multitenantUtility.resolveCurrentTenantIdentifier();
            if (tenantId != null) {
                multitenantUtility.setCurrentTenant(tenantId);
                authenticationVO = userService.checkLoginCredentialsWithOTP(authenticationVO);
            } else {
                System.out.println("request body is empty");
                //throw new DMPBadRequestException("Request body is empty");
            }
            }
        else {
            System.out.println("Mobile Number is mandatory");
            //throw new DMPBadRequestException("Request body is empty");
        }
        }
        catch(Exception e) 
        {
            System.out.println("Excepton "+e);
        }
        finally
        {
            multitenantUtility.clearThreadLocal();
            LOGGER.info("authenticateUser - before returning");
        }
        
        
        return authenticationVO;
    }

请大家帮我解决这个问题。几天来,我一直在努力让它发挥作用,我尝试了很多方法,但都没有奏效。请帮我知道我错过了什么。提前致谢

试试这个...

替换下行

Call<ResponseAPI> saveMobile(@Body AuthenticationVO authenticationVO);

Call<ResponseAPI> saveMobile(@Body RequestBody jsonObject);

下面一行也需要修改

        Call<ResponseAPI> responseAPICall = ApiClient.geVuAPIServices().saveMobile (authenticationVO);

try {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("mobileNumber", 0123456789);
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), (jsonObject.toString()));

    }catch (Exception e){
        e.printStackTrace();
    }
  Call<ResponseAPI> responseAPICall = ApiClient.geVuAPIServices().saveMobile (body);
  //now continue as your code
  responseAPICall.enque.....

也尝试用这个改变改造客户端

public static Retrofit getClient(String baseUrl) {

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

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new   OkHttpClient.Builder().addInterceptor(interceptor).build();

    retrofit = new Retrofit.Builder()
            .baseUrl(baseUrl) //if all api base url is same only add here. If not same then add url as string in “getClient()” method and then pass that here
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(client)
            .build();
    return retrofit;
}

希望这会奏效

我通过在拦截中添加主机解决了问题headers,整个问题都解决了。

特别感谢@pratik vekariya 的努力

使用:

        @RequestMapping(
                value = "/",
                method = RequestMethod.POST,
                produces = "application/json"
        )

而不是@PostMapping("/")

这样就可以了