이메일 입력값에서 점(.) 이후의 값이 잘려서 넘어온다?
이메일 중복 확인 테스트가 계속 실패했다.
먼저 코드를 확인해보자. 아래 코드는 Controller 클래스의 메소드 그리고 해당 메소드의 테스트 코드이다.
구현 코드
@GetMapping("/email/{userEmail}")
public ResponseEntity<Void> checkUserEmail(@PathVariable("userEmail") String userEmail) {
try {
service.isExistUserEmail(userEmail);
} catch (EmailAlreadyExistsException e) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
return new ResponseEntity<Void>(HttpStatus.OK);
}
테스트 코드
@Test
public void C_이메일_중복_확인_테스트() throws Exception {
mockMvc.perform(get("/users/email/tomato@naver.com")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isConflict());
}
tomato@naver.com이 DB에 저장되어 있는지 중복 여부를 확인하는 테스트. 이미 해당 이메일 주소는 DB에 삽입되어 있으므로 409 상태 코드를 반환해야 한다. 그런데 계속 200 상태 코드를 반환했다. 즉 해당 이메일 주소가 DB에 없다는 것이다.
로그에 출력된 SQL 구문은 다음과 같다.
이상하다. .com 없이 tomato@naver만 출력되었다. 점(.)과 함께 점(.) 뒤의 글자가 인식되지 않은 것이다.
SELECT COUNT(user_email) FROM site_user WHERE user_email = 'tomato@naver'
스프링은 점(.) 뒤의 문자는 파일 확장자로 인식한다. ( .json / .xml)
따라서 이메일 주소 뒤의 .com을 파일 확장자로 인식해서 .com을 잘라버린 것이다. tomato@naver를 파라미터 값으로 사용하기 위해서.
이렇게 해결했습니다.
첫 번째 방법은 점(.)이 삽입되는 @PathVariable 변수에 :.* 를 추가하는 것.
{userEmail:.+}로 입력해도 작동한다.
@GetMapping("/email/{userEmail:.*}")
public ResponseEntity<Void> checkUserEmail(@PathVariable("userEmail") String userEmail) {
try {
service.isExistUserEmail(userEmail);
} catch (EmailAlreadyExistsException e) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
return new ResponseEntity<Void>(HttpStatus.OK);
}
두 번째 방법은 슬래시(/) 기호를 통해 해당 값은 URI 값으로 사용되는 것이라고 스프링에 알리는 것이다.
이 방법으로 테스트 해보니 404 상태값을 반환한다. 슬래시를 통해 다음 자원으로 이동하도록 URI를 수정했지만, 더 이상 추가 경로를 입력하지 않았기 때문이다. userEmail 값 이후로 더이상 추가될 값이 없기 때문에 본인의 경우 이 방법을 사용할 수 없다. 따라서 URI의 마지막이 아닌 중간에 값이 삽입되는 경우 유용하게 사용할 수 있겠다.
@GetMapping("/email/{userEmail}/")
public ResponseEntity<Void> checkUserEmail(@PathVariable("userEmail") String userEmail) {
try {
service.isExistUserEmail(userEmail);
} catch (EmailAlreadyExistsException e) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
return new ResponseEntity<Void>(HttpStatus.OK);
}
세 번째 방법은 @Configuration 어노테이션을 사용해 스프링 설정 클래스를 생성하여 프로젝트 전역에 걸쳐 영향을 받도록 설정하는 것이다. 해당 코드는 아래 참고 링크를 통해 얻을 수 있다.
참고
'Programming > Spring' 카테고리의 다른 글
[Spring] Spring MVC 프로젝트 정적 리소스 접근 경로 설정 (0) | 2022.04.01 |
---|---|
[Spring] 제어의 역전 그리고 의존성 주입 (0) | 2022.02.22 |
ambiguous handler methods mapped for... (0) | 2022.02.12 |
[Spring] XML 대신 Java 클래스 파일로 스프링 관련 설정하기 (0) | 2022.02.03 |
[Spring Boot] Path with "WEB-INF" or "META-INF" 에러 (0) | 2021.11.11 |