오답노트
[Spring] Server to Server 본문
Server to Server
지금까지는 서버를 개발하여 클라이언트의 요청을 처리하기만 했다. 하지만 우리도 누군가의 클라이언트가 되어 요청을 보내고 응답을 받아와야 할 경우가 있다.
GET
import com.example.client.dto.UserResponse;
import lombok.extern.slf4j.Slf4j;
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;
@Slf4j
@Service
public class RestTemplateService {
public UserResponse hello(){
URI uri = UriComponentsBuilder.fromUriString("http://localhost:8080").path("/api/server/hello")
.queryParam("name","steve")
.queryParam("age",20)
.encode().build().toUri();
log.info(uri.toString());
RestTemplate restTemplate = new RestTemplate();
UserResponse result = restTemplate.getForObject(uri,UserResponse.class);
return result;
}
}
UriComponentsBuilder는 Uri를 메소드를 활용하여 만들어주는 클래스다. 적절히 메소드를 활용해 서버의 uri를 만들자.
해당 Uri를 RestTemplate의 getForObject 메소드를 통해 서버에 GET을 보낼 수 있다.
@RestController
@RequestMapping("/api/client")
public class ApiController {
private final RestTemplateService restTemplateService;
public ApiController(RestTemplateService restTemplateService) {
this.restTemplateService = restTemplateService;
}
@GetMapping("")
public UserResponse getHello(){
return restTemplateService.hello();
}
}
반환한 내용을 위 코드처럼 활용하여 Client가 우리 Server에 요청을 했을 때, 우리도 Client가 되어 다른 서버에 요청을 보낼 수 있다.
POST
public UserRequest post(){
URI uri = UriComponentsBuilder.fromUriString("http://localhost:8080").path("/api/server/user/{userid}/name/{username}")
.encode().build().expand(100,"steve").toUri();
log.info(uri.toString());
UserRequest req = new UserRequest();
req.setName("steve");
req.setAge(10);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UserRequest> response = restTemplate.postForEntity(uri,req,UserRequest.class);
log.info(response.getStatusCode().toString());
log.info(response.getHeaders().toString());
log.info(response.getBody().toString());
return response.getBody();
}
RestTemplate에서 getForEntity에서 postEntity만 달라졌다.
Exchange 와 Generic
RestTemplate의 exchange 메소드는 요청을 보낼 자료형과 응답 받을 자료형이 다를 때 사용한다. (POST 사용)
그리고 보통 응답받을때 어떤 형식의 데이터가 오는지 알 수 없을 수 있다. 이때 제네릭을 활용하면 좋다.
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Req<T> {
private Header header;
private T rBody;
@Getter
@Setter
public static class Header {
private String responseCode;
}
@Override
public String toString() {
return "Req{" +
"header=" + header +
", body=" + rBody +
'}';
}
}
어떤 자료형을 받을지 몰라 제네릭 타입인 T를 사용했다.
public Req<UserResponse> generic (){
URI uri = UriComponentsBuilder.fromUriString("http://localhost:8080").path("/api/server/user/{userid}/name/{username}")
.encode().build().expand(100,"steve").toUri();
log.info(uri.toString());
UserRequest userRequest = new UserRequest();
userRequest.setName("steve");
userRequest.setAge(10);
Req req = new Req();
req.setHeader(
new Req.Header()
);
req.setRBody(
userRequest
);
RequestEntity<Req<UserRequest>> requestEntity = RequestEntity.post(uri)
.contentType(MediaType.APPLICATION_JSON)
.header("x-authorization","abcd")
.header("custom-header","fffff")
.body(req);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Req<UserResponse>> response
= restTemplate.exchange(requestEntity,new ParameterizedTypeReference<Req<UserResponse>>(){});
return response.getBody();
}
T에 UserRequest 형식으로 넘어오는 것을 알고 Generic을 사용한 코드이다.
Generic 타입의 경우 Class 클래스가 적용되지 않는다. 따라서
ParameterizedTypeReference를 통해 자료형을 지정해야한다.
'Java > Spring' 카테고리의 다른 글
[Spring] 코드 Test하기 (0) | 2023.07.17 |
---|---|
[Spring] Server to Server 예제 (네이버 API) (0) | 2023.07.14 |
[Spring] 비동기 처리 (Async) (0) | 2023.07.14 |
[Spring] Interceptor (0) | 2023.07.14 |
[Spring] Filter (0) | 2023.07.14 |