매일 매일 미라클 코딩

[Mybatis ] insert와 400에러, 그리고 Date 포맷 본문

BackEnd/SPRING

[Mybatis ] insert와 400에러, 그리고 Date 포맷

뚜벅-뚜벅 2021. 4. 13. 23:55

mybatis를 이용해 DB에 값을 넣을때 종종 400 에러를 마주친다

이런 경우 보통 뷰에서 받아온 값이 VO 타입이나 DB 타입에 맞지 않을때 발생하고

특히 VO 중 Date 타입으로 값을 전달할 때 자주 발생한다

 

나의 경우 뷰에서 datepicker 로 날짜값을 받고, VO에서는 Java.util.date 자료형으로 담아줬다.

그리고 최종적으로 MySql 에 datetime 타입으로 insert 해야했다. 

 

 

datepicker로 받은 날짜값 (Date타입)

이렇게 Datepicker 로 받은값을 매핑해주면

보기엔 저래보여도 정상적으로 insertDAO 로 값을 전달한다.

일반적인 form submit 으로 페이지를 이동한다면 이대로 충분하다.

 

문제는 중간에 결제 API 페이지를 추가하면서, vo로 받은 값을 다시 그 다음페이지로 넘겨줄 때 발생하였다

 

 

<form id = "form" method = "post" action="insertRsv.do">
<input type = "hidden" name = "parker_id" value = "${rsvInfo.parker_id}">
<input type = "hidden" name = "parking_id" value = "${rsvInfo.parking_id}" >
<input type = "hidden" name = "rsv_price" value = "${rsvInfo.rsv_price}" >
<input type = "hidden" name = "rsv_intime" id = "rsvIn" value = "${rsvInfo.rsv_intime}">
<input type = "hidden" name = "rsv_outtime" id = "rsvOut" value = "${rsvInfo.rsv_outtime}">
<script>

결제페이지를 지나 예약테이블에 insert 될값을 전달하도록, 결제페이지에 심어준 코드이다

 

 

 

 

이렇게 결제 API가 실행되는 페이지에 숨겨서 값을 넘겨주었다.

결제를 성공적으로 마치고 action ="insertRsv.do" 리퀘스트로 보내줬는데

그때 400번 에러가 발생했다.

이런 경우 콘솔창에 에러메시지도 뜨지않고

insert 리퀘스트로 접근도 하지 않아 디버깅도 불가능하다.

타입문제라고 생각하고 java.util.Date 를 쓰거나 int 형 필드에 null 값이 있지 않은지 확인해야한다. 

 

나같은 경우는 원래 insertDAO 가 잘 실행되던 컨트롤러였으므로, date 포맷에서 문제를 찾았다.

자세히 보니 value에 담긴 date 타입이 아주 약간 다른 것을 알 수 있다.

 

잘 되던 것  : Tue Apr 13 2021 09:00:00 GMT+0900 (대한민국 표준시)

안 되는 것 : Tue Apr 13 09:00:00 KST 2021 

 

날짜선택 -> 결제 페이지로 vo 전달은 정상적으로 된것을 확인할 수 있다.

결제 페이지에서 예약삽입 시 ${rsvInfo.rsv_intime} 을 통해 값을 뷰로 보내면서 전달형식 살짝 바뀐게 문제였다.

더 깔끔해 보여도 아주 머리아픈 문제를 일으킨다... 

 

처음엔 "YYYY-MM-DD" 형식으로 넣어주거나

VO를 아예 String으로 바꾸면 되지 않을까 해서 시도해 봤지만 소용없었다..

Date 는 지저분한 Date 형식으로 넣어줘야한다...!

 

 

광인처럼 검색한 흔적

 

그리하여 Date 형식이 EL문에서 변환된 형태를 다시 Date 형태로 바꿔주는 작업을 하게 되었다.

결론 : 자바의 Date 타입과 SQL Datetime 에 들어가는 날짜데이터를 얻으려면 new Date 로 객체 생성을 해줘야한다. 

 

<fmt:formatDate var="rsvInDt" value="${rsvInfo.rsv_intime}" pattern="YYYY-MM-dd-HH-mm-ss"/>
<fmt:formatDate var="rsvOutDt" value="${rsvInfo.rsv_outtime}" pattern="YYYY-MM-dd-HH-mm-ss"/>
<form id = "form" method = "post" action="insertRsv.do">
<input type = "hidden" name = "parker_id" value = "${rsvInfo.parker_id}">
<input type = "hidden" name = "parking_id" value = "${rsvInfo.parking_id}" >
<input type = "hidden" name = "rsv_price" value = "${rsvInfo.rsv_price}" >
<input type = "hidden" name = "rsv_intime" id = "rsvIn" value = "${rsvInDt}">
<input type = "hidden" name = "rsv_outtime" id = "rsvOut" value = "${rsvOutDt}">
</form>
<script>
const str1 = $("#rsvIn").val();
const str2 = $("#rsvOut").val();
const strArr1 = str1.split('-');
const strArr2 = str2.split('-');
const date1 = new Date(strArr1[0], strArr1[1]-1, strArr1[2],strArr1[3],strArr1[4],strArr1[5]);
const date2 = new Date(strArr2[0], strArr2[1]-1, strArr2[2],strArr2[3],strArr2[4],strArr2[5]);
$("#rsvIn").attr("value",date1);
$("#rsvOut").attr("value",date2);
</script>

 

노가다 같지만...(맞음)

1. fmt: 태그로 date형식을 변환한다. 

2. 변환한 값을 년,월,일,시,분,초 단위로 split 한다. 

3. 쪼개진 배열을 순서대로 new Date 객체로 생성한다.  

4. 생성한 값을 다음페이지로 넘겨줄 input의 value 속성으로 지정해준다

 

 

그결과 지저분한 본래 형태로 돌아온것을 볼 수 있다.

역시 이대로 값을 넘겨주니 컨트롤러 내에서 커맨드 객체로 잘 받아졌다.

 

정리

java.util.Date 필드에 값을 전달하려면 뷰단에서도 Date 형식으로 받아줘야한다. 
이 Date 형식은 날짜객체로 생성된 상태일 때 원활히 전달된다.
피치못하게 "YYYY-MM-DD" 같은 예쁜 모양으로 값을 받았다면, 자바스크립트 split() 함수와 new Date() 를 활용해 새로운 Date 객체를 생성하고 해당 값을 전달한다.