지금까지 살펴본 부분은 항상 Server의 입장에서 API를 제공하는 방법에 대하여 학습
Back-end에서 Client로 다른 Server와의 연결은 필수!!!
Port 설정은 resource 하위의 application.properties 파일에서
server.port = {사용할 포트 번호} 로 변경할 수 있다.
1. Server to Server - GET
Client
package com.example.client.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private String name;
private int age;
}
package com.example.client.service;
import com.example.client.dto.UserResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@Service
public class RestTemplateService {
// <http://localhost/api/server/hello>
// response
public UserResponse hello(){
URI uri = UriComponentsBuilder
.fromUriString("<http://localhost:9090>")
.path("/api/server/hello")
.queryParam("name","jun")
.queryParam("age",30)
.encode()
.build()
.toUri();
System.out.println(uri.toString());
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);
System.out.println("getStatusCode : "+ result.getStatusCode());
System.out.println("getBody : "+ result.getBody());
return result.getBody();
}
}
RestTemplate 클래스를 이용하여 다른 서버로 요청(GET, POST, DELETE, …) 을 보낼 수 있다.
서버와 API 표준 스펙을 정하여 DTO 클래스를 설계하여 응답을 받을 때 사용한다.
Server
package com.example.server.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private int age;
}
package com.example.server.controller;
import com.example.server.dto.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@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;
}
}
2. Server to Server - POST
Client
package com.example.client.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserRequest {
private String name;
private int age;
}
package com.example.client.service;
import com.example.client.dto.UserRequest;
import com.example.client.dto.UserResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@Service
public class RestTemplateService {
public UserResponse post(){
// <http://localhost:9090/api/server/user/{userId}/name/{userName}>
URI uri = UriComponentsBuilder
.fromUriString("<http://localhost:9090>")
.path("/api/server/user/{userId}/name/{userName}")
.encode()
.build()
.expand(100,"jun")
.toUri();
System.out.println(uri);
// http body -> object -> object mapper -> json -> rest template -> http body json
UserRequest req = new UserRequest();
req.setAge(30);
req.setName("jun");
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UserResponse> response = restTemplate.postForEntity(uri, req, UserResponse.class);
System.out.println("getStatusCode : "+ response.getStatusCode());
System.out.println("getHeaders : "+ response.getHeaders());
System.out.println("getBody : "+ response.getBody());
return response.getBody();
}
}
RestTemplate의 postForEntity 함수를 이용하여 requstBody의 내용을 추가하여 다른 서버로 요청할 수 있다.
Server
package com.example.server.controller;
import com.example.server.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping("/api/server")
public class ServerApiController {
@PostMapping("/user/{userId}/name/{userName}")
public User post(@RequestBody User user, @PathVariable int userId, @PathVariable String userName){
log.info("userId : {} , userName : {}",userId,userName);
log.info("user : {}",user);
return user;
}
}
3. Server to Server - exchange
Client
package com.example.client.service;
import com.example.client.dto.Req;
import com.example.client.dto.UserRequest;
import com.example.client.dto.UserResponse;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@Service
public class RestTemplateService {
public UserResponse exchange(){
// <http://localhost:9090/api/server/user/{userId}/name/{userName}>
URI uri = UriComponentsBuilder
.fromUriString("<http://localhost:9090>")
.path("/api/server/user/{userId}/name/{userName}")
.encode()
.build()
.expand(100,"jun")
.toUri();
System.out.println(uri);
// http body -> object -> object mapper -> json -> rest template -> http body json
UserRequest req = new UserRequest();
req.setAge(30);
req.setName("jun");
RequestEntity<UserRequest> requestEntity = RequestEntity
.post(uri)
.header("x-authorization","asdf")
.header("custom-header","112233")
.body(req);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UserResponse> response = restTemplate.exchange(requestEntity,UserResponse.class);
System.out.println("getStatusCode : "+ response.getStatusCode());
System.out.println("getHeaders : "+ response.getHeaders());
System.out.println("getBody : "+ response.getBody());
return response.getBody();
}
}
RestTemplate의 exchange함수를 이용하여 RequestEntity를 추가할 수 있다.
→ RequestEntity 클래스에서 httpMethod, URI, Header, Body를 설정
Server
package com.example.server.controller;
import com.example.server.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@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/{userId}/name/{userName}")
public User post(@RequestBody User user,
@PathVariable int userId,
@PathVariable String userName,
@RequestHeader(name ="x-authorization") String authorization ,
@RequestHeader(name ="custom-header") String customHeader){
log.info("userId : {} , userName : {}",userId,userName);
log.info("x-authorization : {} , custom-header: {}",authorization,customHeader);
log.info("user : {}",user);
return user;
}
}
4. Server to Server - GenericExchange
{
"header": {
"response_code" : ""
},
"body" : {
"name" : "jun",
"age" : 30
}
위 처럼 JSON 내용이 header,body 2가지로 나뉘고 상황에 따라 body의 내용만 바뀌는 상황이 있을 수 있다.
제네릭 dto클래스를 이용하여 간단하게 구현할 수 있다.
Client
package com.example.client.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Req<T> {
private Header header;
private T resBody;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Header{
private String responseCode;
}
}
package com.example.client.service;
import com.example.client.dto.Req;
import com.example.client.dto.UserRequest;
import com.example.client.dto.UserResponse;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@Service
public class RestTemplateService {
public Req<UserResponse> genericExchange(){
// <http://localhost:9090/api/server/user/{userId}/name/{userName}>
URI uri = UriComponentsBuilder
.fromUriString("<http://localhost:9090>")
.path("/api/server/user/{userId}/name/{userName}")
.encode()
.build()
.expand(100,"jun")
.toUri();
System.out.println(uri);
// http body -> object -> object mapper -> json -> rest template -> http body json
UserRequest userRequest = new UserRequest();
userRequest.setAge(30);
userRequest.setName("jun");
Req<UserRequest> req = new Req<>();
req.setHeader(new Req.Header());
req.setResBody(userRequest);
RequestEntity<Req<UserRequest>> requestEntity = RequestEntity
.post(uri)
.header("x-authorization","asdf")
.header("custom-header","112233")
.body(req);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Req<UserResponse>> response = restTemplate
.exchange(requestEntity, new ParameterizedTypeReference<Req<UserResponse>>() {});
System.out.println("getStatusCode : "+ response.getStatusCode());
System.out.println("getHeaders : "+ response.getHeaders());
System.out.println("getBody : "+ response.getBody());
return response.getBody();
}
}
Server
package com.example.server.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Req<T> {
private Header header;
private T resBody;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Header{
private String responseCode;
}
}
package com.example.server.controller;
import com.example.server.dto.Req;
import com.example.server.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping("/api/server")
public class ServerApiController {
@PostMapping("/user/{userId}/name/{userName}")
public Req<User> post(
@RequestBody Req<User> req,
@PathVariable int userId,
@PathVariable String userName,
@RequestHeader(name ="x-authorization") String authorization ,
@RequestHeader(name ="custom-header") String customHeader){
log.info("userId : {} , userName : {}",userId,userName);
log.info("x-authorization : {} , custom-header: {}",authorization,customHeader);
log.info("user : {}",req.getResBody());
Req<User> response = new Req<>();
response.setHeader(new Req.Header());
response.setResBody(req.getResBody());
return response;
}
}
'Spring' 카테고리의 다른 글
| Jacoco - 테스트 커버리지 확인하기 (1) | 2025.04.21 |
|---|---|
| JUnit (0) | 2025.04.21 |
| 비동기 처리하기 (1) | 2025.04.15 |
| Interceptor (0) | 2025.04.15 |
| 서블릿 컨테이너와 Spring 컨텍스트 (0) | 2025.04.15 |

