스프링부트 Server to Server 2. Rest Template 사용하기

min seung moon·2021년 6월 30일
0

Spring

목록 보기
39/50

1. Project Test

https://advenoh.tistory.com/46

01. Create Project

  • client Project, spring web, server.port = 8080

  • server Project, Spring web, lobok, server.port = 9090

2. GET 형식으로 통신

01. Client Server에서 Server에게 String Data 받기

-1. Client

  • Package : controller, service
  • Class : Apicontroller, RestTemplateService
  • controller / Apicontroller.java
package com.example.client.controller;

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;

    public ApiController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/hello")
    public String getHello() {
        return restTemplateService.hello();
    }
}
  • service / RestTemplateService.java
    • RestTemplate
      • spring 3.0부터 지원하는 객체로, 스프링에서 제공하는 http 통신에 유용하게 슬 수 있는 템플릿이며, HTTP 서버와의 통신을 단순화하고 RESTful 원칙을 지킨다
      • Resttemplate은 간편하게 Rest 방식 api를 호출할 수 있는 spring 내장 클래스
      • json , xml응답을 모두 받을 수 있습니다.
      • https://advenoh.tistory.com/46
    • restTemplate.getForObject(uri, String.class)
      • String result = restTemplate.getForObject(uri, String.class);
      • 주어진 URL 주소로 HTTP GET 메서드로 객체로 결과를 반환받는다
      • getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
    • restTemplate.getForEntity(uri, String.class)
      • ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);
      • 주어진 URL 주소로 HTTP GET 메서드로 결과는 ResponseEntity로 반환받는다
      • status, body 등 다양한 정보를 갖고 있는 클래스
      • getBody() 메소드로 서버로부터 전송받은 데이터를 갖고 온다
package com.example.client.service;

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 String hello() {
        URI uri = UriComponentsBuilder
                    .fromUriString("http://localhost:9090")
                    .path("/api/server/hello")
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }
}



02. Client Server에서 Server에게 JSON Data 받기

  • Package : dto
  • Class : UserResponse(Client), User(Server)

-1. Client

  • dto / UserResponse.java
package com.example.client.dto;

public class UserResponse {

    private String name;
    private int 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;
    }

    @Override
    public String toString() {
        return "UserResponse{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • controller / 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;

    public ApiController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/hello")
    public UserResponse getHello() {
        return restTemplateService.hello();
    }
}

-2. Server

  • dto / 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;
}
  • controller / ServerApiController.java
package com.example.server.contoller;

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.RestController;

@RestController
@RequestMapping("/api/server")
public class ServerApiController {

    @GetMapping("/hello")
    public User hello() {
        User user = new User();
        user.setName("steve");
        user.setAge(10);
        return user;
    }

}

03. Client의 UriComponentsBuilder 활용

-1. .queryParam()

  • 주소에 QueryParameter가 들어가야 된다면 UriComponentsBuilder에 추가로 바인딩을 해주면 된다
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","steve")
                    .queryParam("age", 10)
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }
}



-2. QueryParameter 전달 받아서 출력하기

_1. Client

  • service / 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 {

    // http://localhost/api/server/hello
    // response
    public UserResponse hello() {
        URI uri = UriComponentsBuilder
                    .fromUriString("http://localhost:9090")
                    .path("/api/server/hello")
                    .queryParam("name","client")
                    .queryParam("age", 25)
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }
}

_2. Server

  • controller / ServerApiController.java
package com.example.server.contoller;

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

}


3 POST 형식으로 통신

01. Client URI로 데이터 전달

-1. Client

  • service / RestTemplateService.java
    • .expand()
      • 순서대로 괄호랑 매치가 된다, ","로 구분하여 작성
    • http body -> object -> object mapper -> json -> rest template -> http body json
    • restTemplate.postForEntity
      • (uri, request object, response object)
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 {

    // http://localhost/api/server/hello
    // response
    public UserResponse hello() {
        URI uri = UriComponentsBuilder
                    .fromUriString("http://localhost:9090")
                    .path("/api/server/hello")
                    .queryParam("name","client")
                    .queryParam("age", 25)
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }

    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 -> http body json
        UserRequest req = new UserRequest();
        req.setName("steve");
        req.setAge(10);

        RestTemplate restTemplate = new RestTemplate();
        // (uri, request object, response object)
        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();
    }
}

  • controller / 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;

    public ApiController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/hello")
    public UserResponse getHello() {
        return restTemplateService.post();
    }
}

