2019/07/04 - [프로그램 자료/Java & Spring] - Java 에서 ValidatorException 등 인증서 관련 에러 해결 - keystore에 SSL/TLS 인증서를 import 하기




이번 프로젝트를 하면서 RESTful API 연동을 하게 되었다. 

다른 서버의 API를 호출해야하는데, 

자바는 어떻게 사용하나 알아보니 okhttp3 를 많이 사용하는 것 같아 그걸로 구현하였다. 



<dependency>

<groupId>com.squareup.okhttp3</groupId>

<artifactId>okhttp</artifactId>

<version>3.13.1</version>

</dependency>


우선 maven을 통해 다음을 추가한다. 

일반 java 프로젝트면 해당 파일을 받아서 프로젝트에 추가하면 된다.



메인으로 사용할 helper class를 대략이나마 작성했다. 


import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class ApiHelper {

private static OkHttpClient 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 X509Certificate[0];
}
} };

// 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();

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

} catch (Exception e) {
throw new RuntimeException(e);
}
}

public String callGetUnsafe(String requestURL, Map<String, String> headerAttr) {
String rtn = "";
try {

Headers headerbuild = Headers.of(headerAttr);

OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder().url(requestURL).headers(headerbuild).build();
Response response = client.newCall(request).execute();

rtn = response.body().string();
return rtn;
} catch (Exception e) {
System.err.println(e.toString());
return null;
}
}

public String callGet(String requestURL, Map<String, String> headerAttr) {
String rtn = "";
try {

Headers headerbuild = Headers.of(headerAttr);

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestURL).headers(headerbuild).build();
Response response = client.newCall(request).execute();

rtn = response.body().string();
return rtn;
} catch (Exception e) {
System.err.println(e.toString());
return null;
}
}

public void callGetUnsafeAsync(String requestURL, Map<String, String> headerAttr, Callback callBack) {

try {
Headers headerbuild = Headers.of(headerAttr);
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder().url(requestURL).headers(headerbuild).build();

client.newCall(request).enqueue(callBack);

} catch (Exception e) {
System.err.println(e.toString());
}
}

public void callGetAsync(String requestURL, Map<String, String> headerAttr, Callback callBack) {

try {
Headers headerbuild = Headers.of(headerAttr);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestURL).headers(headerbuild).build();

client.newCall(request).enqueue(callBack);

} catch (Exception e) {
System.err.println(e.toString());
}
}

public String callPostUnsafe(String requestURL, Map<String, String> headerAttr, String jsonMessage) {
String rtn = "";
try {
Headers headerbuild = Headers.of(headerAttr);
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder().url(requestURL)
.post(RequestBody.create(MediaType.parse("application/json"), jsonMessage)).headers(headerbuild)
.build();
Response response = client.newCall(request).execute();

rtn = response.body().string();
return rtn;

} catch (Exception e) {
System.err.println(e.toString());
return null;
}
}

public String callPost(String requestURL, Map<String, String> headerAttr, String jsonMessage) {
String rtn = "";
try {
Headers headerbuild = Headers.of(headerAttr);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestURL)
.post(RequestBody.create(MediaType.parse("application/json"), jsonMessage)).headers(headerbuild)
.build();
Response response = client.newCall(request).execute();

rtn = response.body().string();
return rtn;

} catch (Exception e) {
System.err.println(e.toString());
return null;
}
}

public void callPostUnsafeAsync(String requestURL, Map<String, String> headerAttr, String jsonMessage,
Callback callBack) {

try {
Headers headerbuild = Headers.of(headerAttr);
OkHttpClient client = getUnsafeOkHttpClient();
Request request = new Request.Builder().url(requestURL)
.post(RequestBody.create(MediaType.parse("application/json"), jsonMessage)).headers(headerbuild)
.build();

client.newCall(request).enqueue(callBack);

} catch (Exception e) {
System.err.println(e.toString());
}
}

public void callPostAsync(String requestURL, Map<String, String> headerAttr, String jsonMessage,
Callback callBack) {

try {
Headers headerbuild = Headers.of(headerAttr);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestURL)
.post(RequestBody.create(MediaType.parse("application/json"), jsonMessage)).headers(headerbuild)
.build();

client.newCall(request).enqueue(callBack);

} catch (Exception e) {
System.err.println(e.toString());
}
}

}




대충 다음과 같이 쓸면 될 것 같더라.

비동기 같은 경우엔 콜백에 잘 사용해야 할 것 같다.


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
import org.springframework.test.context.junit4.SpringRunner;

import kr.drsoft.nexon.api.ApiHelper;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

@RunWith(SpringRunner.class)
@SpringBootTest
@Commit
public class CallRestApiTest {

@Test
public void get_sync() {
// 동기
ApiHelper api = new ApiHelper();

Map<String, String> head = new HashMap<String, String>();
head.put("Content-Type", "application/json;charset=utf-8");
head.put("Authorization", "token.....");

String rtn = api.callGet("https://localhost/version", head);
System.out.println(rtn);
}

@Test
public void get_async() {
// 비동기
System.out.println("@@@@@start async");

new Thread() {

@Override
public void run() {
ApiHelper api = new ApiHelper();

Map<String, String> head = new HashMap<String, String>();
head.put("Content-Type", "application/json;charset=utf-8");
head.put("Authorization", "token.....");

api.callGetUnsafeAsync("https://localhost/version", head, callback);
}
}.start();

try {
// 새로운 스레드로 테스트하면 callback 호출되기전에 테스트 종료됨...
Thread.sleep(1000 * 999);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private final Callback callback = new Callback() {
// callback 으로 돌아오면 할일....sample
@Override
public void onFailure(Call call, IOException e) {
System.out.println(e.getStackTrace());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
String rtn = "init";
try {
rtn = response.body().string();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(rtn);
}
};

}



















Posted by motolies

댓글을 달아 주세요