일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 자바편
- 코드로배우는스프링웹프로젝트
- ㅒ
- 처음 만나는 AI수학 with Python
- 코드로배우는스프링부트웹프로젝트
- 스프링부트핵심가이드
- iterator
- 티스토리 쿠키 삭제
- baeldung
- network configuration
- 선형대수
- 데비안
- 이터레이터
- resttemplate
- /etc/network/interfaces
- 목록처리
- 알파회계
- d
- 처음 만나는 AI 수학 with Python
- 구멍가게코딩단
- 자료구조와 함께 배우는 알고리즘 입문
- 자료구조와함께배우는알고리즘입문
- 리눅스
- 서버설정
- 친절한SQL튜닝
- Kernighan의 C언어 프로그래밍
- GIT
- 페이징
- 스프링 시큐리티
- 네트워크 설정
- Today
- Total
bright jazz music
blog12: 예외처리2 본문
예외처리 1에서는 정상적이지 않은 입력값이 들어갔을 경우의 예외처리를 구성하였다.
이번에는 PostController에서 발생할 수 있는 오류에 대한 예외처리를 만들고 테스트한다.
우선 단건 조회부터.
//PostService.java
//...
//단건 조회
public PostResponse get(Long id) {
Post post = postRepository.findById(id)
// .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 글입니다.")); //있으면 post반환 없으면 에러 반환
// .orElseThrow(() -> new PostNotFound());
.orElseThrow(PostNotFound::new); //위와 같은 표현
//또한 IllegalArgumentException과 같은 자바 기본제공 에러들은 우리의 에러를 명확히 표현해 주지는 못함.
// 이렇게 처리해주면 굳이 test에서 전부 메시지를 확인할 필요가 없다. 이 에러가 발생했다면 글을 찾지 못했다는 뜻이기 때문이다.
//응답 클래스를 분리
return PostResponse.builder()
.id(post.getId())
.title(post.getTitle())
.content(post.getContent())
.build();
}
위에서 보듯이 현재 단건조회에 대한 입력 오류는 PostNotFound 클래스를 통해 메시지를 반환해야 한다.
현재 예외는 내가 만든 ExceptionController(@ControllerAdvice부착)가 해결하고 있다.
따라서 ExceptionController에서 PostNotFound를 활용해 에러를 반환할 수 있도록 해줘야 한다.
이러한 처리를 하지 않은 상태에서 블라우저를 사용하여 글을 단건 조회하면(e.g. localhost:8080/posts/1), 500에러가 떨어진다.
ExceptionController에 PostNotFound 처리 추가하기
//ExceptionController.java
package com.endofma.blog.controller;
import com.endofma.blog.exception.PostNotFound;
import com.endofma.blog.response.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@ControllerAdvice
public class ExceptionController {
//...
@ResponseBody
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(PostNotFound.class)
public ErrorResponse postNotFound(PostNotFound e) {
ErrorResponse response = ErrorResponse.builder()
.code("404")
.message(e.getMessage()) //익셉션으로 받은 에러 메시지 "PostNotFound=>존재하지 않는 글입니다."
.build();
return response; //@Response바디가 붙었으므로 json으로 반환
}
}
위에서는 validation 필드가 비어 있는데, 만약 빈 필드가 반환되는 것이 싫다면 해당 필드를 가진 클래스의 선언부 위에 아래의 코드를 추가해 주면 된다.
@JsonInclude(value = JsonInclude.Include.NON_EMPTY) //비어있지 않은 데이터만 보낸다.
public class ExampleClass{ //... }
edit()에 관한 컨트롤러 테스트 에러추
@Test
@DisplayName("존재하지 않는 게시글 수정")
void test10() throws Exception{
//given
ObjectMapper objectMapper = new ObjectMapper();
PostEdit postEdit = PostEdit.builder()
.title("블로그 수정")
.content("부림동 ").build();
//excepted
mockMvc.perform(patch("/posts/{postId}", 1L)
.contentType(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(postEdit)))
// .andExpect(status().isOk())
.andExpect(status().isNotFound())
.andDo(print());
/*
MockHttpServletResponse:
Status = 404
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body = {"code":"404","message":"PostNotFound=>존재하지 않는 글입니다.","validation":{}}
Forwarded URL = null
Redirected URL = null
Cookies = []
*/
---
잘못된 요청에 대한 예외에 대응하기 위해 exception패키지에 InvalidRequest.java 클래스를 만들어 주었다.
//InvalidRequest.java
package com.endofma.blog.exception;
public class InvalidRequest extends RuntimeException {
private static final String MESSAGE ="잘못된 요청입니다.";
public InvalidRequest() {
super(MESSAGE);
}
//글 작성 등에서 글 작성에서 @NotBlank와 같은 어노테이션으로
//해결할 수 없을 경우 추가적인 방법이 필요할 때.
//PostController의 post()에 보내는 요청의 제목에 "바보"라는 글자를 넣을 수 없다면.
}
컨트롤러에는 아래와 같이 적어주었다.
//PostController.java
@PostMapping("/posts")
public void post(@RequestBody @Valid PostCreate request) {
//PostController의 post()에 보내는 요청의 제목에 "바보"라는 글자를 넣을 수 없다면.
if(request.getTitle().contains("바보")){
throw new InvalidRequest();
}
postService.write(request);
// return Map.of();
}
테스트를 아래와 같이 작성하였다.
//PostControllerTest.java
@Test
@DisplayName("게시글 작성 시 제목에 '바보'는 포함될 수 없다.")
void test11() throws Exception{
//given
PostCreate request = PostCreate.builder()
.title("나는 바보입니다.")
.content("제이드빌.")
.build();
String json = objectMapper.writeValueAsString(request);
//when
mockMvc.perform(post("/posts")
.contentType(APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andDo(print());
}
/*
Request processing failed; nested exception is com.endofma.blog.exception.InvalidRequest: 잘못된 요청입니다.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.endofma.blog.exception.InvalidRequest: 잘못된 요청입니다.
at app//org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at app//org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
*/
'Projects > blog' 카테고리의 다른 글
blog12: 예외처리 4 (0) | 2023.01.14 |
---|---|
blog12: 예외처리 3 (0) | 2023.01.14 |
blog12: 예외처리1 (0) | 2023.01.10 |
blog11: 게시글 삭제 (0) | 2023.01.10 |
blog10: 게시글 수정 2 (오류수정, 보충) (0) | 2023.01.09 |