JSP에서 Controller 로 데이터 전달
form 태그 사용 방식
- JSP
<form id="menuForm" action="/menu/insertMenu.do" method="post">
<!-- s: 넘길 data -->
<input type="hidden" name="fileYn" value="N">
<input type="hidden" name="registUserId" value="${loginUser.userId}">
<input type="hidden" name="menuUrl" value="/board/boardList.do">
<input type="hidden" name="linkYn" value="N">
<input type="hidden" name="noticeYn" value="N">
<input type="hidden" name="delYn" value="N">
<input type="hidden" name="updatePos" value="Y">
<!-- e: 넘길 data -->
<div class="surv">
<div class="mb-3 d-flex">
<label for="menuName" class="form-label">메뉴명</label>
<input type="text" class="form-control" id="menuName" name="menuName">
</div>
<div class="mb-3 d-flex">
<label for="menuType" class="form-label">게시판유형</label>
<select class="form-select" aria-label="Default select example" name="menuType" onchange="menuTypeChanged(this)">
<option value="general" selected>일반게시판</option>
<option value="gallery">갤러리게시판</option>
<option value="link">링크게시판</option>
</select>
</div>
</div>
</form>
<div class="mt-5 mb-5 text-center">
<button type="button" class="btn btn-secondary" onclick="moveBack()">취소</button>`
<button type="button" class="btn btn-primary" onclick="insertMenu()">등록</button>
</div>
form 태그 사용 시 input 태그의 key 값으로는 name 속성, value 값으로는 value 속성이 전달된다.
데이터를 전달 받으려는 컨트롤러에서는 Vo를 선언하고 name 속성의 이름이 Vo 필드와 매핑되어 전달된다.
이 때 버튼의 위치에 따라 데이터를 전송하는 시점이 달라진다.
버튼이 form 태그 안에 있게 되면 버튼 클릭시 form 태그 안의 url 로 바로 데이터를 전달 할 수 있다.
그 경우 <form action="/board/insBoardPost.do"> 이와 같이 form 태그의 action 속성을 이용해 url 을 매핑한다.
위 코드 처럼 버튼의 form 태그 밖에 있게 되면 onclick 메서드를 이용해 좀 더 다양한 전처리를 할 수 있다.
- script
<script type="text/javascript">
// 등록 버튼 클릭
function insertMenu() {
// 메뉴 등록 정보 유효성 체크
if (!menuValidation()) {
return;
}
let form = document.getElementById('menuForm');
let formData = new FormData(form);
form.submit();
}
</script>
위 스크립트와 같이 동적인 상황 필요없는 상황에서 단순 데이터만 전달할 때는 form.submit() 을 이용한다.
위에서 언급했던 것처럼 버튼은 form 태그 밖에 위치하면 onclick 으로 function 을 걸어서 데이터 유효성 검사 등 전처리가 가능하다.
- Vo
@Data
public class MenuVO {
private Integer menuNo;
private String menuName;
private String fileYn;
private String noticeYn;
private String delYn;
private String registDt;
private String updateDt;
private Integer registUserId;
private Integer accessRight;
private String showYn;
private Integer menuOrder;
private String menuUrl;
private String linkYn;
private String linkUrl;
private String updatePos;
}
JSP 파일에서 form 태그 안의 name 속성과 객체 필드 이름이 일치해야 한다.
- Controller
/*
* 메뉴 등록
*/
@PostMapping("/menu/insertMenu.do")
public String insertMenu(MenuVO menuVo, Model model) {
int result = menuService.insertMenu(menuVo);
if (result != 0) {
model.addAttribute("msg", "메뉴등록이 완료되었습니다.");
}
else {
model.addAttribute("msg", "메뉴등록을 실패했습니다.");
}
return "menu/menuRegister.tiles";
}
컨트롤러에서 데이터를 받을 때 파라미터에 객체를 적어두면 매핑되어 데이터가 들어간다.
ajax 이용 방식
- JSP
// 피드 등록 버튼 클릭
function insertSns() {
let editorContent = editor.getData();
// 유효성 검사
if (!snsFeedValidation(editorContent)) {
editor.focus();
return;
}
$.ajax({
type: 'post', // 요청 방식
url: '/sns/insertSnsFeed.do', // 요청 url 주소
data: {
menuNo: $('input[name=menuNo]').val(),
writer: '${loginUser.userId}',
content: editorContent,
pId: $('input[name=pId]').val(),
depth: $('input[name=depth]').val()
}, // 전달할 데이터 -> 여러 형태가 될 수 있음(json, list 등)
success: function(data) {
if (data == 'success') {
alert('피드가 등록되었습니다.');
getSnsList();
editor.setData('');
}
}, // ajax 통신 성공 시 실행 로직
error: function() {
alert('error');
} // ajax 통신 실패 시 실행 로직
});
}
ajax 로 데이터를 전달하는 방식이다. 비동기식으로 실행되어 페이지의 리로드가 필요없이 데이터 리스트를 불러오는 부분만 재실행하면 동적으로 데이터가 추가되고 리스트를 불러오는 것을 볼 수 있다.
- Controller
/*
* SNS 글 등록
*/
@ResponseBody
@PostMapping("/sns/insertSnsFeed.do")
public String insertSnsFeed(BoardVO boardVo) {
// <나 >태그를 제거하는 정규표현식
String noneHtmlContent = boardVo.getContent().replaceAll("<(;)?(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?>(;)?", "");
boardVo.setNoneHtmlContent(noneHtmlContent);
boardService.insBoardPost(boardVo, null);
return "success";
}
데이터는 역시 객체 형태를 파라미터에 지정해두면 ajax 의 data 안의 key-value 값이 매핑되어 vo에 세팅된다.
ajax 배열 데이터 전달
- JSP
$.ajax({
type: "post",
url: "/board/delBoardPost.do",
data: {
boardNoArr: deletes
},
success: function(data) {
if (data == "success") {
alert("글 " + deletes.length + "건 삭제 완료");
// 새로고침
history.go(0);
}
},
error: function() {
alert("error")
}
})
checkbox 로 선택된 요소의 board_id 를 배열에 담아서 ajax로 전송하는 부분이다.
key : "boardNoArr", value : deletes 배열 형태로 데이터를 전송한다.
deletes 의 타입은 배열로 ['12', '13', '14'] 의 형태로 되어있다.
- Controller
/*
* 게시글 삭제
*/
@ResponseBody // 응답(return)을 그대로 넘긴다 -> ajax 부분에서 success 라는 string 도출이 가능
@RequestMapping(value = "/board/delBoardPost.do", method = RequestMethod.POST)
public String delBoardPost(@RequestParam(value = "boardNoArr[]") List<Integer> list, HttpServletRequest request) {
HttpSession session = request.getSession();
UserVO loginUser = (UserVO) session.getAttribute("loginUser");
// 삭제자가 작성자 또는 관리자인지 확인
if (loginUser != null) {
if (loginUser.getUserId() == 10 || loginUser.getUserId() == 0) {
boardService.delBoardPost(list);
}
}
return "success";
}
위 JSP 파일에서 데이터를 boardNoArr로 보냈지만 실제로는 boardNoArr[]의 이름으로 전달되는 것을 알 수 있다.
그래서 컨트롤러에서는 @RequestParam의 value 값으로 boardNoArr[] 로 설정하여 데이터를 받는다.
@RequestParam
클라이언트에서 서버로 보낸 요청(request)의 단일 데이터를 가져오기 위해 사용하는 어노테이션이다.
메서드단의 파라미터 앞에 사용하며 위 코드 처럼 사용할 시 전달되는 데이터가 없다면 400 (Bad Request) 에러가 발생할 것이다. 에러 방지를 위해서는 @RequestParam의 속성중 required 라는 속성을 false 로 설정해주면 400 에러를 방지할 수 있다.
(@RequestParam(value = "boardNoArr[]" required = false)
ajax JSON 데이터 전달
- JSP
$.ajax({
type: 'post',
url: '/survey/insertSurvey.do',
contentType: "application/json",
data: JSON.stringify(sendData),
success: function(data) {
if (data == 'success') {
alert("설문조사 등록이 완료되었습니다.");
location.href = '/survey/surveyManager.do';
}
else if (data == 'fail') {
alert("관리자 로그인이 필요한 서비스입니다.");
}
},
error: function() {
alert("error");
}
})
JSP에서 Controller 로 ajax 를 이용한 JSON 데이터를 전송하는 방법이다.
contentType: "application/json" 은 Controller 로 전송하는 데이터타입을 JSON 이라고 명시하는 것이다.
data: JSON.stringify(data) 은 JSON 형태의 자바스크립트 객체 타입 데이터를 String 타입으로 변환시켜 JSON 데이터를 한 줄의 String으로 변환 시킨다.
sendData 라는 데이터의 구조는 다음과 같다.
key, value 로 이루어져 있으며 배열을 value 로 가진 key 도 존재한다.
- Controller
/*
* 설문조사 / 문항 / 선택지 등록
*/
@PostMapping("/survey/insertSurvey.do")
@ResponseBody
public String insertSurvey(@RequestBody String surveyJsonStr, HttpSession session) {
UserVO loginUser = (UserVO) session.getAttribute("loginUser");
if (loginUser != null) {
if (loginUser.getUserType().equals("admin") || loginUser.getUserType().equals("super")) {
Gson gson = new Gson();
// json.stringify 로 변환된 string 데이터를 자바 객체에 맞게 변환
SurveyVO survey = gson.fromJson(surveyJsonStr, new TypeToken<SurveyVO>() {}.getType());
surveyService.insertSurveyInfo(survey);
return "success";
}
}
return "fail";
}
Controller 에서 데이터를 받기 위해 파라미터에는 String 형태로 받으며 @RequestBody 어노테이션을 사용한다.
@RequestBody 는 클라이언트에서 서버로 요청하는 body의 내용을 그대로 전달하기 때문에 파라미터의 형태는 String으로 받는다. 여기서 SurveyVO 의 객체로 바로 받을 수 있다고는 하나 왜인지 모르겠는 오류를 못잡아 저런 식으로 진행하였다.
Gson 라이브러리를 이용하여 gson.fromJson(surveyJsonStr, new TypeToken<SurveyVO>() {}.getType()); 을 사용하게 되면 surveyJsonStr 문자열을 SurveyVO 객체의 각 필드에 맞게 데이터가 매핑된다.
- VO
import java.util.List;
public class SurveyVO {
private Integer survNo; // PK
private String survName;
private String description;
private String supervisor;
private String target;
private String startDate;
private String endDate;
private Integer participationNum;
private String prizeInfo;
private String useYn;
private String delYn;
private Integer registUserId;
private String registDt;
private String updateDt;
/* 등록 데이터 받는 용 */
private List<QuesVO> ques;
private List<List<QuesOptionVO>> quesOptions;
위처럼 VO를 ajax 로 넘긴 데이터와 형태를 맞춰주어야 VO의 각 필드에 데이터가 성공적으로 매핑된다.
Controller 에서 JSP 로 데이터 전달
Model 을 이용한 데이터 전달
가장 간단한 방법이다.
Model 객체를 이용해 view단으로 데이터를 전송한다.
- Controller
/*
* 게시판 리스트 페이징
*/
@RequestMapping(value = "/board/boardList.do", method = RequestMethod.GET)
public String boardListAOP(@ModelAttribute SearchVO searchVO, Model model) {
// 일반 게시글
searchVO.setMenuNo(searchVO.getMenuNo());
// 게시물 총 개수 조회
searchVO.setTotalRecordCnt(boardService.getBoardListTotCnt(searchVO));
searchVO.pageSetting();
// 일반 게시글 조회
model.addAttribute("boardList", boardService.getBoardList(searchVO));
return "board/boardList.tiles";
}
Cotroller 메서드의 파라미터에 Model 을 선언하고 addAttribute 메서드를 통해 "board/boardList.tiles" 페이지로 데이터를 전달한다.
key 값으로 boardList, value 값으로 리스트를 조회한 데이터를 전송한다.
JSP에서는 EL과 JSTL 을 이용해 데이터를 꺼내쓸 수 있다.
- JSP
<table class="table table-hover table-striped">
<thead>
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<c:forEach items="${boardList}" var="board">
<tr>
<td>${board.boardNum }</td>
<td>${board.title }</td>
<td>${board.id}</td>
<td>${board.boardCnt}</td>
<td>${board.registDt}</td>
</tr>
</c:forEach>
</tbody>
</table>
JSTL 을 사용하여 Cotroller 에서 보낸 리스트를 반복문을 돌리고,
EL 을 사용하여 ${data.필드명} 형식으로 데이터를 꺼내서 출력한다.
@ResponseBody 를 이용해 응답 본문을 그대로 전달
JSON으로 많이 쓰임
@Responsebody 동작
1. 반환형이 string
@Responsebody 가 없는 경우 반환형이 string 일 경우에는 ViewResolver 가 동작을 해 jsp 파일을 불러온다. (dispatcher-servlet 에 설정되어 있음)
@Responsebody 가 있는 경우는 ViewResolver 가 아닌 HttpMessageConverter 의 StringHttpMessageConverter 가 동작하게 되며 해당 페이지에 단순 "success" 라는 문자열을 반환하게 된다.
2. 반환형이 객체 타입
MappingJackson2HttpMessageConverter 가 동작하게 되며 json 형태로 변경하여 클라이언트로 전달한다.
.
.
.
.
.
.
작성중인 글입니다. 추후에 추가 작성하도록 하겠습니다.
- Just Do It -
'Spring' 카테고리의 다른 글
[Spring] 현재접속자 목록 (0) | 2023.07.30 |
---|---|
[Spring] jxls 을 이용해 table을 엑셀 파일로 생성해 다운로드 (0) | 2023.03.14 |
[Spring] 페이징 / 검색 (0) | 2022.12.27 |
[Spring] spring, vue.js 를 이용해 todoList 만들기 (0) | 2022.09.15 |