Retrofit2 POST 方法获取代码 400 但适用于 Restlet 客户端

Posted

技术标签:

【中文标题】Retrofit2 POST 方法获取代码 400 但适用于 Restlet 客户端【英文标题】:Retrofit2 POST method gets code 400 but works with Restlet Client 【发布时间】:2020-01-09 01:47:54 【问题描述】:

我正在使用 Retrofit2。我想从我的移动设备向我的 Web 服务发布一些数据,但总是得到代码 400 响应。当我尝试从 Restlet 客户端发送 POST 请求时,我得到了正常响应 (chrome-extension://aejoelaoggembcahagimdiliamlcdmfm/restlet_client.html#requests)。

我得到一些信息,问题可能出在服务器证书中,所以我实现了 OkHttpClient,但我仍然得到相同的结果。 如果我尝试 POST 到 jsonPlaceHolder,我会得到正常结果 (https://jsonplaceholder.typicode.com/posts)

API 接口:

public interface JsonPlaceHolderApi 

@POST("hws/hibisWsTemplate/api/v1/order/posts")
Call<Post> createPost(@Body Post post);

我的帖子课程:

public class Post 
private String vodilni_slog;
private String IBAN_placnka;
private String polog;
...

public Post(String vodilni_slog, String IBAN_placnka, String polog) 
    this.vodilni_slog = vodilni_slog;
    this.IBAN_placnka = IBAN_placnka;
    this.polog = polog;
    ...


//getters and setters
 ...

主要活动(仅我发送 POST 请求的部分):

...

send_btn.setOnClickListener(new View.OnClickListener()
        @Override
        public void onClick(View v) 

       //RETROFIT
        OkHttpClient okHttpClient = getUnsafeOkHttpClient();

        Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://xxxxxx.x-xx.xx/") //url
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);


         Post post = new Post("test", "test", "test", "test");

         Call<Post> call = jsonPlaceHolderApi.createPost(post);

         call.enqueue(new Callback<Post>() 
                    @Override
                    public void onResponse(Call<Post> call, Response<Post> response) 

                        if (!response.isSuccessful()) 
                            MainActivity.content.setText("Code: " + response.code());
                            return;
                        
                        Post postResponse = response.body();

                        String x = "";
                        x += "Code: " + response.code() + "\n";
                        x += "Naziv: " + postResponse.getIme_prejemnika() + "\n";
                        x += "IBAN: " + postResponse.getIBAN_prejemnika() + "\n";
                        x += "Sklic: " + postResponse.getReferenca_prejemnika() + "\n";

                        MainActivity.content.setText(x); 
                    

                    @Override
                    public void onFailure(Call<Post> call, Throwable t) 
                        MainActivity.content.setText(t.getMessage());
                    
                );
            
    );

OKHTTP 客户端:

private static OkHttpClient getUnsafeOkHttpClient() 
    try            
        final TrustManager[] trustAllCerts = new TrustManager[] 
                new X509TrustManager() 
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException 
                    

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException 
                    

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() 
                        return new java.security.cert.X509Certificate[];
                    
                
        ;

        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
        builder.hostnameVerifier(new HostnameVerifier() 
            @Override
            public boolean verify(String hostname, SSLSession session) 
                return true;
            
        );

        OkHttpClient okHttpClient = builder.build();
        return okHttpClient;
     catch (Exception e) 
        throw new RuntimeException(e);
    

我希望代码 201 带有正文: “vodilni_slog”:“字符串”, "polog": "字符串", “dvig”:“字符串”, ...

但我得到代码 400...

【问题讨论】:

【参考方案1】:

我发现我收到了错误 400,因为 IBAN_placnka 应该是 iban_placnka,所以如果您收到错误 400,请检查您的拼写并使用此行查看您实际获得的 json 格式:

Log.e("x" , "Request is" + new Gson().toJson(post).toString() );

【讨论】:

以上是关于Retrofit2 POST 方法获取代码 400 但适用于 Restlet 客户端的主要内容,如果未能解决你的问题,请参考以下文章

改造 2 POST JSON 对象,响应给出错误代码 400,消息 = nul

Retrofit 2.0 - 如何获取 400 Bad Request 错误的响应正文?

尝试处理通过 POST 方法接收的 JSON 数组 (Retrofit2)

Ajax中post方法400和404的问题

在 Jquery Ajax POST 中获取 400 错误请求错误

retrofit2.0+RxJava结合使用时,怎么才能通过post请求返回一个response对象