-2. Server

  • controller / ServerApiController.java
package com.example.server.contoller;

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) {
        log.info("userId : {}, userName : {}", userId, userName);
        log.info("client request : {}",user);

        return user;
    }

}




-3. response 데이터의 타입을 모를경우 일단 String으로 찍을 수 도 있다

_1. client

  • controller / 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;

    public ApiController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/hello")
    public UserResponse getHello() {
        restTemplateService.post();

        return new UserResponse();
    }
}

  • service / RestTemplateService.java
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 {

    // http://localhost/api/server/hello
    // response
    public UserResponse hello() {
        URI uri = UriComponentsBuilder
                    .fromUriString("http://localhost:9090")
                    .path("/api/server/hello")
                    .queryParam("name","client")
                    .queryParam("age", 25)
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }

    public void 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 -> http body json
        UserRequest req = new UserRequest();
        req.setName("steve");
        req.setAge(10);

        RestTemplate restTemplate = new RestTemplate();
        // (uri, request object, response object)
        ResponseEntity<String> response = restTemplate.postForEntity(uri, req, String.class);

        System.out.println(response.getStatusCode());
        System.out.println(response.getHeaders());
        System.out.println(response.getBody());

        //return response.getBody();
    }
}



3 exchange로 HEADER 추가

  • HTTP 헤더를 새로 만들 수 있고 어떤 HTTP 메서드도 사용가능하다

01. requestRequestEntity 클래스를 활용한 기본 exchange 메소드

-1. Client

  • service / RestTemplateService.java
    • .header()
      • (key, value)
      • header 값 추가
package com.example.client.service;

import com.example.client.dto.UserRequest;
import com.example.client.dto.UserResponse;
import org.springframework.http.MediaType;
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 {

    // http://localhost/api/server/hello
    // response
    public UserResponse hello() {
        URI uri = UriComponentsBuilder
                    .fromUriString("http://localhost:9090")
                    .path("/api/server/hello")
                    .queryParam("name","client")
                    .queryParam("age", 25)
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }

    public void 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 -> http body json
        UserRequest req = new UserRequest();
        req.setName("steve");
        req.setAge(10);

        RestTemplate restTemplate = new RestTemplate();
        // (uri, request object, response object)
        ResponseEntity<String> response = restTemplate.postForEntity(uri, req, String.class);

        System.out.println(response.getStatusCode());
        System.out.println(response.getHeaders());
        System.out.println(response.getBody());

        //return response.getBody();
    }

    public UserResponse exchange() {
        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 -> http body json
        UserRequest req = new UserRequest();
        req.setName("steve");
        req.setAge(10);

        RequestEntity<UserRequest> requestRequestEntity = RequestEntity
                .post(uri)
                .contentType(MediaType.APPLICATION_JSON)
                .header("x-authorization", "abcd")
                .header("custom-header", "fffff")
                .body(req);

        RestTemplate restTemplate = new RestTemplate();

        ResponseEntity<UserResponse> response = restTemplate.exchange(requestRequestEntity, UserResponse.class);

        return response.getBody();

    }
}

  • controller / 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;

    public ApiController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/hello")
    public UserResponse getHello() {
        restTemplateService.exchange();

        return new UserResponse();
    }
}

-2. Server

  • controller / ServerApiController.java
package com.example.server.contoller;

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("x-authorization") String authorization,
                    @RequestHeader("custom-header") String customHeader
                    ) {
        log.info("userId : {}, userName : {}", userId, userName);
        log.info("authorization : {}", authorization);
        log.info("customHeader : {}",customHeader);
        log.info("client request : {}",user);

        return user;
    }

}



02. exchange 메소드 확장

  • 기본 JSON의 형태만 있으면 편하지만 그렇지 않은 경우가 더 많다
    • 기본형태
    {
    	"name" : "steve",
      "age" : 10
    }
    • 다른 형태
      • 내용이 계속 변경이 된다(body 내부의 내용, header는 거의 동일하다)
    {
    	"header" : {
      	...
      },
      "body" : {
      	...
      }
    }
  • 우리가 전송할 데이터 예시
{
	"header" : {
		"response_code" : "OK"
	},
	"body" : {
		"name" : "spring boot",
        "age" : 1024
	}
}

