* HttpURLConnection, HttpsURLConnection이란?
클라이언트 프로그램을 URL을 통해서버와 통신할 때 사용하는 클래스로 URLConnection를 상속받는 클래스로 HTTP 기능을 제공한다.
HttpsURLConnection는 SSL 적용된 url에 접근하기 위해 사용
javadoc : https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/HttpsURLConnection.html
* 클래스 구조
java.lang.Object
└ java.net.URLConnection
└ java.net.HttpURLConnection
└ javax.net.ssl.HttpsURLConnection
URLConnection은 리소스(헤더값,바디값..)에 연결하기 전에 구성
URLConnection 인스턴스는 재사용이 될 수 없다.
* URLConnection의 주요 메소드
● boolean getAllowUserInteraction() : 연결 된 곳(해당 서버, 연결 포트)에 Client가 Sever와 통신 할 수 있는 환경 허용여부를 확인한다.
● boolean getDefaultAllowUserInteraction(): 통신 대상(Client, Server...)과 통신 가능한 상태인지 확인한다.
● abstract void connect() : 해당 url에 연결 된 곳에 접속 할때 사용한다. false인 경우, 연결 객체는 지정된 URL로의 통신 링크를 작성하고 true인 경우엔 통신 링크가 설정되이 있다.
● void setDoInput(true) :
- URLConnection에 대한 doInput 필드값을 지정된 값으로 설정한다. URL 연결은 입출력에 사용될 수 있다. true로 설정시 서버통신에서 입력 가능한 상태로 설정 한다.(응답 헤더와 메시지 등을 Read) (default : true)
● void setDoOutput(false) :
- URLConnection에 대한 doOutput 필드값을 지정된 값으로 설정한다. true로 설정시 서버통신에서 출력 가능한 상태로 설정 한다.(outputstream으로 데이터 처리 등) (default : false)
● void getDoInput() : Server에서 온 데이터를 입력 받을 수 있는 상태인지 여부를 확인한다.(default : true)
● void getDoOutput(): Server에서 온 데이터를 출력 할수 있는 상태인지 여부를 확인한다.(default : false)
● void useCaches(true) : 프로토콜은 가능할 때마다 캐싱을 사용할 수 있다. 즉 이전에 다운로드 받은 데이터를 사용할지에대한 여부. DefaultUseCaches에서 가져 오며 기본값은 true이다.
참조 : https://goddaehee.tistory.com/268
예제 코드
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class HttpConnection {
public static void main(String args[]){
String connection = getPost();
//System.out.println("connection : "+connection);
}
/** URL Connection SSL ignore **/
public static TrustManager[] createTrustManagers() {
TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() {
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) { }
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) { }
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; }
}};
return trustAllCerts;
}
public static String getPost(){
//HttpURLConnection conn = null;
HttpsURLConnection conn = null;
try {
// SSL ignore 설정
/* SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, createTrustManagers(), new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = (hostname, session) -> true;
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);*/
//URL url = new URL("https://www.naver.com/");
URL url = new URL("https://installer-whale.pstatic.net/downloads/banner/RydDy7/WhaleSetup.exe");
//conn = (HttpURLConnection) url.openConnection();
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","x-www-form-urlencoded");
conn.setRequestProperty("client-id","abc_id");
// 요청 헤더의 정보를 모두 출력
/* for (Map.Entry<String, List<String>> header : conn.getRequestProperties().entrySet()) {
for (String value : header.getValue()) {
System.out.println("request header : "+header.getKey() + " : " + value);
}
}*/
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
StringBuffer sb = new StringBuffer();
sb.append("id=tom");
sb.append("&pw=123");
System.out.println("param : "+sb.toString());
os.write(sb.toString().getBytes("UTF-8"));
os.flush();
if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK){
return null;
}else{
// 응답 헤더의 정보를 모두 출력
/* for (Map.Entry<String, List<String>> header : conn.getHeaderFields().entrySet()) {
for (String value : header.getValue()) {
System.out.println("response header : "+header.getKey() + " : " + value);
}
}*/
InputStream is = conn.getInputStream();
//BufferedReader read = new BufferedReader(new InputStreamReader(is,"UTF-8"));
// buffer 설정
int bytesRead = -1;
byte[] buffer = new byte[4096];
/* String line ;
String page="";
int i=0;
while ((line = read.readLine())!=null){
page +=line;
page+="\n";
}
int start = page.indexOf("<ul class=\"list_nav type_fix\">");
int end = page.indexOf("class=\"list_nav NM_FAVORITE_LIST\"")-4;*/
FileOutputStream outputStream = new FileOutputStream("/Users/janghyojeroot/Desktop/WhaleSetup.exe");
// download
while ((bytesRead = is.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return null;
}
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally{
if(conn !=null){
conn.disconnect();
}
}
}
}
참조 : https://develop-is-reality.tistory.com/28
* HTTP 와 HTTPS 차이
: 암호화 여부
HTTP는 Client와 Server사이에 이루어지는 요청request/응답response 프로토콜이다. 암호화 되지 않은 방법으로 데이털을 전송
HTTPS는 소켓 통신에서 일반 텍스트를 이용하는 대신에, SSL이나 TLS 프로토콜을 통해 세션 데이터를 암호화 한다. 네트워크에서 HTTP Layer 전에 SSL 보안 계층을 제공
SSL(Secure Socket Layer)은 암호화 기반 인터넷 보안 프로토콜
* SSL 세팅
// Set Hostname verification
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
// Ignore host name verification. It always returns true.
System.out.println("hostname : "+hostname);
return true;
}
};
conn.setHostnameVerifier(hostnameVerifier);
// SSL setting
SSLContext context = SSLContext.getInstance("SSL");
context.init(null, null, null); // No validation for now
conn.setSSLSocketFactory(context.getSocketFactory());
// Connect to host
conn.connect();
conn.setInstanceFollowRedirects(true);
* HttpsURLConnection 사용시 발생하는 Exception 문제 - SSLHandshakeException
원인
1. SSL 인증서가 신뢰하는 기관 인증서가 없거나 SSL/TLS암호화 버전이 맞지 않는 경우
2. 연결하려는 서버의 인증서가 신뢰하는 인증기관 인증서 목록(keystore)에 없을 경우(=사설 인증서)
3. 서버/클라이언트 사이에 사용하려는 TLS 버전이 맞지 않을 때
* 인증서 우회하여 SSL인증 무시하는 경우
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType){
}
public void checkServerTrusted(X509Certificate[] certs, String authType){
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
SSL 원리/CA 검증
참고 : https://wayhome25.github.io/cs/2018/03/11/ssl-https/
https://blog.itcode.dev/posts/2021/08/18/about-ssl
'Spring > 1-4. API' 카테고리의 다른 글
Spring RestTemplate (1) | 2022.11.25 |
---|