Thymeleaf 로 뷰를 만들다 보면 JavaScript 의 ajax가 아닌 HTML Form태그 만으로 데이터 전송을 해야할 때가 있다.
이 때 로그인 인증을 위한 csrf 토큰을 보냄과 동시에 multipart 로 데이터와 이미지를 동시에 보내야 하는 상황이여서 막막했던 차에 좋은 해결 방법을 찾아서 공유한다.
우선 소스코드는 아래와 같다.
<form name="form" action="url" method="post"
enctype="multipart/form-data">
<input type="hidden" name="_csrf" th:value="${_csrf.token}">
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
<span>
텍스트 <span class="required">*</span>
</span>
<input type="text" class="input-field" id="data" name="data"/>
<span>
이미지 <span class="required">*</span>
</span>
<input type="file" name="image" id="image" accept="image/*">
<label>
<span>
</span>
<input type="submit" value="Submit"/>
</label>
</form>
1. 로그인 세션 문제
흔히 웹사이트들은 권한이 필요한 페이지들은 유저들이 로그인 한 정보를 토큰으로 남기고 이 토큰을 같이 전송해서 로그인 한 유저가 보낸 요청이라는 것을 서버에 알린다.
ajax 에서는 beforeSend 를 통해 미리 토큰을 보내 해결할 수 있지만 form 태그에서는 어떻게 보낼 지 막막하던 차에
hidden 으로 input 을 넣고 value 를 thymeleaf의 th:value 를 이용하여 토큰을 보내면 해결 된다는 것을 알게 되었다.
2. multipart 전송 문제
데이터를 보낼 때 이미지와 input 데이터를 같이 보낼 때는 form 태그에 enctype="multipart/form-data" 를 넣어주면 된다.
이 때 각 input 에서 name 값을 뭘로 설정하였는지가 중요하다.
위와 같이 HTML 뷰 코드를 만들었다면 서버에서 데이터를 받아오는 것은 간단하다.
Spring Controller 단에서 보낸 데이터를 받아 올 때는 아래와 같이 어노테이션을 넣어주면 된다.
@PostMapping(value = "/url")
public String formData(@ModelAttribute DTO dto, @RequestPart MultipartFile image) {
...
}
@ModelAttribute 는 생략 가능하며 DTO 객체 안에 뷰에서 보낼때 사용한 input 필드 name인 data라는 필드가 있다면 값이 자동으로 매핑된다.
Multipart로 나눠서 보낸 이미지 데이터의 경우, @RequestPart 로 이미지가 있는 파일을 가져올 수 있다.
사실 이 @RequestPart 를 사용하면 Multipart 라는 것 자체가 HTTP Request Body 내부에 여러 part 로 데이터를 영역을 나눠서 넣었다는 의미이기 때문에 변수 명만 맞춰서 적어주면 사진이 여러장이여도, 원하는 데이터를 지정해서 가져올 수 있다.
'Backend > Spring' 카테고리의 다른 글
테스트 케이스 돌리니 TestEngine with ID 'junit-vintage' failed to discover tests 오류가 뜨는 경우 (0) | 2021.11.06 |
---|---|
[Spring] HTTP Range Requests 를 이용한 비디오 스트리밍 만들기(Video Streaming) (0) | 2021.02.07 |
[Spring] 쉽게 익히는 JDBC Template 사용법 및 간단 예제 (0) | 2020.11.30 |
[Spring]AOP의 개념 및 적용 예제(공통관심사 처리하기) (1) | 2020.11.23 |
[Spring]Request Scope를 사용해서 깔끔하게 로그남기기 (0) | 2020.11.19 |