Search code examples
androidpostretrofit2http-status-code-500

Retrofit 2 login post request returns 500 but works well on postman


I'm implementing a login post method using retrofit 2. It works well in Postman but returns 500 error. I've tried different solutions and the ones searched in StackOverFlow didn't worked for me, so here is my implementation:

INetworkAPI interface:

   @FormUrlEncoded
   @POST("mobile/login")
   Call<JsonObject> login(@Field(value = "_username") String username, @Field(value = "_password") String password); 

INetworkAPI interface:

login

 public void login(String _username, String _password, final NetworkRequestObjectResult callBackResult) {


         mRoomPresenceAPI = provideApiService();

    Call<JsonObject> callObject = mRoomPresenceAPI.login(_username, _password);
    callObject.enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {

          if (response.body() != null && response.code() == 200) {
                Log.i(TAG, "mobile/login Success code: "+response.code() + " content: "+response.body().toString());
                callBackResult.onSuccess(null);

            } else {
                if (response.errorBody() != null) {
                    Log.e(TAG, "mobile/login error code: "+response.code() + " error content: "+response.errorBody().toString());
                    //general error
                    callBackResult.onError(mContext.getResources().getString(R.string.error_login));
                }
            }


        }

        @Override
        public void onFailure(Call<JsonObject> call, Throwable t) {
            Log.e(TAG, "mobile/login error : "+t.getMessage());
            callBackResult.onError(mContext.getResources().getString(R.string.error_login));
        }
    });

}

provide service

  public INetworkAPI provideApiService() {
    return provideRetrofit(BASE_URL, provideClient()).create(INetworkAPI.class);
   }

   //provide client
   public OkHttpClient provideClient() {

    loadSSLConfig();

    OkHttpClient.Builder clientBuilder = getUnsafeOkHttpClient();
    clientBuilder.addInterceptor(new ResponseInterceptor());

    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    clientBuilder.addInterceptor(loggingInterceptor);


    return clientBuilder.build();
}


class ResponseInterceptor implements Interceptor {
    @Override
    public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
        okhttp3.Response response = chain.proceed(chain.request());
        return response.newBuilder()

    }
}






private void loadSSLConfig() {
    try {
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

        InputStream inputStream = mContext.getApplicationContext().getAssets().open("roompresencecom_cert.crt");

                //new BufferedInputStream(new FileInputStream("roompresencecom_cert.crt"));
               // mContext.getResources().openRawResource(R.raw.roompresencecom_cert);
        Certificate certificate = certificateFactory.generateCertificate(inputStream);
        inputStream.close();

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", certificate);

        // Create a TrustManager that trusts the CAs in our KeyStore.
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
        trustManagerFactory.init(keyStore);

        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        x509TrustManager = (X509TrustManager) trustManagers[0];

        // Create an SSLSocketFactory that uses our TrustManager
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
        sslSocketFactory = sslContext.getSocketFactory();


    } catch (Exception ex) {
        ex.printStackTrace();
    }


}


public static OkHttpClient.Builder getUnsafeOkHttpClient() {
    try {
        // Create a trust manager that does not validate certificate chains
        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[]{};
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        // Create an ssl socket factory with our all-trusting manager
        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;
            }
        });
        return builder;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

provide retrofit public Retrofit provideRetrofit(String baseURL, OkHttpClient client) {

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


    return new Retrofit.Builder()
            .baseUrl(baseURL)
            .client(client)
           .addConverterFactory(ScalarsConverterFactory.create())
           .addConverterFactory(GsonConverterFactory.create(gson))
            .build();
}

base URL public final String BASE_URL = "https://sandbox.roompresence.com/";

       [Postman][1]

Solution

  • Problem solved (server problem). One particular note: in the API this request was redirecting internally to the request for the web login, this redirecting was performing well from POstman and IOS but not coming from Android (my coworkers who developed the web version have detected this with Fiddler). This request also did not belong to the mobile API that I was using, so the problem might be there.

    The solution was to add a new login request to the mobile API and voilà, it worked.

    Retrofit request:

     @POST("mobile/login")
     Call<JsonObject> login(@Body Map<String,String> parameters);