@Controller
public class RegisterController {
@Autowired
UserService userService;
@InitBinder
public void convert(WebDataBinder binder) {
// dateformat으로 변환
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(df,false));
binder.setValidator(new GlobalValidator());
}
@GetMapping("/register")
public String register() {
return "registerForm";
}
@PostMapping("/register")
public String register(@Valid UserDto userDto, BindingResult result, Model m) {
try {
if(!result.hasErrors()) {
userService.registerUser(userDto);
return "registerInfo";
}
throw new Exception("Register failed");
} catch (Exception e) {
e.printStackTrace();
m.addAttribute("userDto", userDto);
m.addAttribute("msg", "REG_ERR");
return "registerForm";
}
}
@PostMapping("/idCheck")
@ResponseBody
public Boolean idcheck(@RequestBody String id) throws Exception {
if(8 <= id.length() && id.length() <= 12 && userService.selectUser(id)==null) {
return true;
}
return false;
}
}
다음과 같이 InitBinder에 Validator를 등록한 경우,
ajax에서 POST 방식으로 데이터를 전송할 때
해당 데이터를 받는 메서드가 InitBinder가 있는 컨트롤러에 포함되어 있는 경우에
java.lang.illegalstateexception: invalid target for validator 라는 에러가 발생한다.
Validator가 POST 방식의 메서드에 적용되기 때문에,
내가 원하지 않던 메서드에도 Validator가 매개변수에 대해 검증을 시도하는 것 같아 보인다.
그러므로 id를 체크하는 메서드를 단순하게 GET 방식으로 바꾸면 해결될 줄 알았는데
Validator 관련 에러는 사라졌지만 새로운 에러가 발생했다.
WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.Boolean com.youtubealbum.myapp.controller.RegisterController.idcheck(java.lang.String) throws java.lang.Exception
GET 방식으로 데이터를 전송하면 쿼리스트링에 데이터가 전달되기 때문에 RequestBody로는 전달이 되지 않는것 같다.
그래서 @RequestBody 애너테이션을 빼고 @RequestParam으로 데이터를 전달 받을 수 있게 하였다.
(기본형 매개변수+String에 @RequestParam이 생략이 가능해서 생략하였음)
@GetMapping("/idCheck")
@ResponseBody
public Boolean idcheck(String id) throws Exception {
if(8 <= id.length() && id.length() <= 12 && userService.selectUser(id)==null) {
return true;
}
return false;
}
이렇게 하니까 더 이상 Validator도 이 메서드에 적용이 되지 않고
원하는 데이터도 이상없이 잘 전달되었다.
알게 된 점은
1. Validator는 POST 방식의 메서드에 적용된다.
2. ajax로 GET 방식을 통해 데이터를 전송하면 쿼리스트링에 데이터를 전송하기 때문에 @RequestBody로
데이터를 받을 수 없으며
대신 @RequestParam으로 데이터를 받는다. (또는 Setter가 있는 객체로 받거나)
(2번에 대해서는 100% 확실하진 않아서 좀 더 알아봐야 할 것 같음
다만 POST 방식으로 데이터를 전송할 때는 @RequestBody로도 이상없이 잘 전달되는거 보면
데이터가 어떻게 전달되느냐에 따라 차이가 나는 것 같음)
검색을 통해 ajax로 POST, GET 방식 데이터 전송에 관하여 알게된 정보로는
POST 방식으로 데이터를 전송받을 때는 Jackson2HttpMessageConverter 가 객체에 데이터를 넣어주고
GET 방식으로 데이터를 전송받을 때는 WebDataBinder를 통해 객체에 있는 Setter로 데이터가 주입이 된다고 한다
즉, POST 방식을 사용해서 데이터를 전송받을 때는 전송받는 객체에 Setter가 없어도 됨
이와 관련된 출처 -> https://jojoldu.tistory.com/407?category=635883
'에러 처리' 카테고리의 다른 글
JPAQueryFactory Bean 생성시 EntityManager를 인수로 받지 못하는 경우 (0) | 2023.08.24 |
---|---|
댓글과 대댓글을 정렬하기 (0) | 2022.06.17 |
[kakao is not defined] 카카오 지도가 페이지에 나오지 않음 (0) | 2022.05.26 |