BackEnd/패캠
Rest Template (Server to Server 통신)
제이드Jade
2022. 1. 25. 00:00
- 서버가 클라이언트가 되어서 다른 서버에게 응답을 요청해보자!!!(고로 서버 두개(클:8080, 서:9090)를 쓸 것임)
- 즉, 브라우저(찐 클라이언트)에서 요청은 그냥 get 으로만 이루어져있음(파라미터, body xx), 그러면 찐 요청은 클라이언트 서버에서 하고, 응답을 서버에서 받아와 찐 클라이언트에게 보냄
1)get요청, 2)post요청, 3)헤더가 있는 post요청, 4)제너릭객체를 돌려주는 post요청을 해보자
<client>
application.yml -> server.port =8080
- controller
@RestController
@RequestMapping("/api/client")
public class ApiController {
private final RestTemplateService restTempleteService; //이제는 생성자 주입으로 많이 함(autowired xxx)
public ApiController(RestTemplateService restTempleteService) {
this.restTempleteService = restTempleteService;
}
@GetMapping("/hello")
public UserResponse hello(){
return restTempleteService.hello();
}
@GetMapping("/user")
public UserResponse getHello(){
return restTempleteService.post();
}
@GetMapping("/header")
public UserResponse getHHello(){
return restTempleteService.exchange();
}
@GetMapping("/generic")
public Req<UserRequest> getGHello(){
return restTempleteService.genericExchange();
}
}
- service
@Service
public class RestTemplateService {
//get요청
public UserResponse hello(){
URI uri= UriComponentsBuilder //요청할 주소 만들기 : http://localhost:9090/api/server/hello
.fromUriString("http://localhost:9090")
.path("/api/server/hello")
.queryParam("name","jade")
.queryParam("age",99)
.encode() //후에 파라미터를 넣을 때 인코딩 하는게 좋으므로 함
.build()
.toUri();
System.out.println(uri.toString());
RestTemplate restTemplate=new RestTemplate(); //서버를 클라이언트로 만들어줌,즉 REST 서비스를 호출할 수 있게 함. restTemplate안에 여러 요청 메소드를 쓸 수 있음
ResponseEntity<UserResponse> result=restTemplate.getForEntity(uri, UserResponse.class); //해당 uri로 가서 반환되는 string객체를 get요청
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
return result.getBody();
}
//post요청
public UserResponse post() {
URI uri=UriComponentsBuilder
.fromUriString("http://localhost:9090")
.path("/api/server/user/{userName}/age/{userAge}") //사실 post에는 paramid필요 x하지만 동작방식을 보여주기 위함
.encode()
.build()
.expand("jade",26) //주소 path에 pathvariable자리, 즉 {}안에 차례대로 넣어준다.
.toUri();
UserRequest req=new UserRequest();
req.setName("jade");
req.setAge(26);
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<UserResponse> result=restTemplate.postForEntity(uri,req,UserResponse.class);
System.out.println(result.getStatusCode());
System.out.println(result.getHeaders());
System.out.println(result.getBody());
return result.getBody();
/*
* 여기서, response가 무슨 타입으로 올지 모르겠어서 일단 텍스트로 형태를 보고 싶다면,
* ResponseEntity<String>~ = (~,String.class)으로 받아서 sout해보는 식으로 할 수 있다. (근데 현업에서 모르게 될 일은 거의 x)
* */
}
//헤더 추가해서 요청하기
public UserResponse exchange() {
URI uri=UriComponentsBuilder
.fromUriString("http://localhost:9090")
.path("/api/server/header/{userName}/age/{userAge}") //사실 post에는 paramid필요 x하지만 동작방식을 보여주기 위함
.encode()
.build()
.expand("jade",26) //주소 path에 pathvariable자리, 즉 {}안에 차례대로 넣어준다.
.toUri();
UserRequest req=new UserRequest();
req.setName("jade");
req.setAge(26);
RequestEntity<UserRequest> requestEntity = RequestEntity
.post(uri)
.contentType(MediaType.APPLICATION_JSON)
.header("x-authorization","nanana")
.header("custom-header","alala")
.body(req);
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<UserResponse> result=restTemplate.exchange(requestEntity,UserResponse.class);
return result.getBody();
}
//요청을 제너릭으로 받아보자.
// {
// Header:"",
// reqBody:{
// name:"",
// age:""
// }
// }
public Req<UserRequest> genericExchange() {
URI uri=UriComponentsBuilder
.fromUriString("http://localhost:9090")
.path("/api/server/generic/{userName}/age/{userAge}") //사실 post에는 paramid필요 x하지만 동작방식을 보여주기 위함
.encode()
.build()
.expand("jade",26) //주소 path에 pathvariable자리, 즉 {}안에 차례대로 넣어준다.
.toUri();
UserRequest userRequest=new UserRequest();
userRequest.setName("jade");
userRequest.setAge(26);
Req<UserRequest> req=new Req<>(); //제너릭객체 만들기
req.setHeader(new Req.Header());
req.setReqBody(userRequest); //바디는 아까 만든 바디
RequestEntity<Req<UserRequest>> requestEntity= RequestEntity
.post(uri)
.contentType(MediaType.APPLICATION_JSON)
.header("x-authorization","nanana")
.header("custom-header","alala")
.body(req); //제너릭객체를 바디로
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<Req<UserRequest>> result
= restTemplate.exchange(requestEntity, new ParameterizedTypeReference<Req<UserRequest>>(){});
//제너릭객체는 .class로 명시x Parameterized~로 받아야 한다.
return result.getBody();
}
}
dto
- Response
public class UserResponse {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- Request
public class UserRequest {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- Req<T>
public class Req<T> {
private Header header;
private T reqBody;
public static class Header{
private String responseCode;
public String getResponseCode() {
return responseCode;
}
public void setResponseCode(String responseCode) {
this.responseCode = responseCode;
}
@Override
public String toString() {
return "Header{" +
"responseCode='" + responseCode + '\'' +
'}';
}
}
@Override
public String toString() {
return "Req{" +
"header=" + header +
", reqBody=" + reqBody +
'}';
}
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
public T getReqBody() {
return reqBody;
}
public void setReqBody(T reqBody) {
this.reqBody = reqBody;
}
}
<server>
- controller
@Slf4j
@RestController
@RequestMapping("/api/server")
public class ServerApiController {
@GetMapping("/hello")
public User hello(@RequestParam String name,
@RequestParam int age){
User user=new User();
user.setName(name);
user.setAge(age);
return user;
}
@PostMapping("/user/{userName}/age/{userAge}") //클라이언트 서버로부터 온 UserRequest가 json형태로 받아지고 이게 다시 User로 매핑
public User user(@RequestBody User user, @PathVariable String userName, @PathVariable int userAge){
log.info("userName:{}, userAge:{} ",userName,userAge);
log.info("clientReq: {}",user);
return user;
}
@PostMapping("/header/{userName}/age/{userAge}") //헤더 추가된 요청받기
public User post(@RequestBody User user,
@PathVariable String userName,
@PathVariable int userAge,
@RequestHeader("x-authorization") String authorization,
@RequestHeader("custom-header") String customHeader){
log.info("userName:{}, userAge:{} ",userName,userAge);
log.info("clientReq: {}",user);
log.info("x-authorization: {}",authorization);
log.info("custom-header : {}",customHeader);
return user;
}
//헤더+요청객체 내에 제너릭타입의 객체가 또 있을 때
@PostMapping("/generic/{userName}/age/{userAge}")
public Req<User> gpost(@RequestBody Req<User> user,
@PathVariable String userName,
@PathVariable int userAge,
@RequestHeader("x-authorization") String authorization,
@RequestHeader("custom-header") String customHeader
//HTTPEntity<String> entity => user대신에 이걸 쓰면 요청 객체를 string 형으로 받는다. 디버깅에 유용.
){
log.info("userName:{}, userAge:{} ",userName,userAge);
log.info("x-authorization: {}",authorization);
log.info("custom-header : {}",customHeader);
log.info("clientReq: {}",user);
// log.info("req:{}",entity)
Req<User> response=new Req<>();
response.setHeader(new Req.Header());
response.setReqBody(user.getReqBody());
return response;
}
}
-dto
-User (=response)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private int age;
}
-req<T>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Req<T> {
private Header header;
private T reqBody;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Header{
private String responseCode;
}
}