From 9690a7d0599647fd41a4a90a3e91bf70c8c57693 Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 14:36:13 +0900 Subject: [PATCH 1/7] =?UTF-8?q?Task=202.1.=20GET=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20/=20RestTemplate=20=EC=9D=98=20getForEntit?= =?UTF-8?q?y()=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=B4=20HTTP=20GET=20=EC=9A=94=EC=B2=AD=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../initial/src/main/java/cholog/Todo.java | 13 +++++++++++-- .../cholog/TodoClientWithRestTemplate.java | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/spring-http-client-1/initial/src/main/java/cholog/Todo.java b/spring-http-client-1/initial/src/main/java/cholog/Todo.java index 7f3644aa..cb7ef5a9 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/Todo.java +++ b/spring-http-client-1/initial/src/main/java/cholog/Todo.java @@ -2,9 +2,18 @@ public class Todo { - // TODO: Todo 객체가 가지는 필드들을 정의 + private Long userId; + private Long id; + private String title; + private boolean completed; + + public Long getUserId() { return userId; } + + public Long getId() { return id; } public String getTitle() { - return null; + return title; } + + public boolean getCompleted() { return completed; } } diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java index 0cc73f46..8bcf911b 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java @@ -1,5 +1,8 @@ package cholog; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; public class TodoClientWithRestTemplate { @@ -10,8 +13,17 @@ public TodoClientWithRestTemplate(RestTemplate restTemplate) { } public Todo getTodoById(Long id) { - // TODO: restTemplate을 사용하여 요청을 보내고 결과를 Todo로 변환하여 반환 - // TODO: 존재하지 않는 id로 요청을 보낼 경우 TodoException.NotFound 예외를 던짐 - return new Todo(); + String resourceUrl = "http://jsonplaceholder.typicode.com/todos/{id}"; +// String resourceUrl = "http://jsonplaceholder.typicode.com/todos/" + id; + try { + ResponseEntity response = restTemplate.getForEntity(resourceUrl, Todo.class, id); + return response.getBody(); + } catch (HttpClientErrorException e) { + if(e.getStatusCode() == HttpStatus.NOT_FOUND) { + throw new TodoException.NotFound(id); + } else { + throw new TodoException("다른 에러: " + e.getMessage()); + } + } } } From 368002bb45d2801dbbd06dce8ea49fa7778c8e1e Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 14:45:41 +0900 Subject: [PATCH 2/7] =?UTF-8?q?Task=202.2.=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20/=20HttpStatus.NOT=5FFOUND=20=EB=A1=9C=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20id?= =?UTF-8?q?=EC=9D=98=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cholog/TodoClientWithRestTemplate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java index 8bcf911b..88d9959f 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java @@ -22,7 +22,7 @@ public Todo getTodoById(Long id) { if(e.getStatusCode() == HttpStatus.NOT_FOUND) { throw new TodoException.NotFound(id); } else { - throw new TodoException("다른 에러: " + e.getMessage()); + throw new TodoException("다른 에러 : " + e.getMessage()); } } } From 34f3439fd3eadb75ae065b9a60f6beb499652506 Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 15:15:40 +0900 Subject: [PATCH 3/7] =?UTF-8?q?Task=203.1.=20GET=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20/=20RestClient=20=EC=9D=98=20get()=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=B4=20HTTP=20GET=20=EC=9A=94=EC=B2=AD=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cholog/TodoClientWithRestClient.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java index ab2b6f5c..50ae0b52 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java @@ -13,8 +13,13 @@ public TodoClientWithRestClient(RestClient restClient) { } public List getTodos() { - // TODO: restClient의 get 메서드를 사용하여 요청을 보내고 결과를 Todo 리스트로 변환하여 반환 - return Collections.emptyList(); + //RestClient.builder().baseUrl("http://jsonplaceholder.typicode.com").build() +// String uri = "http://jsonplaceholder.typicode.com/todos"; + List todos = restClient.get() + .uri("/todos") + .retrieve() + .body(List.class); + return todos; } public Todo getTodoById(Long id) { From 27fb79b526453f51d58b8928e923f3f83a51923c Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 15:25:09 +0900 Subject: [PATCH 4/7] =?UTF-8?q?Task=203.2.=20GET=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=9D=98=20=EC=9D=91=EB=8B=B5=20=EB=B3=80=ED=99=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20/=20RestClient=20=EC=9D=98=20body()=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=B4=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EB=B3=80=ED=99=98=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cholog/TodoClientWithRestClient.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java index 50ae0b52..0f70ea6b 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java @@ -1,5 +1,7 @@ package cholog; +import org.springframework.http.HttpStatus; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestClient; import java.util.Collections; @@ -23,8 +25,18 @@ public List getTodos() { } public Todo getTodoById(Long id) { - // TODO: restClient의 get 메서드를 사용하여 요청을 보내고 결과를 Todo로 변환하여 반환 - // TODO: 존재하지 않는 id로 요청을 보낼 경우 TodoException.NotFound 예외를 던짐 - return new Todo(); + try { + Todo todo = restClient.get() + .uri("/todos/{id}", id) + .retrieve() + .body(Todo.class); + return todo; + } catch (HttpClientErrorException e) { + if(e.getStatusCode() == HttpStatus.NOT_FOUND) { + throw new TodoException.NotFound(id); + } else { + throw new TodoException("다른 에러 : " + e.getMessage()); + } + } } } From 02bae14dc5bddf64973ec8b21bd85022539d2cff Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 15:37:59 +0900 Subject: [PATCH 5/7] =?UTF-8?q?Task=203.3.=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20/=20RestClient=20=EC=9D=98=20onStatus()=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=B4=20HTTP=20=EC=9D=91=EB=8B=B5=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cholog/TodoClientWithRestClient.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java index 0f70ea6b..8d339e4a 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java @@ -25,18 +25,13 @@ public List getTodos() { } public Todo getTodoById(Long id) { - try { - Todo todo = restClient.get() - .uri("/todos/{id}", id) - .retrieve() - .body(Todo.class); - return todo; - } catch (HttpClientErrorException e) { - if(e.getStatusCode() == HttpStatus.NOT_FOUND) { - throw new TodoException.NotFound(id); - } else { - throw new TodoException("다른 에러 : " + e.getMessage()); - } - } + Todo todo = restClient.get() + .uri("/todos/{id}", id) + .retrieve() + .onStatus(status -> status.value() == 404, (req, res) -> { + throw new TodoException.NotFound(id); + }) + .body(Todo.class); + return todo; } } From b5f6f91425735dd4d6aec484fda69557f4960e57 Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 18:51:09 +0900 Subject: [PATCH 6/7] =?UTF-8?q?Task=204.=20RestTemplate=20-=20post,=20put,?= =?UTF-8?q?=20delete=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../initial/src/main/java/cholog/Todo.java | 13 ++++++ .../cholog/TodoClientWithRestTemplate.java | 44 ++++++++++++++++++- .../test/java/cholog/RestTemplateTest.java | 31 +++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/spring-http-client-1/initial/src/main/java/cholog/Todo.java b/spring-http-client-1/initial/src/main/java/cholog/Todo.java index cb7ef5a9..e0baff68 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/Todo.java +++ b/spring-http-client-1/initial/src/main/java/cholog/Todo.java @@ -1,5 +1,11 @@ package cholog; +//import lombok.AllArgsConstructor; +//import lombok.Data; + +//@Data // getter, setter +//@NoArgsConstructor // 기본 생성자 생성 +//@AllArgsConstructor // 모든 필드를 포함하는 생성자 생성 public class Todo { private Long userId; @@ -7,6 +13,13 @@ public class Todo { private String title; private boolean completed; + public Todo(Long userId, Long id, String title, boolean completed) { // -> AllArgsConstructor (Lombok) + this.userId = userId; + this.id = id; + this.title = title; + this.completed = completed; + } + public Long getUserId() { return userId; } public Long getId() { return id; } diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java index 88d9959f..ad48986c 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java @@ -1,7 +1,6 @@ package cholog; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; @@ -26,4 +25,45 @@ public Todo getTodoById(Long id) { } } } + + public Todo createTodo(Todo newTodo) { + String resourceUrl = "http://jsonplaceholder.typicode.com/todos"; + try { + ResponseEntity response = restTemplate.postForEntity(resourceUrl, newTodo, Todo.class); + return response.getBody(); + } catch (HttpClientErrorException e) { + throw new TodoException("Todo 생성 중 에러 발생: " + e.getMessage()); + } + } + + public Todo updateTodo(Long id, Todo updatedTodo) { + String resourceUrl = "http://jsonplaceholder.typicode.com/todos/{id}"; + try { + HttpEntity requestUpdate = new HttpEntity<>(updatedTodo); + ResponseEntity response = restTemplate.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Todo.class, id); + return response.getBody(); + } catch (HttpClientErrorException e) { + if(e.getStatusCode() == HttpStatus.NOT_FOUND) { + throw new TodoException.NotFound(id); + } else { + throw new TodoException("Todo 업데이트 중 에러 발생: " + e.getMessage()); + } + } + } + + public HttpStatusCode deleteTodo(Long id) { + try { + String resourceUrl = "http://jsonplaceholder.typicode.com/todos/{id}"; + restTemplate.delete(resourceUrl, id); +// ResponseEntity response = restTemplate.exchange(resourceUrl, HttpMethod.DELETE, null, Void.class, id); +// return response.getStatusCode(); + return HttpStatus.OK; + } catch (HttpClientErrorException e) { + if(e.getStatusCode() == HttpStatus.NOT_FOUND) { + throw new TodoException.NotFound(id); + } else { + throw new TodoException("Todo 삭제 중 에러 발생: " + e.getMessage()); + } + } + } } diff --git a/spring-http-client-1/initial/src/test/java/cholog/RestTemplateTest.java b/spring-http-client-1/initial/src/test/java/cholog/RestTemplateTest.java index 7217ab08..b7e75efa 100644 --- a/spring-http-client-1/initial/src/test/java/cholog/RestTemplateTest.java +++ b/spring-http-client-1/initial/src/test/java/cholog/RestTemplateTest.java @@ -3,6 +3,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; + +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -26,4 +30,31 @@ public void testGetTodoWithNonExistentId() { assertThatThrownBy(() -> todoClient.getTodoById(nonExistentId)) .isInstanceOf(TodoException.NotFound.class); } + + @Test + public void testCreateTodo() { + Todo newTodo = new Todo(2L, 2L, "New Todo", false); + Todo createdTodo = todoClient.createTodo(newTodo); + + assertThat(createdTodo).isNotNull(); + assertThat(createdTodo.getTitle()).isEqualTo(newTodo.getTitle()); + } + + @Test + public void testUpdateTodo() { + testCreateTodo(); + + Todo updatedTodo = new Todo(2L, 2L, "Updated Todo", true); + Todo resultTodo = todoClient.updateTodo(2L, updatedTodo); + + assertThat(resultTodo).isNotNull(); + assertThat(resultTodo.getTitle()).isEqualTo("Updated Todo"); + } + + @Test + public void testDeleteTodo() { + // DELETE 요청을 보내고 상태 코드 확인 + HttpStatusCode deleteStatus = todoClient.deleteTodo(3L); + assertThat(deleteStatus).isEqualTo(HttpStatus.OK); // 204 No Content 확인 + } } From ba25eff4ac7714489ee23956c0d80cbf004de920 Mon Sep 17 00:00:00 2001 From: LocKey Date: Mon, 26 Aug 2024 19:38:37 +0900 Subject: [PATCH 7/7] =?UTF-8?q?Task=204.=20RestClient=20-=20post,=20put,?= =?UTF-8?q?=20delete=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cholog/TodoClientWithRestClient.java | 25 +++++++++++++++ .../src/test/java/cholog/RestClientTest.java | 32 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java index 8d339e4a..39c44572 100644 --- a/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java +++ b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestClient.java @@ -34,4 +34,29 @@ public Todo getTodoById(Long id) { .body(Todo.class); return todo; } + + public Todo createTodo(Todo newTodo) { + Todo createdTodo = restClient.post() + .uri("/todos") + .body(newTodo) + .retrieve() + .body(Todo.class); + return createdTodo; + } + + public Todo updateTodo(Long id, Todo updatedTodo) { + Todo updatedResult = restClient.put() + .uri("/todos/{id}", id) + .body(updatedTodo) + .retrieve() + .body(Todo.class); + return updatedResult; + } + + public void deleteTodo(Long id) { + restClient.delete() + .uri("/todos/{id}", id) + .retrieve() + .toBodilessEntity(); // DELETE 요청에 대한 응답 본문이 필요 없으므로 toBodilessEntity 사용 + } } diff --git a/spring-http-client-1/initial/src/test/java/cholog/RestClientTest.java b/spring-http-client-1/initial/src/test/java/cholog/RestClientTest.java index 1aaf5f7c..b01f4abc 100644 --- a/spring-http-client-1/initial/src/test/java/cholog/RestClientTest.java +++ b/spring-http-client-1/initial/src/test/java/cholog/RestClientTest.java @@ -3,6 +3,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import java.util.List; @@ -34,4 +36,34 @@ public void testGetTodoWithNonExistentId() { assertThatThrownBy(() -> todoClient.getTodoById(nonExistentId)) .isInstanceOf(TodoException.NotFound.class); } + + @Test + public void testCreateTodo() { + Todo newTodo = new Todo(2L, 2L, "New Todo", false); + Todo createdTodo = todoClient.createTodo(newTodo); + + assertThat(createdTodo).isNotNull(); + assertThat(createdTodo.getTitle()).isEqualTo(newTodo.getTitle()); + } + + @Test + public void testUpdateTodo() { + testCreateTodo(); + + Todo updatedTodo = new Todo(2L, 2L, "Updated Todo", true); + Todo resultTodo = todoClient.updateTodo(2L, updatedTodo); + + assertThat(resultTodo).isNotNull(); + assertThat(resultTodo.getTitle()).isEqualTo("Updated Todo"); + } + + @Test + public void testDeleteTodo() { + todoClient.deleteTodo(2L); + + //삭제된 후, 해당 id로 getTodoById를 호출하면 TodoException.NotFound 예외가 발생하는지를 검증 + // 예외를 발생하는지 -> NotFound class 인지 +// assertThatThrownBy(() -> todoClient.getTodoById(2L)).isInstanceOf(TodoException.NotFound.class); + } + }