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[] chainString authType)
                        throws CertificateException {
                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] chainString 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 hostnameSSLSession session) {
                            return true;
                        }
                    }).build();

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

    public String callGetUnsafe(String requestURLMap<StringStringheaderAttr) {
        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 requestURLMap<StringStringheaderAttr) {
        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 requestURLMap<StringStringheaderAttrCallback 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 requestURLMap<StringStringheaderAttrCallback 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 requestURLMap<StringStringheaderAttrString 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 callPostUrlencodedUnsafe(String requestURLMap<String,Stringparam) {
        String rtn = "";
        try {
            OkHttpClient client = getUnsafeOkHttpClient();

            RequestBody requestBody = makeBuilderFromMap(param)
                    .build();
            
            Request request = new Request.Builder()
                    .header("Content-Type""application/x-www-form-urlencoded")
                    .url(requestURL)
                    .post(requestBody)
                    .build();
            
            Response response = client.newCall(request).execute();

            return response.body().string();

        } catch (Exception e) {
            log.debug(requestURL);
            log.debug(e.getMessage(), e);
            return null;
        }
    }
    
    private FormBody.Builder makeBuilderFromMap(final Map<StringStringmap) {
        FormBody.Builder formBody = new FormBody.Builder();
        for (final Map.Entry<StringStringentrySet : map.entrySet()) {
            formBody.add(entrySet.getKey(), entrySet.getValue());
        }
        return formBody;
    }

    public String callPost(String requestURLMap<StringStringheaderAttrString 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 requestURLMap<StringStringheaderAttrString 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 requestURLMap<StringStringheaderAttrString 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
,