minlog
article thumbnail

 

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();
}

 

profile

minlog

@jimin-log

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!