2017년 6월 24일 토요일

java 8, Spring 에서 requestMapping method의 parameter name을 generic으로 획득하기

최종 목표는 @GetMapping으로 바인딩된 호출의 parameterName을 구하는 것이다.


springframework를 사용하기 전 우선 java 8에서 method의 parameterName을 generic으로 구할 수 있는가에 대해 알아보자.

우선 java 에서 generic으로 다음과 같이 parameter name을 구할 수 있다.


String name = String.class.getMethod("substring", int.class).getParameters()[0].getName()
System.out.println(name);

하지만 막상 획득해보면 원래 이름이 아닌 arg0, arg1, arg2 ... 와 같은 이름으로 반환된다.

java 가 컴파일 시 이름에 대해 메모리 공간을 낭비하지 않기 위해 이와 같이 통일된 값으로 변환하여 사용하기 때문이다.

이를 원래 parameter name으로 사용하고자 하는 경우 vm 옵션으로 -parameters 를 사용하면 된다.

Spring에서는 parameter name을 사용하여 외부 요청의 key 값을 매핑하고 있기 때문에 이에 대해 저장, 관리를 하고 있다.

이를 사용하기 위해 ParameterNameDiscoverer 를 제공하고 있다.

다음과 같이 사용하면 된다.


private static DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = discoverer.getParameterNames(method);

2017년 6월 8일 목요일

pageImpl 로 반환된 json 타입 restTemplate 호출하기

data jpa를 쓰는 경우 응답 처리의 paging 처리를 하기 위해 pageImpl로 반환하는 경우가 많다.
이 결과를 restTemplate으로 호출하는 경우 pageImpl 으로 반환하는 방법은 다음과 같다.
pageImpl을 재선언하여 restTemplate 호출을 받을 수 있는 class를 만든다.
아래는 단순 map 형태로 반환 받는 pageImpl의 구현 예이다.
@JsonIgnoreProperties(ignoreUnknown = true)
public class RestPageImpl extends PageImpl<Map<?, ?>> {
 private static final long serialVersionUID = 1L;

 @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
 public RestPageImpl(@JsonProperty("content") List<Map<?, ?>> content, @JsonProperty("number") int page,
   @JsonProperty("size") int size, @JsonProperty("totalElements") long total) {
  super(content, new PageRequest(page, size), total);
 }

 public RestPageImpl(List<Map<?, ?>> content, Pageable pageable, long total) {
  super(content, pageable, total);
 }

 public RestPageImpl(List> content) {
  super(content);
 }

 @SuppressWarnings("unchecked")
 public RestPageImpl() {
  super(Collections.EMPTY_LIST);
 }
}