package nlib.restful.service.impl;
import java.nio.charset.StandardCharsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
import nlib.restful.service.DataApiInterface;
import nlib.restful.service.DataApiReqVO;
import nlib.restful.service.DataApiResVO;
import nlib.util.StringUtil;
/**
*
* @Class Name : DataApiRESTful.java
*
* @Description : 통합자료관리시스템에 RESTful API를 통해 질의/응답을 처리한다.
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
*
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 6. 22. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 6. 22.
* @version 1.0
*
*/
public class DataApiRESTful implements DataApiInterface {
private static final Logger log = LoggerFactory.getLogger(DataApiRESTful.class);
/* DataApi 접속 서버 정보 */
@Value("#{properties['dataapi.server.ip']}")
private String DAPI_SERVER_IP;
@Value("#{properties['dataapi.server.port']}")
private String DAPI_SERVER_PORT;
@Value("#{properties['dataapi.server.protocol']}")
private String DAPI_SERVER_PROTOCOL;
/**
* 실제 RESTful API 서버로 요청을 전송하고, 응답받은 자료를 응답VO에 담아서 리턴한다.
*
* @param reqVO
* @param method
* @return
*/
public DataApiResVO request(DataApiReqVO reqVO) {
log.debug("request > " + reqVO.getReqMethod());
DataApiResVO resVO = null;
try {
//-----------------------------------
// 입력값 검증작업
//-----------------------------------
resVO = DataApiInterface.checkReqCommonParams(reqVO);
if(resVO != null) return resVO;
HttpMethod method = reqVO.getReqMethod();
//-----------------------------------
// 폼 파라메터 생성 작업 및 요청 처리
//-----------------------------------
String url = DAPI_SERVER_PROTOCOL + "://" + DAPI_SERVER_IP + ("80".equals(DAPI_SERVER_PORT) ? "" : ":" + DAPI_SERVER_PORT) + reqVO.getReqUrl();
log.debug("REQ URL : " + url);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
ResponseEntity responseEntity = null;
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
HttpStatus statusCode = HttpStatus.OK;
String resultXML = null;
if(method == HttpMethod.GET) {
HttpEntity requestEntity = new HttpEntity(headers);
try {
responseEntity = restTemplate.exchange (DataApiInterface.makeRequestParamUrl(url, reqVO), method, requestEntity, String.class);
statusCode = responseEntity.getStatusCode();
resultXML = responseEntity.getBody();
} catch(HttpClientErrorException e) {
log.error("request > HttpClientErrorException 발생 : " + e.toString());
resultXML = e.getResponseBodyAsString();
statusCode = e.getStatusCode();
} catch(HttpServerErrorException e) {
log.error("request > HttpServerErrorException 발생 : " + e.toString());
resultXML = e.getResponseBodyAsString();
statusCode = e.getStatusCode();
}
} else if(method == HttpMethod.POST) {
MultiValueMap parameters = DataApiInterface.makeRequestParamMultiValueMap(reqVO);
parameters.forEach((k, v) -> log.debug("params > " + k + " : " + v));
HttpEntity> requestEntity = new HttpEntity(parameters, headers);
try {
responseEntity = restTemplate.postForEntity(url, requestEntity , String.class);
statusCode = responseEntity.getStatusCode();
resultXML = responseEntity.getBody();
} catch(HttpClientErrorException e) {
log.error("request > HttpClientErrorException 발생 : " + e.toString());
resultXML = e.getResponseBodyAsString();
statusCode = e.getStatusCode();
} catch(HttpServerErrorException e) {
log.error("request > HttpServerErrorException 발생 : " + e.toString());
resultXML = e.getResponseBodyAsString();
statusCode = e.getStatusCode();
}
} else {
String message = "RESTFul API Http Method 설정 오류입니다. : POST, GET 방식만 허용됩니다.";
log.error("request > " + message);
return DataApiInterface.makeErrorRes("E_ERR_METHOD", message);
}
//-----------------------------------
// 응답 처리
//-----------------------------------
log.debug("RES StatusCode : " + statusCode);
log.debug("RES resultXML : " + resultXML);
// 응답 자료 객체화
resVO = DataApiInterface.convertXmlToResVO(resultXML);
// 처리결과 코드 확인
if(StringUtil.isEmpty(resVO.getResultCode())) {
String resultMessage = resVO.getResultMessage();
if (statusCode == HttpStatus.OK) {
resVO.setResultCode("S_HTTP_STATUS_OK");
resVO.setResultMessage(StringUtil.isEmpty(resultMessage) ? "정상처리되었습니다." : resultMessage);
} else {
resVO.setResultCode("E_STATUS_CODE_FAIL");
resVO.setResultMessage(StringUtil.isEmpty(resultMessage) ? String.format("처리에 실패하였습니다. (HTTP상태코드 : %s)", statusCode.toString()) : resultMessage);
}
}
log.debug("RES resVO : resultCode = " + resVO.getResultCode());
log.debug("RES resVO : resultMessage = " + resVO.getResultMessage());
}catch(HttpClientErrorException e) {
log.error("request > HttpClientErrorException 발생 : " + e.toString());
return DataApiInterface.makeErrorRes("E_REQ_HTTPCLIENTERROREXCEPTION", e.toString());
}catch(HttpServerErrorException e) {
log.error("request > HttpServerErrorException 발생 : " + e.toString());
return DataApiInterface.makeErrorRes("E_REQ_HTTPSERVERERROREXCEPTION", e.toString());
} catch(Exception e) {
log.error("request > Exception 발생 : " + e.toString());
return DataApiInterface.makeErrorRes("E_REQ_EXCEPTION", e.toString());
}
return resVO;
}
}