-1. Client

  • Class : dto/Req
  • dto / Req.java
    • T
      • Data의 타입을 전달받을 때 결정하기 위해서 generic type T를 사용
package com.example.client.dto;

public class Req<T> {

    private Header header;

    private T responseBody;

    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 + '\'' +
                    '}';
        }
    }

    public Header getHeader() {
        return header;
    }

    public void setHeader(Header header) {
        this.header = header;
    }

    public T getResponseBody() {
        return responseBody;
    }

    public void setResponseBody(T responseBody) {
        this.responseBody = responseBody;
    }

    @Override
    public String toString() {
        return "Req{" +
                "header=" + header +
                ", body=" + responseBody +
                '}';
    }
}
  • service / RestTemplateService.java
    • RequestEntity
      • HttpEntity 클래스를 상속받아 구현한 클래스
    • ParameterizedTypeReference
      • generic type을 응답 받을 수 있게 해준다
      • Req<UserResponse>.class generic에는 .class를 붙일 수 없다 그렇기 때문에 ParameterizedTypeReference로 랩핑 해준다
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.MediaType;
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 {

    // http://localhost/api/server/hello
    // response
    public UserResponse hello() {
        URI uri = UriComponentsBuilder
                    .fromUriString("http://localhost:9090")
                    .path("/api/server/hello")
                    .queryParam("name","client")
                    .queryParam("age", 25)
                    .encode()
                    .build()
                    .toUri();

        System.out.println(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // getForObject 실행되는 순간이 클라이언트에서 http에서 서버로 붙는 시간
        // String result = restTemplate.getForObject(uri, String.class);
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }

    public void 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 -> http body json
        UserRequest req = new UserRequest();
        req.setName("steve");
        req.setAge(10);

        RestTemplate restTemplate = new RestTemplate();
        // (uri, request object, response object)
        ResponseEntity<String> response = restTemplate.postForEntity(uri, req, String.class);

        System.out.println(response.getStatusCode());
        System.out.println(response.getHeaders());
        System.out.println(response.getBody());

        //return response.getBody();
    }

    public UserResponse exchange() {
        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 -> http body json
        UserRequest req = new UserRequest();
        req.setName("steve");
        req.setAge(10);

        RequestEntity<UserRequest> requestRequestEntity = RequestEntity
                .post(uri)
                .contentType(MediaType.APPLICATION_JSON)
                .header("x-authorization", "abcd")
                .header("custom-header", "fffff")
                .body(req);

        RestTemplate restTemplate = new RestTemplate();

        ResponseEntity<UserResponse> response = restTemplate.exchange(requestRequestEntity, UserResponse.class);

        return response.getBody();

    }


    public Req<UserResponse> genericExchange() {
        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 -> http body json

        UserRequest userRequest = new UserRequest();
        userRequest.setName("steve");
        userRequest.setAge(10);

        Req req = new Req<UserRequest>();
        req.setHeader(
                new Req.Header()
        );
        req.setResponseBody(
                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>>(){});
        // Req<UserResponse>.class generic에는 .class를 붙일 수 없다
        // 그렇기 때문에 ParameterizedTypeReference로 랩핑 해준다

        return response.getBody();
    }
}

  • controller / ApiController.java
package com.example.client.controller;

import com.example.client.dto.Req;
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;

    public ApiController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/hello")
    public Req<UserResponse> getHello() {
        return restTemplateService.genericExchange();
    }
}

-2. Server

  • Class : dto/Req
  • dto / Req.java
package com.example.server.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Req<T> {

    private Header header;
    private T responseBody;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Header{
        private String responseCode;
    }

}
  • controller / ServerApiController.java
package com.example.server.contoller;

import com.example.server.dto.Req;
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 Req<User> post(
                    //HttpEntity<String> entity,
                    @RequestBody Req<User> user,
                    @PathVariable int userId,
                    @PathVariable String userName,
                    @RequestHeader("x-authorization") String authorization,
                    @RequestHeader("custom-header") String customHeader
                    ) {
        //log.info("req : {}", entity.getBody());
        log.info("userId : {}, userName : {}", userId, userName);
        log.info("authorization : {}", authorization);
        log.info("customHeader : {}",customHeader);
        //log.info("client request : {}",user);

        Req<User> response = new Req<>();
        response.setHeader(
                new Req.Header()
        );
        response.setResponseBody(user.getResponseBody());
        return response;
    }

}



profile
아직까지는 코린이!

0개의 댓글