오류 : java.lang.IllegalStateException: Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]: org.apache.catalina.connector.RequestFacade@
ajax 비동기방식 작성시 multipart값을 받지 못했다.
기존 동기방식의 게시글 작성페이지에서 첨부파일 기능을 추가했었다.
그 후 첨부파일 백단을 조금 손봐서 , ajax를 사용하는 비동기 방식의 댓글 작성에서 첨부파일 기능을 구현하려 했는데,
클라이언트 보낸 multipart 인코딩타입의 첨부파일데이터를 서버에서 받을 수 있도록 처리해주는 multipart라이브러리의 인터페이스인 MultipartHttpServletRequest가 데이터를 받지 못한다는 오류가 발생했다.
일단 이 오류가 뜨는 이유는
1. 폼태그에 enctype="multipart/form-data" 를 넣지 않음
2.컨트롤러에 Multipart라이브러리의 인터페이스를 선언했는데 multipart 값이 오지 않음
3.Multipart라이브러리 설정(xml)들 중 오타나 경로지정이 잘 못 됐을 때
이다.
그래서 오타가 있는지 확인 하고, 컨트롤러에 인터페이스를 제대로 선언했는지 확인하고, 마지막으로 라이브러리 설정들도 경로지정이나 오타가 문제가 없는지 확인했더니 이상이 없었다,
그래서 ajax가 아닌 동기방식으로 따로 폼태그를 만들어서 input file을 넣고 컨트롤러로 multipart값을 submit해봤다.
컨트롤러에
logger.info("mpRequest=" + mpRequest); //mpRequest는 multipart 라이브러리 인터페이스 객체
로그를 추가해서 값이 넘어오나 확인해봤더니 제대로 첨부파일값이 넘어오는 것을 확인.
문제는 ajax 부분이였다.
구글링하고 찾고 찾아 결국
var insertData = new FormData($('#commentInsertForm')[0]);
new FormData($('폼태그')[0]) ; 의 형식으로 ajax전에 폼태그의 값을 변환시켜주면 된다.
json 데이터를 String으로 변환해서 form 데이터로 보내는 방법으로 해결했다.
ajax의 contentType은 application/json인데
multipart/form-data 도 contentType으로 취급되며, 이것은 2개가 될 수 없기 때문에 오류가 나는 것이였다.
폼에서 받는 데이터를 FormData로 변환해주고 !! 문법에 주의..
processData: false, contentType: false
를 ajax안에 넣어준다.
FormData를 사용해서 ajax통신을 할때는
contentType과 processData옵션을 false로 설정해줘야 한다.
contentType의 디폴트값( 아무 설정하지 않았을때) 은 UTF-8이므로 multipart로 전송되도록 false로 설정해준다.
processData는 tdata파라미터로 전달된 데이터를 jQuery 내부적으로 쿼리스트링으로 말들기 때문에, 파일전송의 경우 이를 하지 않아야하기 때문이다.
FormData로 컨트롤러로 넘겨주는 값을 처리해주니 정상작동됐다.