form 태그 내에 단일 입력 뿐만 아니라 테이블 형태의 입력값도 받아야 하는 경우, 어떻게 한꺼번에 controller 단으로 전송을 해야할지 고민했다.
다른 여러가지 방법들이 있겠지만 이번에는 json 형태로 전송한 데이터를 ObjectMapper를 이용하여 DTO 객체로 파싱해보았다.
.html
var id = $('#id').val();
var pw = $('#pw').val();
var useYn = ($('#useYn').prop('checked'))?'Y':'N';
var paraList = [];
var sendDataGroup = {
'id': id,
'pw': pw,
'useYn': useYn
}
테이블 입력값은 각 row를 배열에 넣기 위해 paraList라는 배열 변수를 선언해주었고 나머지 단순 입력값들은 val() 함수로 입력값을 가져와 변수에 저장했다. 최종적으로 전송할 데이터묶음을 sendDataGroup 변수로 선언했다.
$('#table tbody tr').each(function() {
var param1 = $(this).find("td").eq(0).html();
var param2 = $(this).find("td").eq(1).html();
var param3 = $(this).find("td").eq(2).html();
paraList.push({
"param1": param1,
"param2": param2,
"param3": param3
});
});
sendDataGroup.paraList = paraList;
그리고 .each 함수로 테이블의 tr (row) 단위의 반복문을 돌려서 paraList 배열에 넣어주고 이를 sendDataGroup 에 추가해주었다. 테이블 행마다 각 셀의 입력값은 .find() 함수로 td를 찾은 다음 eq(index)를 사용하여 순차적으로 저장했다. $(this).find("td:eq(index)") 의 형태도 가능하다.
$.ajax({
url: "/admin/manage/ajaxInsert",
type: 'POST',
traditional: true,
data: JSON.stringify(sendDataGroup),
contentType:'application/json; charset=utf-8',
success: function(data) {
if(data.msg == "success") {
alert("저장되었습니다.");
location.reload();
} else {
alert(data.msg);
location.reload();
}
}
});
자바스크립트에서 차곡차곡 모은 데이터를 json 문자열 형태로 전송하기 위해 JSON.stringify() 함수로 변환해준다.
traditional 속성은 전송 데이터가 배열일 때 true를 주면 되는데 여기서 왜 넣었지? 삭제해도 될 듯 하다.
controller.java
@PostMapping("/admin/manage/ajaxInsert")
@ResponseBody
public Map<String, Object> ajaxInsert(HttpServletRequest request, @RequestBody Map<String, Object> data) {
Map<String, Object> result = new HashMap<String, Object>();
try {
ListDTO list = new ListDTO();
list.setId((data.get("id"));
list.setPw((data.get("pw"));
list.setUseYn((data.get("useYn"));
ArrayList<ListParamDTO> rdata = new ArrayList<ListParamDTO>();
if (data.get("paraList") != null) {
ObjectMapper mapper = new ObjectMapper();
rdata = mapper.convertValue(data.get("paraList"), new TypeReference<ArrayList<ListParamDTO>>() {});
}
mgrService.insert(list, rdata);
result.put("msg", "success");
} catch (Exception e) {
e.printStackTrace();
result.put("msg", "Internal Error.");
}
return result;
}
json 파라미터를 받기 위해 @RequestBody 어노테이션을 붙여주었다. 이 어노테이션은 HTTP 요청의 바디 부분을 자바객체로 변환해서 매핑시켜 주기 때문에 get() 함수의 사용이 가능해진다.
또한 ajaxInsert 함수에 붙은 @ResponseBody 어노테이션은 서버에서 클라이언트로 메시지를 전송할 때 자바객체를 HTTP 응답 본문 객체로 변환하여 전송하도록 해준다.
테이블 외의 값들은 ListDTO에 매핑하고 테이블에 있는 값들은 ListParamDTO에 매핑해줄건데 매 행마다 각각 DTO에 저장해야하므로 ArrayList 객체를 생성했다.
json을 DTO 객체로 파싱해줄 ObjectMapper를 사용하기 위해서는 Jackson 라이브러리가 필요하기 때문에 maven depandency를 추가해준다.
ObjectMapper의 convertValue(변환 전 값, 변환 후 클래스) 함수를 사용하여 원하는 형태로 변환 후 사용하면 끝!
이렇게 정리해놓으니 간단해보이지만 꽤나 돌아왔다..