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) {

    // &lt;나 &gt;태그를 제거하는 정규표현식
    String noneHtmlContent = boardVo.getContent().replaceAll("&lt(;)?(/)?([a-zA-Z]*)(\\s[a-zA-Z]*=[^>]*)?(\\s)*(/)?&gt(;)?", "");
    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 -

 

반응형
복사했습니다!