API 서버에 요청하여 정보 가져오는 방법
다른 서버에 정보를 요청하는 방법은 RestTemplate, Apache Client ,WebClient,...등 의 방법이 있다.
스프링에서는 주로 RestTemplate 을 사용한다.
1 . API 서버가 어떤 데이터를 주는지 JSON 표준 규격을 보고 클래스를 생성한다.
2 . UriComponentsBuilder 를 통해 API 서버와 연결
3 . RestTemplate 을 통해 GET 또는 POST로 데이터를 주고 받는다.
< Setting - Client Port : 8088 / Server Port : 9090 >
1. GET 요청으로 API 데이터 가져오기
Server (port : 9090)
1 ) 데이터 객체
📑User.java
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;
}
2) 컨트롤러 : 데이터를 전달 받아서 리턴
📑serverApiController.java
package com.example.server.controller;
import com.example.server.dto.User;
import org.springframework.beans.factory.annotation.Autowired;
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;
}
}
Client (port : 8088)
1 ) json표준 규격을 보고 객체 클래스 생성
📑UserResponse.java
package com.example.client.dto;
public class UserResponse {
private String name;
private int age;
@Override
public String toString() {
return "UserResponse{" +
"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;
}
}
2) 서비스 로직에서 서버에 정보 전달 및 요청
📑RestTemplateService.java
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 {
//response
//클라이언트
public UserResponse hello(){
//http://localhost:9090/api/server/hello
URI uri = UriComponentsBuilder
.fromUriString("http://localhost:9090")
.path("/api/server/hello")
//GET으로 요청할 경우, 서버에 전달할 파라미터를 넘길 수 있다.
.queryParam("name","steve")
.queryParam("age","20")
.encode()
.build()
.toUri();
System.out.println(uri.toString());
RestTemplate restTemplate = new RestTemplate();
//헤더내용이나 상세 내용을 더 받을 경우 ResponseEntity로 받는것을 추천
ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class); // 내가 받으려는 타입
//오브젝트만 받을경우 getForObject
UserResponse resultObject = restTemplate.getForObject(uri, UserResponse.class); // 내가 받으려는 타입
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
return result.getBody();
}
}
- UriComponentsBuilder : Uri를 동적으로 생성하고 데이터를 서버로 Get으로 전달한다 ( 쿼리 스트링 )
- scheme(String)
- userInfo (String)
- host(String)
- fromUriString(String)
- port(String or int)
- path(String)
- queryParam(String, Object...) : 파라미터 값 전달
- fragment(String)
- encode(void or Charset) : void일 경우 UTF-8 로 인코딩
- build()
- expand( int or String) : Post PathVariable로 보낼때 안에 들어갈 값.
- toUri : 전체 uri로 바꿔준다
- RestTemplate 을 사용하여 URI 서버에서 전달 온 데이터를 전달 받는다.
- 헤더내용이나 상세 내용을 더 받을 경우 사용 : ResponseEntity< 받으려는 타입 >
- restTemplate.getForEntity(uri, UserResponse.class);
- Object 데이터만 받을 경우 : Object타입
- restTemplate.getForObject(uri, UserResponse.class); // 내가 받으려는 타입
3) 클라이언트 컨트롤러
📑ApiController.java
package com.example.client.controller;
import com.example.client.dto.UserResponse;
import com.example.client.service.RestTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/client")
public class ApiController {
//@Autowired
//private RestTemplateService restTemplateService;
//생성자 주입 방식
private final RestTemplateService restTemplateService;
public ApiController(RestTemplateService restTemplateService) {
this.restTemplateService = restTemplateService;
}
@GetMapping("/hello")
public UserResponse getHello(){
return restTemplateService.hello();
}
}
- http://localhost:8088/api/client/hello로 접속시 서버와 연결되는 서비스 로직(RestTemplateService)을 실행하여 값을 리턴한다.
ResponseEntity로 받을 경우 현제 상태 코드 번호와 Body 내용도 클라이언트 서버에서 전달 받을 수 있다.
📑실행결과
2. POST 요청으로 API 데이터 가져오기
Server (port : 9090)
1 ) 데이터 객체
📑User.java
...(내용 동일)
2) 컨트롤러 : 데이터를 전달 받아서 리턴
📑serverApiController.java
...
@PostMapping("/user/{userId}/name/{userName}")
public User post(@RequestBody User user, @PathVariable int userId,@PathVariable String userName){
log.info("user id:{} , user name:{}",userId,userName);
log.info("client user: {}",user);
return user;
}
Client (port : 8088)
1 ) json표준 규격을 보고 객체 클래스 생성
📑UserResponse.java
...(내용 동일)
2) 서비스 로직에서 서버에 정보 전달 및 요청
📑RestTemplateService.java
...
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,"steve")
.toUri();
System.out.println(uri);
//http body -> object -> object mapper -> json -> rest template -> body json
UserRequest req = new UserRequest();
req.setName("jimin123");
req.setAge(20);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UserResponse> response = restTemplate.postForEntity(uri,req, UserResponse.class);
System.out.println(response.getStatusCode());
System.out.println(response.getHeaders());
System.out.println(response.getBody());
return response.getBody();
}
- UriComponentsBuilder : Uri를 동적으로 생성하고 데이터를 서버로 Get으로 전달한다 ( 쿼리 스트링 )
- expand( int or String) : Post PathVariable로 보낼때 안에 들어갈 값.
※ Api 서버에서 받아주는 값을 확인하고 싶을경우
받아주는 값을 String 으로 해서 확인이 가능하다.
3) 클라이언트 컨트롤러
📑ApiController.java
...
@GetMapping("/post")
public UserResponse postHello(){
return restTemplateService.post();
}
'BackEnd > Spring Boot' 카테고리의 다른 글
[ Spring Boot ] 로깅 SLF4J - @Slf4j (0) | 2023.03.23 |
---|---|
[ Spring Boot ] Server 연결 (2) - 실제로 많이 사용되는 구조와 네이버 Api 연결해보기 (1) | 2023.03.13 |
[ Spring Boot ] Exception 예외 처리 방법 (0) | 2023.03.10 |
[ Spring ] Test Code - Controller 전체를 테스트하는 방법 (0) | 2023.03.09 |
[ Spring Boot ] Validation (2) - @AssertTrue/False , Custom Annotation (0) | 2023.03.09 |