302 Redirect 처리
외부에서 제공하는 API를 사용하다보면 GET요청은 문제가없이 잘동작하는데, http로 된 URL에 POST요청을 할 경우 종종 302상태 코드를 리턴 받게 된다.
처음에는 당황했다. 302리다렉트할꺼면 제공하는 url를 처음부터 https로 주던지…쩝
3xx Redirect
301과 302가 존재하는데, 301 redirect는 기존 URL를 영구적(Permanent)으로 옮겼을 때 사용하고 302 redirect은 URL를 일시적(Temporary)으로 옮겼을 때 발생한다.
301 redirect은 api호출하는 입장에서 크게 수정해야할 부분이 없다. 영구적으로 url이 옮겨졌으니 자동으로 새로운 URL로 연결해준다.
하지만 302 redirect를 받을 경우 이야기는 달라진다. 말그대로 임시 URL이기 때문에 호출하는 쪽에서 새로운 URL로 redirect처리를 해줘야한다.
Apahce httpclient를 사용하자
apahce httpclient 버전을 4.3이상되는 거를 사용해야지 편리하게 사용할 수 있다.
4.3아래 버전에서는 커낵션관리, redirect처리, pool관리 등 defulat값들이 정해져있지 않아 수동으로 해줘야해서 손이 많이간다.
4.2.6버전에서 302redirect를 처리한 post요청 코드이다.
private int sendPooledRequest(String requestBody, String apiURL) throws Exception, ConnectException {
if (cm == null) {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
cm = new PoolingClientConnectionManager(schemeRegistry);
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
}
HttpPost httpPost = new HttpPost(apiURL);
// header
httpPost.setHeader(new BasicHeader("Pragma", "no-cache"));
httpPost.setHeader(new BasicHeader("Cache-Control", "no-cache"));
// body
StringEntity bodyEntity = new StringEntity(requestBody, "application/json", "UTF-8");
httpPost.setEntity(bodyEntity);
HttpClient httpClient = null;
HttpResponse response = null;
int resStatus = -1;
try {
httpClient = new DefaultHttpClient(cm);
response = httpClient.execute(httpPost);
resStatus = response.getStatusLine().getStatusCode();
} catch (ConnectException ce) {
//ce.printStackTrace();
if (httpPost != null) {
httpPost.abort();
}
throw ce;
} catch (IOException ioe) {
//ioe.printStackTrace();
if (httpPost != null) {
httpPost.abort();
}
throw ioe;
} finally {
if (response != null) {
EntityUtils.consume(response.getEntity());
}
}
return resStatus;
}
4.5.3버전에서 302redirect를 처리한 post요청 코드이다.
public int shootRequest(ApiRequestModel apiRequest, String inputUrl) throws IOException {
Gson gson = new Gson();
String requestData = gson.toJson(apiRequest);
HttpPost httpPost = new HttpPost(inputUrl);
httpPost.setHeader(new BasicHeader("Pargma", "no-cache"));
httpPost.setHeader(new BasicHeader("Cache-Control", "no-cache"));
System.out.println("request Data => " + requestData);
StringEntity bodyEntity = new StringEntity(requestData, "application/json", "UTF-8");
httpPost.setEntity(bodyEntity);
CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
CloseableHttpResponse response = httpClient.execute(httpPost);
return response.getStatusLine().getStatusCode();
}
4.5 버전에서는 closeable객체를 사용하고, 거의 대부분의 값들이 default로 셋팅되어 있어 크게 손볼 것이 없다.