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..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,10 +1,32 @@ package cholog; +//import lombok.AllArgsConstructor; +//import lombok.Data; + +//@Data // getter, setter +//@NoArgsConstructor // 기본 생성자 생성 +//@AllArgsConstructor // 모든 필드를 포함하는 생성자 생성 public class Todo { - // TODO: Todo 객체가 가지는 필드들을 정의 + private Long userId; + private Long id; + 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; } public String getTitle() { - return null; + return title; } + + public boolean getCompleted() { return completed; } } 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..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 @@ -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; @@ -13,13 +15,48 @@ 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) { - // TODO: restClient의 get 메서드를 사용하여 요청을 보내고 결과를 Todo로 변환하여 반환 - // TODO: 존재하지 않는 id로 요청을 보낼 경우 TodoException.NotFound 예외를 던짐 - return new Todo(); + 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; + } + + 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/main/java/cholog/TodoClientWithRestTemplate.java b/spring-http-client-1/initial/src/main/java/cholog/TodoClientWithRestTemplate.java index 0cc73f46..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,5 +1,7 @@ package cholog; +import org.springframework.http.*; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; public class TodoClientWithRestTemplate { @@ -10,8 +12,58 @@ 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()); + } + } + } + + 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/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); + } + } 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 확인 + } }