8

I'm trying to use OkHttp library to send post request to API with some url parameters. Following this blog post I have this code so far:

    public String okHttpRequest() throws IOException{

        OkHttpClient client = new OkHttpClient();
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {

                return true;
            }
        });
        HttpUrl.Builder urlBuilder = HttpUrl.parse("myurl").newBuilder();
        urlBuilder.addQueryParameter("username","username");
        urlBuilder.addQueryParameter("password","7777");
        String url = urlBuilder.build().toString();

        Request request = new Request.Builder()
                .url(url)
                .build();

        //HERE EXCEPTION IS THROWN
        Response response = client.newCall(request).execute(); 
        return response.body().string();
}

The exception is:

javax.net.ssl.SSLPeerUnverifiedException: Hostname {domain} not verified:

Alvin
  • 894
  • 8
  • 16

3 Answers3

7

UPDATE

Code for com.squareup.okhttp3:okhttp:3.0.1

mTextView = (TextView) findViewById(R.id.textView);
mHandler = new Handler(Looper.getMainLooper());

final Request request = new Request.Builder()
        .url("https://...")
        .post(formBody)
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, final IOException e) {
        Log.e(LOG_TAG, e.toString());
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                String message = request.toString() + "\r\n" + e.toString();
                mTextView.setText(message);
            }
        });
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        try {
            JSONObject jsonObject = new JSONObject(response.body().string());
            final String message = jsonObject.toString(5);
            Log.i(LOG_TAG, message);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mTextView.setText(message);
                }
            });
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
});

Because your project uses OkHttp v3.0.0-RC1, so to fix that Exception, your code should be as the following sample:

        OkHttpClient client = new OkHttpClient.Builder()
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                })
                .build();

        Request request = new Request.Builder()
                .url("https://...")
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Request request, final IOException e) {
                // do something...
            }

            @Override
            public void onResponse(Response response) throws IOException {
                // do something...
            }
        });

However, instead of return true; above, I suggest that you read Google's documentation about Common Problems with Hostname Verification for more information.

One more useful link is OkHttp's HTTPS wiki.

Hope it helps!

P/S: please note that I use async way of OkHttp (at client.newCall(request).enqueue(new Callback()...), you can also use sync way as your code.

BNK
  • 23,994
  • 8
  • 77
  • 87
  • You are just great @BNK ! Request is now sent to a test url for post request. How can add parameters to request url ? /login?username=alvin&password=2186 etc. – Alvin Jan 10 '16 at 11:56
  • @Alvin for parameters, you can read more at http://stackoverflow.com/questions/30142626/how-to-add-query-parameters-to-a-http-get-request-by-okhttp – BNK Jan 10 '16 at 14:12
  • is there any particular thing for https @BNK ? Because, it fails when I try to request to my url (https), but all is ok with some test url (http://httpbin.org/ip). I'll accept it ;) – Alvin Jan 11 '16 at 07:21
  • your `httpbin...` responses `{ "origin": "118.69.226.223" }`? Is that your url? About failed, what is the error message? – BNK Jan 11 '16 at 07:40
  • I think the problem was with not adding **method()**. Adding that; Request request = new Request.Builder() .url("myPrivateAPIurl") .method("POST", ???? ) .build(); the **method** should take RequestBody instead of question marks @BNK . – Alvin Jan 11 '16 at 07:50
  • For POST request, pls read https://github.com/square/okhttp/wiki/Recipes, many examples – BNK Jan 11 '16 at 07:59
  • What should be the request body ? I think I don't even need that, MediaType things.... I have a url and I have to send a simple post request to that url. No body, no header. What can I do ? @BNK – Alvin Jan 11 '16 at 08:15
  • POST request with no body? Why don't you use GET? – BNK Jan 11 '16 at 08:26
  • I have a url and I have to send a **POST** request with some key-values. (https:://url/login?username=22222&password=3456) That's all what I need. Is the RequestBody those key-value pairs ?? @BNK – Alvin Jan 11 '16 at 08:29
  • `?username=22222&password=3456` are url parameters and will be displayed in address bar, they are not POST body – BNK Jan 11 '16 at 08:34
  • Yes, I also think they are not Body. But How can add parameters to this request? – Alvin Jan 11 '16 at 08:38
  • Try add it to the url and check. For POST without body, can refer to `RequestBody requestBody = new FormEncodingBuilder() .build(); final Request request = new Request.Builder() .url("http://...") .post(requestBody) .build();` – BNK Jan 11 '16 at 08:49
  • As I searched, I think that will be the solution =D But I don't have FormEncodingBuilder class.. @BNK =( – Alvin Jan 11 '16 at 08:52
  • For ver 3, it's replaced with FormBody and FormBody.Builder combo, please read https://github.com/square/okhttp/blob/master/CHANGELOG.md – BNK Jan 11 '16 at 08:57
  • When I use this: RequestBody formBody = new FormBody.Builder() .add("username","22222") .add("password","3456") .build(); Request request = new Request.Builder() .url("myUrl") .post(formBody) .build(); It Fails and the result is: Request{method=POST, url=myUrl, tag=Request{method=POST, url=myUrl, tag=null}} @BNK – Alvin Jan 11 '16 at 09:09
  • When you use that, it's POST body, not query paras, try use `url("https:://url/login?username=22222&password=3456"` for example. I am busy now, we'll discuss later :) – BNK Jan 11 '16 at 09:13
  • In that case it's sending GET request by default, but I need POST. Ok, I'll wait )) =D @BNK – Alvin Jan 11 '16 at 09:41
  • @Alvin: I have just updated code for `com.squareup.okhttp3:okhttp:3.0.1` – BNK Jan 28 '16 at 01:28
0

Apparently you try to connect to a SSL website (https), therefore you need to add a SSLSocketFactory, below little code snippet.

OkHttpClient client = new OkHttpClient();
client.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

For more details see this page or this, it should help you.

If you want to "trust all certificates", see this example but it`s not recommanded and should only be used for testing purposes!

Community
  • 1
  • 1
Simon
  • 1,691
  • 2
  • 13
  • 28
  • @Alvin see my edit but this is only part of the code, pls see the links for more details of SSL implementation. – Simon Jan 08 '16 at 08:19
0

Check SSLSession hostname and your connection host name...

OkHttpClient client = new OkHttpClient();
client.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                    System.out.println("Warning: URL host '" + urlHostName
                            + "' is different to SSLSession host '"
                            + session.getPeerHost() + "'.");
                }
                return true;
            }
        });
nurisezgin
  • 1,530
  • 12
  • 19
  • 1
    why setHostnameVerifier can not be resolved ? @nurisezgin – Alvin Jan 08 '16 at 08:42
  • OkHttpclient api "sethostnameverifier" method prototype in this link https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/OkHttpClient.html – nurisezgin Jan 08 '16 at 09:14