Spring에서 SuperTypeToken을 사용하고 싶다면, 이미 존재하는 org.springframework.core.ParameterizedTypeReference 사용하면 된다.
테스트
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class SpringbootAcApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootAcApplication.class, args);
}
@RestController
public static class MyController{
@RequestMapping("/")
public List<User> users(){
return DB.users();
}
}
static class User{
long id;
String name;
int age;
String gender;
int money;
String email;
public User() { }
public long getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getGender() {
return gender;
}
public int getMoney() {
return money;
}
public String getEmail() {
return email;
}
public void setId(long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setMoney(int money) {
this.money = money;
}
public void setEmail(String email) {
this.email = email;
}
public User(long id,String name, int age, String gender, int money, String email) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.money = money;
this.email = email;
}
public String toString() {
return "[id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", money=" + money
+ ", email=" + email + "]\n";
}
}
static class DB{
private static long num = 0L;
static String[] nameDB = {
"남재인", "한재인", "신이경", "오유리", "장경완", "봉숙자", "황여진", "심재인", "복미래", "신여진",
"배미란", "배영신", "이애정", "송여진", "남영애", "안미란", "문재규", "홍숙자", "장경님", "양경님",
"양장미", "추자경", "백장미", "권민서", "전재규", "윤재규", "전지해", "설재신", "배경완", "황보혜린",
"정무열", "조경구", "남성한", "조경모", "남치원", "유병헌", "최성한", "윤남규", "문성한", "강승헌",
"백성한", "표경구", "조치원", "오재섭", "하경구", "정요한", "송광조", "백재범", "안남규", "배덕수",
"노광조", "복일성", "안재범", "임경구", "유무영", "남궁덕수", "하치원", "하동건", "유무영", "유무영",
"성란", "임재", "심진", "설린", "강현", "전진", "이성", "사공리", "탁재", "복상", "하진", "이상",
"심리", "송설", "조진", "문성", "문지", "임린", "예현", "손진", "유리", "전현", "유재", "배은",
"예상", "황성", "임진", "심재", "백현", "한리", "남훈", "심광", "예철", "정건", "하웅", "권훈",
"성훈", "한훈", "하훈", "심광", "성호", "봉건", "류혁", "노훈", "서훈", "권훈", "윤호", "송건",
"윤광", "하웅", "노호", "이철", "문혁", "추철", "정광", "한호", "예철", "오훈", "사공웅", "고훈",
"제갈다솜", "하햇살", "양보다", "정자람", "전우리", "노보람", "최한울", "봉빛나", "장비", "전누리",
"전두리", "전마음", "예한별", "김은별", "김민들레", "홍자람", "안꽃", "전나빛", "안아름", "고보름",
"백나라", "전아람", "설빛나", "강나비", "문샛별", "유새벽", "성여름", "남다솜", "양하다", "권하루",
"손우람", "허버들", "봉미르", "남궁나라우람", "노힘찬", "황보달", "류빛가람", "윤나라우람", "유미르",
"황보힘찬", "이믿음", "남궁샘", "남한길", "황보나길", "한한길", "전나라우람", "최한길", "권한길", "임믿음",
"고한결", "설믿음", "황샘", "표나길", "안달", "양샘", "임달", "황빛가람", "홍한길", "제갈한결", "배버들",
"강광일", "송세은", "문준웅", "백은선", "설서우", "강경희", "권윤미", "봉재경", "표수민", "조동근",
"추진석", "황민숙", "남원석", "심시준", "이선우", "조정우", "유태일", "추경윤", "권규환", "임은주",
"표연웅", "류창기", "풍병수", "서인숙", "남궁명욱", "박시현", "전창현", "남궁주원", "이우태", "사공혜윤"
};
static String[] mailDB = {
"@naver.com", "@nate.com" , "@daum.net" , "@kakao.com" , "@gmail.com" , "@outlook.com",
"@hotmail.com" , "@yahoo.com"
};
static String[] gender = {
"남자", "여자"
};
static ThreadLocalRandom ran = ThreadLocalRandom.current();
static List<User> users() {
return IntStream.range(0, 20)
.mapToObj(n-> getUser())
.collect(Collectors.toList());
}
static User getUser() {
return new User(num++,getUsername(), getAge(), getGender(), getMoney(), getEmail());
}
static String getUsername() {
return nameDB[ran.nextInt(nameDB.length)];
}
static String getEmail() {
StringBuilder sb = new StringBuilder();
for(int i=0,len=ran.nextInt(5, 15);i<len;i++)
sb.append(getWord());
sb.append(mailDB[ran.nextInt(mailDB.length)]);
return sb.toString();
}
static char getWord() {
return (char)ran.nextInt(97, 122+1);
}
static String getGender() {
return gender[ran.nextInt(gender.length)];
}
static int getAge() {
return ran.nextInt(10, 80);
}
static int getMoney() {
return ran.nextInt(10_000, 1_000_000);
}
}
}
실행
import java.util.List;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import com.example.springbootac.SpringbootAcApplication.User;
public class Test {
public static void main(String[] args) {
RestTemplate rest = new RestTemplate();
List<?> forObject = rest.getForObject("http://localhost:8080", List.class);
System.out.println("타입 토큰 방식");
System.out.println(forObject.get(0).getClass());
// forObject.forEach(System.out::println);
ResponseEntity<List<User>> exchange = rest.exchange(
"http://localhost:8080",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<User>>() {});
System.out.println("슈퍼 타입 토큰 방식");
System.out.println(exchange.getBody().get(0).getClass());
// System.out.println(exchange.getBody());
}
}
20:16:45.500 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET http://localhost:8080
20:16:45.518 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
20:16:45.545 [main] DEBUG org.springframework.web.client.RestTemplate - Response 200 OK
20:16:45.551 [main] DEBUG org.springframework.web.client.RestTemplate - Reading to [java.util.List<?>]
타입 토큰 방식
class java.util.LinkedHashMap
20:16:45.588 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET http://localhost:8080
20:16:45.589 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
20:16:45.592 [main] DEBUG org.springframework.web.client.RestTemplate - Response 200 OK
20:16:45.593 [main] DEBUG org.springframework.web.client.RestTemplate - Reading to [java.util.List<com.example.springbootac.SpringbootAcApplication$User>]
슈퍼 타입 토큰 방식
class com.example.springbootac.SpringbootAcApplication$User
타입 토큰 방식은 기본적으로 지네릭 정보를 알 수 없기 때문에 JSON에 매칭되는 Map을 만들어 값을 반환한다.
슈퍼 타입 토큰은 슈퍼 타입의 지네릭 정보를 읽어 알맞게 DTO 객체로 바인딩한다.
DTO 클래스로 JSON이나, xml 같은 데이터를 받게 되면 validation을 쉽게 수행할 수 있고, IDE 코드 추천을 받을 수 있다는 것이 큰 장점이다.
'개발 > 자바(JAVA)' 카테고리의 다른 글
SuperTypeToken (0) | 2023.06.29 |
---|---|
컴포지트 패턴 연습 - 2 (0) | 2023.04.16 |
컴포지트 패턴 연습 - 1 (0) | 2023.04.13 |
기본형 배열 List로 변환하기 (0) | 2023.03.10 |
객체 지향 - 6 (0) | 2023.02.03 |