HttpRequest를 사용하려 했는데, 서비스 D의 경우 java 1.8을 사용하고 있어서 HttpRequest 적용이 안 되었다... ㅎ;;
결국 HttpEntity와 ResponseEntity를 이용하여 작업을 진행했는데, 이 과정에서 HttpClient, HttpRequest, HttpResponse, HttpEntity, ResponseEntity에 대하여 공부한 기록을 남겨보려고 한다.
HttpClient, HttpRequest, HttpResponse
HTTP Client는 Java 11에서 추가되었고, HTTP request를 이용하는데 사용한다.
HTTP/1.1과 HTTP/2, 동기식 비동기식 프로그래밍을 지원하고, request와 response bodies를 reactive-streams로 다룬다.
reactive streams: non-blocking, backPressure을 이용하여 비동기 서비스를 할 때 기본이 되는 스펙. java의 RxJava, Spring5 Webflux의 Core에 있는 ProjectReactor 프로젝트 모두 해당 스펙을 따른다고 한다.
GET request후, response body를 프린트하는 예제
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://openjdk.java.net/"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
HttpClient
request를 보내기 위해서 HttpClient를 먼저 생성해야 한다. 한 번 HttpClient를 생성하면 여러 request에 사용할 수 있다.
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_2)
.followRedirects(Redirect.SAME_PROTOCOL)
.proxy(ProxySelector.of(new InetSocketAddress("www-proxy.com", 8080)))
.authenticator(Authenticator.getDefault())
.build();
HttpRequest
한 번 생성한 HttpRequest는 변경 불가하고, 여러번 보낼 수 있다.
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://openjdk.java.net/")
.timeout(Duration.ofMinutes(1))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofFile(Paths.get("file.json")))
.build()
Synchronous or Asynchronous
request는 동기, 비동기로 모두 가능하다. 동기식으로 한다면 HttpResponse가 되는 동안 block이 생길 것이다.
HttpResponse<String> response =
client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
비동기식은 CompletableFuture와 함께 return 된다. CompletableFuture는 Java8에서 추가되었다.
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(response -> { System.out.println(response.statusCode());
return response; })
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
HttpEntity, ResponseEntity
HttpEntity
springframework.http안에 속한다.
RestTemplate과 함께 사용되는 경우가 많다.
HttpHeader headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<String> entity = new HttpEntity<>("Hello World", headers);
URI location = template.postForLocation("https://example.com", entity);
Spring MVC 에서 다음과 같이 사용될 수 있다고 한다.
@GetMapping("/handle")
public HttpEntity<String> handle() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new HttpEntity<>("Hello World", responseHeaders);
}
ResponseEntity
마찬가지로 springframework.http안에 속하고, HttpStatus status code가 포함된 HttpEntity의 확장이다.
@Controller에서 RestTemplate과 함께 쓰인다.
RestTemplate에서 getForEntity()와 exchange()에 의해 return 된다.
@RequestMapping("/handle")
public ResponseEntity<String> handle() {
URI location = "";
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setLocation(location);
responseHeaders.set("MyResponseHeader", "MyValue");
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}
Reference
[참고 1]
https://openjdk.org/groups/net/httpclient/intro.html
[참고 2]
https://brush-up.github.io/java/java11-http-client/
[참고 3]
https://sabarada.tistory.com/98
[참고 4]
'Spring' 카테고리의 다른 글
Builder 패턴 (0) | 2022.09.02 |
---|---|
ResponseEntity (0) | 2022.09.02 |
Exception 공부 (0) | 2022.08.31 |
RestTemplate, WebClient (0) | 2022.08.24 |
@RequestParam, @PathVariable (0) | 2022.08.19 |