通过 POST 将 JSON 格式的求职申请发送到 REST API:获取 SSL 异常
Sending a JSON formatted job application to a REST API via POST: getting an SSL exception
上下文:
我想向公司提交工作申请,相关说明已发布在此处 ("Apply via our REST API"):
https://3sidedcube.com/contact/join-us
我做了什么:
我写了一个简单的应用程序来发送应用程序,它使用 "Android Asynchronous HTTP Client" 库来完成大部分工作:http://loopj.com/android-async-http/
这是应用程序的代码:
主要活动:
package jobsrc;
import java.io.UnsupportedEncodingException;
import org.apache.http.Header;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.jobapp.R;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.loopj.android.http.*;
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
Button b = (Button) findViewById(R.id.btnSend);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sendRequest();
}
});
}
private void sendRequest() {
final String TAG = "jobApp";
Log.i(TAG, "Sending post..");
AsyncHttpClient client = new AsyncHttpClient();
JSONObject params = new JSONObject();
// //fill params here..
try {
params.put("name", "TEST");
params.put("email", "TEST");
params.put("message", "TEST");
params.put("cv-link", "TEST");
params.put("github-profile", "TEST");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
StringEntity se = null;
try{
se = new StringEntity(params.toString());
}catch(UnsupportedEncodingException e){
}
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
//DEBUG
//requestbin test: ("http://requestb.in/18jj7lk1?inspect" to see result)
//client.post(null, "http://requestb.in/18jj7lk1", se, "application/json", new JsonHttpResponseHandler(){
//submission URL: transmission fails with error:
// "javax.net.ssl.SSLException: hostname in certificate didn't match: <3sidedcube.com> != <*.cubeapis.com> OR <*.cubeapis.com> OR <cubeapis.com>"
client.post(null, "https://3sidedcube.com/api/jobs", se, "application/json", new JsonHttpResponseHandler(){
@Override
public void onSuccess(int statusCode, Header[] headers,
JSONArray response) {
Log.i(TAG, "Success: array");
Log.i(TAG, response.toString());
super.onSuccess(statusCode, headers, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers,
JSONObject response) {
Log.i(TAG, "Success: object");
Log.i(TAG, response.toString());
super.onSuccess(statusCode, headers, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers,
String responseString) {
Log.i(TAG, "Success: string");
Log.i(TAG, responseString);
super.onSuccess(statusCode, headers, responseString);
}
@Override
public void onFailure(int statusCode, Header[] headers,
String responseString, Throwable throwable) {
// TODO Auto-generated method stub
super.onFailure(statusCode, headers, responseString, throwable);
}
@Override
public void onFailure(int statusCode, Header[] headers,
Throwable throwable, JSONArray errorResponse) {
// TODO Auto-generated method stub
super.onFailure(statusCode, headers, throwable, errorResponse);
}
@Override
public void onFailure(int statusCode, Header[] headers,
Throwable throwable, JSONObject errorResponse) {
// TODO Auto-generated method stub
super.onFailure(statusCode, headers, throwable, errorResponse);
}
});
}
}
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Send.." />
</RelativeLayout>
问题:
当我 运行 我的代码时,我收到一个 onFailure 响应,它正在接收一个 SSL 异常,调试将异常显示为:
"javax.net.ssl.SSLException: hostname in certificate didn't match: <3sidedcube.com> != <*.cubeapis.com> OR <*.cubeapis.com> OR <cubeapis.com>"
我需要知道的:
这是我的错,还是他们的错?我不是这方面的专家,所以我很可能在做一些愚蠢的事情!
我使用 RequestBin ("http://requestb.in/18jj7lk1?inspect") 测试了我的 POST 请求,似乎 ECHO 正确且准确,所以我觉得这可能是他们方面的问题?
无论如何,如果是我的错,我会改正我的做法,如果是他们的错,我会发邮件给他们解释一下。
让我知道你的想法,谢谢你的帮助!
要么 3sidedcube.com 需要用准确的域 (CN) 修复他们的证书,要么您需要禁用主机名验证。您可以使用下面给出的代码绕过验证。
....
KeyStore trustStore=KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null,null);
SSLSocketFactory socketFactory=new InsecureSSLSocketFactory(trustStore);
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
client.setSSLSocketFactory(socketFactory);
client.post(null, "https://3sidedcube.com/api/jobs", se, "application/json", new JsonHttpResponseHandler(){
.....
我是 3 Sided Cube 的开发人员之一。感谢您发现我们在 API 中故意犯下的错误 ;-)
如果您现在在 https://3sidedcube.com/api/job 尝试您的请求,您应该会得到更有帮助的回复。
祝你好运!
上下文:
我想向公司提交工作申请,相关说明已发布在此处 ("Apply via our REST API"): https://3sidedcube.com/contact/join-us
我做了什么:
我写了一个简单的应用程序来发送应用程序,它使用 "Android Asynchronous HTTP Client" 库来完成大部分工作:http://loopj.com/android-async-http/
这是应用程序的代码:
主要活动:
package jobsrc;
import java.io.UnsupportedEncodingException;
import org.apache.http.Header;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.jobapp.R;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.loopj.android.http.*;
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
Button b = (Button) findViewById(R.id.btnSend);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sendRequest();
}
});
}
private void sendRequest() {
final String TAG = "jobApp";
Log.i(TAG, "Sending post..");
AsyncHttpClient client = new AsyncHttpClient();
JSONObject params = new JSONObject();
// //fill params here..
try {
params.put("name", "TEST");
params.put("email", "TEST");
params.put("message", "TEST");
params.put("cv-link", "TEST");
params.put("github-profile", "TEST");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
StringEntity se = null;
try{
se = new StringEntity(params.toString());
}catch(UnsupportedEncodingException e){
}
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
//DEBUG
//requestbin test: ("http://requestb.in/18jj7lk1?inspect" to see result)
//client.post(null, "http://requestb.in/18jj7lk1", se, "application/json", new JsonHttpResponseHandler(){
//submission URL: transmission fails with error:
// "javax.net.ssl.SSLException: hostname in certificate didn't match: <3sidedcube.com> != <*.cubeapis.com> OR <*.cubeapis.com> OR <cubeapis.com>"
client.post(null, "https://3sidedcube.com/api/jobs", se, "application/json", new JsonHttpResponseHandler(){
@Override
public void onSuccess(int statusCode, Header[] headers,
JSONArray response) {
Log.i(TAG, "Success: array");
Log.i(TAG, response.toString());
super.onSuccess(statusCode, headers, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers,
JSONObject response) {
Log.i(TAG, "Success: object");
Log.i(TAG, response.toString());
super.onSuccess(statusCode, headers, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers,
String responseString) {
Log.i(TAG, "Success: string");
Log.i(TAG, responseString);
super.onSuccess(statusCode, headers, responseString);
}
@Override
public void onFailure(int statusCode, Header[] headers,
String responseString, Throwable throwable) {
// TODO Auto-generated method stub
super.onFailure(statusCode, headers, responseString, throwable);
}
@Override
public void onFailure(int statusCode, Header[] headers,
Throwable throwable, JSONArray errorResponse) {
// TODO Auto-generated method stub
super.onFailure(statusCode, headers, throwable, errorResponse);
}
@Override
public void onFailure(int statusCode, Header[] headers,
Throwable throwable, JSONObject errorResponse) {
// TODO Auto-generated method stub
super.onFailure(statusCode, headers, throwable, errorResponse);
}
});
}
}
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Send.." />
</RelativeLayout>
问题:
当我 运行 我的代码时,我收到一个 onFailure 响应,它正在接收一个 SSL 异常,调试将异常显示为:
"javax.net.ssl.SSLException: hostname in certificate didn't match: <3sidedcube.com> != <*.cubeapis.com> OR <*.cubeapis.com> OR <cubeapis.com>"
我需要知道的:
这是我的错,还是他们的错?我不是这方面的专家,所以我很可能在做一些愚蠢的事情!
我使用 RequestBin ("http://requestb.in/18jj7lk1?inspect") 测试了我的 POST 请求,似乎 ECHO 正确且准确,所以我觉得这可能是他们方面的问题?
无论如何,如果是我的错,我会改正我的做法,如果是他们的错,我会发邮件给他们解释一下。
让我知道你的想法,谢谢你的帮助!
要么 3sidedcube.com 需要用准确的域 (CN) 修复他们的证书,要么您需要禁用主机名验证。您可以使用下面给出的代码绕过验证。
....
KeyStore trustStore=KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null,null);
SSLSocketFactory socketFactory=new InsecureSSLSocketFactory(trustStore);
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
client.setSSLSocketFactory(socketFactory);
client.post(null, "https://3sidedcube.com/api/jobs", se, "application/json", new JsonHttpResponseHandler(){
.....
我是 3 Sided Cube 的开发人员之一。感谢您发现我们在 API 中故意犯下的错误 ;-)
如果您现在在 https://3sidedcube.com/api/job 尝试您的请求,您应该会得到更有帮助的回复。
祝你好运!