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

+ Recent posts