Language/JAVA
[JAVA] HttpUtil
yjkim_97
2021. 12. 19. 19:22
[2021.12.15]
이 포스트는 아래 게시글에서 파생된다. Spring RestTemplate 통신할때 사용되는 유틸리티이다.
2021.12.19 - [IT story/Spring] - [Spring] RestTemplate - Java에서 HTTP 통신
특수한 도메인에서 path param, query param, request body 파라미터를 생성하는 유틸리티이다.
구현 로직중에서 Exception은 소스를 올리기 위해 수정한 것이다. 실제로는 커스텀한 exception을 내렸다.
HttpUtil.java
@Slf4j
public class HttpUtil
{
public static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z0-9_:.-]+\\}");
public static Map<String, String> listHttpParamToMap(List<TbHttpParam> params)
{
if(ObjectUtils.isEmpty(params))
{
return null;
}
Map<String,String> keyvalueMap = params.stream()
.collect(Collectors.toMap(TbHttpParam::getKey, TbHttpParam::getVal));
return keyvalueMap;
}
public static Map<String, String> listHttpParamToMap(List<TbHttpParam> params, PARAM_TYPE paramType)
{
if(ObjectUtils.isEmpty(params) || paramType == null)
{
return null;
}
Map<String,String> keyvalueMap = params.stream()
.filter(m -> m.getParamTypeCd() == paramType)
.collect(Collectors.toMap(TbHttpParam::getKey, TbHttpParam::getVal));
return keyvalueMap;
}
/**
* convert {@link TbHttpParam} to path param
*
* @param uri
* @param params
* @return
*/
public static String convertPathParams(String uri, List<TbHttpParam> params)
{
if(StringUtils.isEmpty(uri))
{
return "";
}
if(ObjectUtils.isEmpty(params))
{
return uri;
}
return HttpUtil.convertPathParams(uri, HttpUtil.listHttpParamToMap(params, PARAM_TYPE.PathParam));
}
private static String convertPathParams(String uri, Map<String,String> params)
{
if(ObjectUtils.isEmpty(params))
{
return uri;
}
Matcher matcher = PATH_PARAM_PATTERN.matcher(uri);
StringBuffer sb = new StringBuffer();
while (matcher.find())
{
String group = matcher.group();
int len = group.length();
String key = group.substring(1,len-1);
if(params.containsKey(key))
{
matcher.appendReplacement(sb, params.get(key));
}
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* convert {@link TbHttpParam} to query param
*
* @param uri
* @param params
* @return
*/
public static String convertQueryParams(String uri, List<TbHttpParam> params)
{
if(StringUtils.isEmpty(uri))
{
return "";
}
if(ObjectUtils.isEmpty(params))
{
return uri;
}
Map<String, String> keyvalueMap = HttpUtil.listHttpParamToMap(params, PARAM_TYPE.QueryParam);
String queryString = HttpUtil.paramToQueryString(keyvalueMap);
StringBuffer sb = new StringBuffer();
sb.append(uri.replace("?", ""));
if(StringUtils.isNotBlank(queryString))
{
sb.append("?");
sb.append(queryString);
}
return sb.toString();
}
public static String paramToQueryString(Map<String, String> paramMap){
if(ObjectUtils.isEmpty(paramMap))
{
return null;
}
List<NameValuePair> params = Lists.newArrayList();
if(paramMap != null){
for(Entry<String, String> paramEntry : paramMap.entrySet()){
String value = paramEntry.getValue();
if(value != null){
params.add(new BasicNameValuePair(paramEntry.getKey(), value.toString()));
}
}
}
return URLEncodedUtils.format(params, "UTF-8");
}
/**
* convert {@link TbHttpParam} to request body
*
* @param listParams
* @return
*/
public static Map<String, Object> convertBodyParams(List<TbHttpParam> listParams)
{
if(ObjectUtils.isEmpty(listParams))
{
return null;
}
List<TbHttpParam> listBodyParams = listParams.stream()
.filter(item -> item.getParamTypeCd() == PARAM_TYPE.ReqBody)
.collect(Collectors.toList());
if(ObjectUtils.isEmpty(listBodyParams))
{
return null;
}
List<TbHttpParam> listRootParam = listBodyParams.stream()
.filter(item -> ObjectUtils.isEmpty(item.getParamPsid()))
.collect(Collectors.toList());
if(ObjectUtils.isEmpty(listRootParam))
{
throw new Exception("httpParam에서 루트 파라미터가 존재하지 않습니다.");
}
Map<String, Object> mapRoot = new HashMap<>();
List<Long> listCompleteSid = new ArrayList<>();
try
{
for(TbHttpParam param : listRootParam)
{
listCompleteSid.add(param.getParamSid());
DATA_TYPE myDataType = param.getDataTypeCd();
Object myValue = param.getVal();
// 내 자식이 존재
if(myDataType == DATA_TYPE.Json || myDataType == DATA_TYPE.List)
{
myValue = (myDataType == DATA_TYPE.Json) ? new HashMap<>() : new ArrayList<>();
HttpUtil.convertBodyChlidParams(myValue, param, listBodyParams, listCompleteSid);
}
HttpUtil.putValueByDataType(mapRoot, param.getKey(),myValue,param.getDataTypeCd());
}
}
catch (NumberFormatException | ClassCastException ex)
{
log.error(ex.getMessage(), ex);
throw new Exception("데이터 변환 도중 오류가 발생했습니다. " + ex.getMessage());
}
catch (Exception ex)
{
log.error(ex.getMessage(), ex);
throw new Exception("작업도중 오류가 발생했습니다. " + ex.getMessage());
}
return mapRoot;
}
private static void convertBodyChlidParams(Object objParent, TbHttpParam parentParam, List<TbHttpParam> listBodyParam, List<Long> listCompleteSid)
throws NumberFormatException, ClassCastException
{
List<TbHttpParam> listTargetParam = listBodyParam.stream()
.filter(item -> item.getParamPsid() != null && item.getParamPsid().equals(parentParam.getParamSid()))
.collect(Collectors.toList());
if(ObjectUtils.isEmpty(listTargetParam))
{
return;
}
DATA_TYPE parentDataType = parentParam.getDataTypeCd();
for(TbHttpParam param : listTargetParam)
{
if(listCompleteSid.contains(param.getParamSid()))
{
continue;
}
listCompleteSid.add(param.getParamSid());
DATA_TYPE myDataType = param.getDataTypeCd();
Object myValue = param.getVal();
// 내 자식이 존재
if(myDataType == DATA_TYPE.Json || myDataType == DATA_TYPE.List)
{
myValue = (myDataType == DATA_TYPE.Json) ? new HashMap<>() : new ArrayList<>();
HttpUtil.convertBodyChlidParams(myValue, param, listBodyParam, listCompleteSid);
}
// 부모에게 내 데이터 세팅
if(parentDataType == DATA_TYPE.Json)
{
HttpUtil.putValueByDataType((Map) objParent, param.getKey(), myValue, myDataType);
}
else if(parentDataType == DATA_TYPE.List)
{
HttpUtil.addValueByDataType((List) objParent, myValue, myDataType);
}
}
}
private static void putValueByDataType(Map<String, Object> map, String key, Object value, DATA_TYPE dataType)
throws NumberFormatException
{
if(StringUtils.isBlank(key))
{
return;
}
if(value == null)
{
map.put(key, null);
return;
}
if(!map.containsKey(key))
{
if(dataType == DATA_TYPE.String)
{
map.put(key, String.valueOf(value));
}
else if(dataType == DATA_TYPE.Integer)
{
map.put(key, Integer.parseInt(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Long)
{
map.put(key, Long.parseLong(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Float)
{
map.put(key, Float.parseFloat(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Decimal)
{
map.put(key, BigDecimal.valueOf(Long.parseLong(String.valueOf(value))));
}
else if(dataType == DATA_TYPE.Boolean)
{
map.put(key, Boolean.parseBoolean(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Json)
{
map.put(key, value);
}
else if(dataType == DATA_TYPE.List)
{
map.put(key, value);
}
}
}
private static void addValueByDataType(List<Object> map, Object value, DATA_TYPE dataType)
{
if(value == null)
{
map.add(null);
return;
}
if(dataType == DATA_TYPE.String)
{
map.add(String.valueOf(value));
}
else if(dataType == DATA_TYPE.Integer)
{
map.add(Integer.parseInt(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Long)
{
map.add(Long.parseLong(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Float)
{
map.add(Float.parseFloat(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Decimal)
{
map.add(BigDecimal.valueOf(Long.parseLong(String.valueOf(value))));
}
else if(dataType == DATA_TYPE.Boolean)
{
map.add(Boolean.parseBoolean(String.valueOf(value)));
}
else if(dataType == DATA_TYPE.Json)
{
map.add(value);
}
else if(dataType == DATA_TYPE.List)
{
map.add(value);
}
}
}