UriComponentsBuilder란?
여러개의 파라미터를 이용하여 URL를 작성할 때에 편하게 작성할 수 있게끔 해주며 서버단에서 동적으로 URI를 생성 가능한 클래스이다.
Json의 형태가 재사용된다면 제네릭을 활용한다.
package com.example.server.controller;
import com.example.server.controller.dto.Req;
import com.example.server.controller.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.annotation.HttpMethodConstraint;
@Slf4j
@RestController
@RequestMapping("/api/server")
public class ServerApiController {
@GetMapping("/hello")
public User hello(@RequestParam String name, 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: {}, custom: {}",authorization,customheader);
log.info("Client req: {}", user);
Req<User> response= new Req<>();
response.setHeader(
new Req.Header()
);
response.setResbody(user.getResbody());
return response;
}
}
package com.example.server.controller.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Req<T> {
private Header header;
private T resbody;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Header{
private String responseCode;
}
}
package com.example.server.controller.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.client.controller;
import com.example.client.dto.Req;
import com.example.client.dto.UserResponse;
import com.example.client.service.RestTemplateService;
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 {
private final RestTemplateService restTemplateService;
public ApiController(RestTemplateService restTemplateService) {
this.restTemplateService = restTemplateService;
}
@GetMapping("/hello")
public Req<UserResponse> getHello(){
return restTemplateService.genericExchange();
}
}
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/sever/hello
// Response
public UserResponse hello(){
URI uri = UriComponentsBuilder
.fromUriString("http://localhost:9090")
.path("/api/server/hello")
.queryParam("name","이호영")
.queryParam("age","25")
.encode() //파라미터 붙는 경우 대비
.build()
.toUri();
System.out.println(uri.toString());
RestTemplate restTemplate= new RestTemplate();
ResponseEntity<UserResponse> result=restTemplate.getForEntity(uri, UserResponse.class);
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
return result.getBody();
}
public UserResponse post(){
// hhtp://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,"이호영")
.toUri();
System.out.println(uri); //주소만들기
//http body-> object-> objectMapper-> json-> Rest Template-> http body json
UserRequest req= new UserRequest();
req.setName("이호영");
req.setAge(25); //object만들면 objectMapper가 자연적으로 json으로 바꿔줌
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();
}
public UserResponse exchange(){
URI uri=UriComponentsBuilder
.fromUriString(("http://localhost:9090"))
.path("/api/server/user/{userId}/name/{Username}")
.encode()
.build()
.expand(100,"이호영")
.toUri();
System.out.println(uri); //주소만들기
//http body-> object-> objectMapper-> json-> Rest Template-> http body json
UserRequest req= new UserRequest();
req.setName("이호영");
req.setAge(25); //object만들면 objectMapper가 자연적으로 json으로 바꿔줌
RequestEntity<UserRequest> requestEntity= 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(requestEntity,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,"이호영")
.toUri();
System.out.println(uri); //주소만들기
//http body-> object-> objectMapper-> json-> Rest Template-> http body json
UserRequest UserRequest= new UserRequest();
UserRequest.setName("이호영");
UserRequest.setAge(25);
Req<UserRequest> req=new Req();
req.setHeader(
new Req.Header()
);
req.setResbody(
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();
}
}
package com.example.client.dto;
public class Req<T> {
private Header header;
private T resbody; //제네릭 타입
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 getResbody() {
return resbody;
}
public void setResbody(T resbody) {
this.resbody = resbody;
}
@Override
public String toString() {
return "Req{" +
"header=" + header +
", body=" + resbody +
'}';
}
}
package com.example.client.dto;
public class UserRequest {
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 +
'}';
}
}
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 +
'}';
}
}