TestController

package egovframework.example.test.web;

import java.io.File;
import java.util.HashMap;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Controller
public class TestController {

	@Autowired
	private TestService testServiceImpl;

	@RequestMapping(value = "/testList.do")
	public String testListView() {
		return "test/testList";
	}
	@RequestMapping(value = "/getTestList.do", produces = "application/json")
	@ResponseBody
	public ResponseEntity<HashMap<String, Object>> testListDo(Search search) throws Exception {

		HashMap<String, Object> result = new HashMap<>();

		// 전체 게시글 개수를 얻어와 listCnt에 저장
		int listCnt = testServiceImpl.getBoardListCnt(search);

		// 검색
		search.pageInfo(listCnt);

		// 페이징
		result.put("pagination", search);

		// 게시글 화면 출력
		result.put("list", testServiceImpl.selectTest(search));
		return ResponseEntity.ok(result);
	}

	// 글 작성 버튼 구현
	@RequestMapping(value = "/insertTest.do", produces = "application/json")
	@ResponseBody
	public ResponseEntity<TestVO> write(TestVO testVO) throws Exception {
		String fileName = null;
		MultipartFile uploadFile = testVO.getUploadFile();
		if (uploadFile != null && !uploadFile.isEmpty()) {
			String originalFileName = uploadFile.getOriginalFilename();
			String ext = FilenameUtils.getExtension(originalFileName); // 확장자 구하기
			UUID uuid = UUID.randomUUID(); // UUID 구하기
			fileName = uuid + "." + ext;
			uploadFile.transferTo(new File("C:\\upload\\" + fileName));
		}
		testVO.setFileName(fileName);

		int testId = testServiceImpl.insertTest(testVO);
		testVO.setTestId(testId);
		testVO = testServiceImpl.selectDetail(testVO);
		return ResponseEntity.ok(testVO);
	}

	// 글 작성 클릭시 글 작성 페이지로 이동
	@RequestMapping(value = "/testRegister.do")
	public String testRegister() {
		return "test/testRegister";
	}

	// 제목 클릭 시 상세보기
	@RequestMapping(value = "/testDetail.do")
	public String viewForm(@ModelAttribute("testVO") TestVO testVO, Model model, HttpServletRequest request)
			throws Exception {

		int testId = Integer.parseInt(request.getParameter("testId"));
		testVO.setTestId(testId);

		TestVO resultVO = testServiceImpl.selectDetail(testVO);
		model.addAttribute("result", resultVO);

		return "test/testDetail";
	}

	// 수정하기
	@RequestMapping(value = "/updateTest.do", produces = "application/json")
	@ResponseBody
	public ResponseEntity<TestVO> updateTest(TestVO testVO) throws Exception {
		// 파일 업로드 처리
		String fileName = null;
		MultipartFile uploadFile = testVO.getUploadFile();
		if (uploadFile != null && !uploadFile.isEmpty()) {
			String originalFileName = uploadFile.getOriginalFilename();
			String ext = FilenameUtils.getExtension(originalFileName); // 확장자 구하기
			UUID uuid = UUID.randomUUID(); // UUID 구하기
			fileName = uuid + "." + ext;
			uploadFile.transferTo(new File("C:\\upload\\" + fileName));
		}
		testVO.setFileName(fileName);
		System.out.println(testVO);
		testServiceImpl.updateTest(testVO);
		testVO = testServiceImpl.selectDetail(testVO);
		return ResponseEntity.ok(testVO);
	}

	// 삭제하기
	@RequestMapping(value = "/deleteTest.do", produces = "application/json")
	@ResponseBody
	public ResponseEntity<TestVO> deleteTest(TestVO testVO) throws Exception {
		testVO = testServiceImpl.selectDetail(testVO);
		testServiceImpl.deleteTest(testVO);
		return ResponseEntity.ok(testVO);
	}
}

testRegister

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
	<div class="container">
		<table class="table table-bordered">
			<thead>
				<h1>글쓰기</h1>
			</thead>
			<tbody>
				<!-- enctype="multipart/form-data" 이 부분을 사용해 줘야지만 파일을 전송할 수 있다. -->
				<form id="form_test" action="insertTest.do" method="post"
					encType="multipart/form-data">
					<tr>
						<th>제목:</th>
						<td><input type="text" placeholder="제목을 입력하세요. "
							name="testTitle" id="testTitle" class="form-control" /></td>
					</tr>
					<tr>
						<th>내용:</th>
						<td><textarea placeholder="내용을 입력하세요 . " id="testContent"
								name="testContent" class="form-control" style="height: 200px;"></textarea></td>
					</tr>
					<tr>
						<th>첨부파일:</th>
						<td><input type="file" id="uploadFile" name="uploadFile"></td>
					</tr>
					<tr>
						<td colspan="2">
							<button id="btn_register" type="button" class="btn btn_register">등록</button>
							<button id="btn_previous" type="button" class="btn btn_previous">이전</button>
					</tr>
				</form>
			</tbody>
		</table>
	</div>

</body>
<script type="text/javascript">
	//글쓰기
	$(document).on('click', '#btn_register', function(e) {

		//데이터를 담아내는 부분 상수 const로
		//jquery val() : Form Element 의 값을 받아오는데 쓰인다. (주로 input 이나 textarea 정도?)- 주의해야할 점은 Form Element 이외의 값은 받아오질 못한다는 점.
		//문자열 좌우에서 공백을 제거하는 함수가 trim() 함수 입니다.
		const testTitle = $("#testTitle").val().trim();
		const testContent = $("#testContent").val().trim();
		const uploadFile = $("#uploadFile")[0].files[0];

		//'==' 연산자를 이용하여 서로 다른 유형의 두 변수의 [값] 비교
		//'==='는 엄격한 비교를 하는 것으로 알려져 있다 ([값 & 자료형] -> true). 변수를 비교하거나 어떤 비교를 위해 항상 '===' 연산자를 사용 할 것을 권장한다.
		if (testTitle === '') {
			alert('제목을 입력해주세요.');
			return;
		}

		if (testContent === '') {
			alert('내용을 입력해주세요.');
			return;
		}

		//ajax 통신을 사용해 서버에 데이터를 전송하기 위해 
		//폼데이터 객체를 생성함
		//jquery의 append를 통해서 프로퍼티에 바인딩이 가능하도록 세팅한다..append()선택된 요소의 마지막에 새로운 요소나 콘텐츠를 추가한다.
		var formData = new FormData();
		formData.append("testTitle", testTitle);
		formData.append("testContent", testContent);

		//만약 uploadFile이 undifined거나 null일 경우 폼데이터에 보내지 않도록 한다.
		//이부분 체크하지 않을 경우 undifined가 데이터로 보내지기 때문에 서버에서 에러가 발생한다.
		if (uploadFile)
			formData.append("uploadFile", uploadFile);

		//ajax로 파일전송 폼데이터를 보내기위해
		//enctype, processData, contentType 이 세가지를 반드시 세팅해야한다.
		$.ajax({
			enctype : 'multipart/form-data',
			processData : false,
			contentType : false,
			cache : false,
			url : "./insertTest.do",
			data : formData,
			type : "POST",
			success : function(res) {
				alert('게시글 등록 완료');
				location.href = "./testList.do";
			}
		});
	});

	//이전 클릭 시 testList로 이동
	$("#btn_previous").click(function javascript_onclikc() {
		$(location).attr('href', 'testList.do');
	});
</script>
</html>



testDetail

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
	integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
	crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
	integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
	crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
	integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
	crossorigin="anonymous"></script>
<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
</head>
<body>
	<div class="container">
		<table class="table table-bordered">
			<thead>
				<h1>글 상세보기 Detail</h1>
			</thead>
			<tbody>
				<form action="updateTest.do" id="viewForm" method="post"
					encType="multipart/form-data">
					<tr>
						<th>글번호:</th>
						<td><input name="testId" id="testId" type="text" value="${result.testId}"
							class="form-control" readonly /></td>

					</tr>
					<tr>
						<th>제목:</th>
						<td><input type="text" value="${result.testTitle}"
							id="testTitle" class="form-control" /></td>
					</tr>
					<tr>
						<th>내용:</th>
						<td><textarea id="testContent" class="form-control"
								style="height: 200px;">${result.testContent}</textarea></td>

					</tr>
					<tr>
						<c:if test="${result.fileName ne null}">
							<tr>
								<td>다운로드</td>

								<td><a href="fileDownload.do?fileName=${result.fileName}">
										<input type="text" id="asd" value="${result.fileName}"
										name="fileName" class="form-control" readonly />
								</a>
									<button id="asdasd" type="button" class="btn_previous">파일지우기</button>
							</tr>
						</c:if>
					</tr>


					<tr>
						<th>첨부파일:</th>
						<td><input type="file" id="uploadFile"></td>
					</tr>
					<tr>

						<td colspan="2">
							<button id="btn_previous" type="button" class="btn_previous">이전</button>
							<button id="btn_delete" type="button" class="btn_previous">삭제</button>
							<button id="btn_modify" type="button" class="btn_register">수정</button>
					</tr>
				</form>
			</tbody>
		</table>
	</div>


</body>
<script type="text/javascript">
	const testId = $("#testId").val();

	$(document).on('click', '#btn_modify', function(e) {
		if (confirm("정말 수정하시겠습니까 ?") == true) {
			
			//데이터를 담아내는 부분
			const testTitle = $("#testTitle").val().trim();
			const testContent = $("#testContent").val().trim();
			const uploadFile = $("#uploadFile")[0].files[0];

			if(testTitle === ''){
				alert('제목을 입력해주세요.');
				return;
			}
			
			if(testContent === ''){
				alert('내용을 입력해주세요.');
				return;
			}

			//ajax 통신을 사용해 서버에 데이터를 전송하기 위해 
			//폼데이터 객체를 생성함
			//append를 통해서 프로퍼티에 바인딩이 가능하도록 세팅한다.
			var formData = new FormData();
			formData.append("testId",testId);
			formData.append("testTitle",testTitle);
			formData.append("testContent",testContent);

			//만약 uploadFile이 undifined거나 null일 경우 폼데이터에 보내지 않도록 한다.
			//이부분 체크하지 않을 경우 undifined가 데이터로 보내지기 때문에 서버에서 에러가 발생한다.
			if(uploadFile)
				formData.append("uploadFile",uploadFile);
			
			//ajax로 파일전송 폼데이터를 보내기위해
			//enctype, processData, contentType 이 세가지를 반드시 세팅해야한다.
			$.ajax({
				enctype: 'multipart/form-data',
				processData: false,
				contentType: false,
				cache: false,
				url : "./updateTest.do",
				data : formData,
				type : "POST",
				success : function(res){
					alert('수정 완료');
					location.href='./testList.do';
				}
			})			
		} 
	});
	
	$(document).on('click', '#btn_delete', function(e) {
		if (confirm("정말 삭제하시겠습니까 ?")) {
			$.ajax({
				url : "./deleteTest.do",
				type : "POST",
				data : {
					testId : testId
				},
				success : function(res){
					alert('삭제 완료');
					location.href='./testList.do';
				}
			})
		}
	});
	
	//이전 클릭 시 testList로 이동
	$("#btn_previous").click(function javascript_onclikc() {

		$(location).attr('href', 'testList.do');

	});
	$("#asdasd").click(function javascript_onclikc() {
		$('#asd').val(null);

	});
</script>
</html>

 

 

 

github.com/jodongyeon/boardTestMiso

 

jodongyeon/boardTestMiso

게시판 formsubmit방식과AJAX비동기방식. Contribute to jodongyeon/boardTestMiso development by creating an account on GitHub.

github.com

게시판연습 깃허브주소

pom.xml

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.7.3</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.7.3</version>
		</dependency>

pom.xml에 dependency추가

 

JSON 값을 RESPONSE 해주기 jackson 라이브러리 사용을 위한 설정. 
Jackson은 JSON 데이터 구조를 처리해주는 라이브러리. 
Spring 3.0 이후로부터, Jacskon과 관련된 API를 제공함으로써, Jackson라이브러리를 사용할 때, 자동화 처리가 가능하게 되었다.
덕분에, JSON데이터를 직접 만들던가, GSON or SimpleJSON방식과 같이 직접 키와 벨류를 세팅하는 방식에서 한 단계 더 발전한 방식. 
Spring3.0 이후로 컨트롤러의 리턴 방식이 @RequestBody 형식이라면, Spring은 MessageConverter API를 통해, 컨트롤러가 리턴하는 객체를 후킹 할 수 있다.
Jackson은 JSON데이터를 출력하기 위한  MappingJacksonHttpMessageConverter를 제공. 
만약 우리가 스프링 MessageConverter를 위의 MappingJacksonHttpMessageConverter으로 등록한다면,
컨트롤러가 리턴하는 객체를 다시 뜯어(자바 리플렉션 사용), Jackson의 ObjectMapper API로 JSON 객체를 만들고 난 후, 출력하여 JSON 데이터를 완성합니다.
더욱 편리해진 점은, Spring 3.1 이후로 만약 클래스패스에 Jackson 라이브러리가 존재한다면, ( 쉽게 말해 Jackson을 설치했느냐 안 했느냐 ) 
자동적으로 MessageConverter가 등록된다는 점입니다. 덕분에 우리는 아래와 같이 매우 편리하게 사용할 수 있다.

 

 


dispatcher-servlet.xml

	<mvc:annotation-driven>
		<mvc:message-converters>
			<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
		</mvc:message-converters>
	</mvc:annotation-driven>

 Spring 과 json연동.

 


TestController

@RequestMapping(value = "/testList.do")
	public String testListView() {
		return "test/testList";
	}
	
	@RequestMapping(value = "/getTestList.do", produces = "application/json")
	@ResponseBody
	public ResponseEntity<HashMap<String, Object>> testListDo(Search search) throws Exception {

		HashMap<String, Object> result = new HashMap<>();

		// 전체 게시글 개수를 얻어와 listCnt에 저장
		int listCnt = testServiceImpl.getBoardListCnt(search);

		// 검색
		search.pageInfo(listCnt);

		// 페이징
		result.put("pagination", search);

		// 게시글 화면 출력
		result.put("list", testServiceImpl.selectTest(search));

		return ResponseEntity.ok(result);
	}

 

이전의 modelandview방식의 view를 return 해주는 컨트롤러를 위처럼 비동기 방식의 컨트롤러로 코드를 수정한다.

 

// ajax url을 getTestList.do로 받기 (후킹??)

// produces = "application/json json형태로 response request요청에 따른 response의 content-type을 변경
// @ResponseBody는 서버에서 클라이언트로 응답데이터를 전송하기 위해 사용

 

Spring Framwork에서 제공하는 클래스중 HttpEntity라는 클래스.

이것은 HTTP 요청(Request) 또는 응답(Response)에 해당하는 HttpHeader와 HttpBody를 포함하는 클래스.

이 HttpEntity 라는 클래스를 상속받아 구현한 클래스가 RequestEntity, ResponseEntity ResponseEntity는 당연히 사용자의 HttpRequest에 대한 응답 데이터를 포함하는 클래스. 따라서 HttpStatus, HttpHeaders, HttpBody를 포함.

 

HashMap은 Map을 구현한다. Key와 value를 묶어 하나의 entry로 저장한다는 특징을 갖는다. 그리고 hashing을
사용하기 때문에 많은양의 데이터를 검색하는데 뛰어난 성능을 보인다. Map 인터페이스의 한 종류로 ( "Key", value)로 이뤄져 있다. key 값을 중복이 불가능하고 value는 중복이 가능. value에 null값도 사용 가능하다. 멀티스레드에서 동시에
HashMap을 건드려 Key - value값을 사용하면 문제가 될 수 있다. 멀티쓰레드에서는 HashTable을 쓴다

 

ResponseEntity의 static 메소드인 ok()는 HttpStatus코드의 OK(200)를 응답 데이터에 포함하도록 하고
ResponseEntity의 BodyBuilder를 return함


 TestServiceImpl

@Override
	public List<TestVO> selectTest(Search search) throws Exception {
		search.setPage(search.getPage() * search.getListSize());
		List<TestVO> result = testDAOService.selectTest(search);
		search.setPage(search.getPage() / search.getListSize());
		return result;
	}

페이지 번호에 따라 10개씩 정상적으로 넘어가기 위한 코드

 


testList.jsp

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>

<head>
<!-- Bootstrap CSS -->

<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
	integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
	crossorigin="anonymous">

<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

</head>

<body>
	<div class="container">
		<h1>게시판List</h1>
		<div class="testlist">
			<form id="boardForm" name="boardForm" method="post">
				<table class="table table-hover">
					<colgroup>
						<col width="20%" />
						<col width="50%" />
						<col width="15%" />
						<col width="15%" />
					</colgroup>
					<thead>
						<tr>
							<th>번호</th>
							<th>제목</th>
							<th>작성자</th>
							<th>등록일자</th>
						</tr>
					</thead>
					<tbody id="dataSection"></tbody>
				</table>
			</form>
		</div>


		<div>
			<button id="btn_write" type="button">글작성</button>
		</div>

		<br>


		<!-- pagination{s} -->
		<div class="pagination1">
			<ul id="paginationBox" class="pagination">

			</ul>
		</div>
		<!-- pagination{e} -->

		<!-- search{s} -->

		<div class="form-group row justify-content-center">

			<div class="w100" style="padding-right: 10px">
				<select class="form-control form-control-sm" id="keywordType">
					<option value="testTitle">제목</option>
					<option value="testContent">본문</option>
					<option value="testName">작성자</option>
				</select>
			</div>

			<div class="w300" style="padding-right: 10px">
				<input type="text" class="form-control form-control-sm"
					name="keyword" id="keyword">
			</div>

			<div>
				<button class="btn btn-sm btn-primary" name="btnSearch"
					id="btnSearch">검색</button>
			</div>
		</div>
		<!-- search{e} -->

		<!-- 페이지 목록 갯수   -->
		<div class="form-group row justify-content-center">
			<p>게시판 목록 갯수</p>
			<div class="w100" style="padding-right: 10px">
				<select id="listSize" class="form-control form-control-sm">
					<option value="10">10 개</option>
					<option value="15">15 개</option>
					<option value="20">20 개</option>
				</select>
			</div>
		</div>

	</div>
	<input type="hidden" id="searchInput" value="" />
	<input type="hidden" id="searchType" value="testTitle" />
</body>


<script type="text/javascript">
	$(document).ready(function() {
		getPage();
	})

	$("#listSize").change(function() {
		getPage();
	});

	//	글조회
	//	어떤 게시물을 클릭했는지 게시물의 번호(testId)를 넘겨 줘야 함 따라서 게시물 클릭 이벤트에서 게시물의 번호를 인자 값으로 받습니다.
	//  get 방식으로 데이터를 전송합니다. 따라서 ? 연산자를 사용해 testId를 주소 뒤에 붙여 줍니다
	function showDetail(testId) {

		var form = document.getElementById("boardForm");
		var url = "<c:url value='/testDetail.do'/>";
		url = url + "?testId=" + testId;

		form.action = url;
		form.submit();
	}

	//글 작성 버튼 클릭 시 testRegister로 이동
	$("#btn_write").click(function javascript_onclikc() {
		$(location).attr('href', 'testRegister.do');
	});

	$("#btnSearch").click(function() {
		const search = $("#keyword").val();
		const searchType = $("#keywordType").val();

		$("#searchInput").val(search);
		$("#searchType").val(searchType);
		getPage();
	});

	function getPage(page) {
		var listSize = $("#listSize").val();
		var searchType = $("#searchType").val();
		var search = $("#searchInput").val();
		$
				.ajax({
					url : "getTestList.do", //서비스 주소 
					data : { //서비스 처리에 필요한 인자값
						page : page,
						searchType : searchType,
						keyword : search,
						listSize : listSize
					},
					success : function(res) {
						const list = res['list'];
						const pagination = res['pagination'];
						var data = "";
						var block = "";

						console.log(pagination);
						// 테이블의 row를 삽입하는 부분
						for (var i = 0; i < list.length; i++) {
							data += "<tr style='cursor:pointer' onclick='showDetail("
									+ list[i]['testId'] + ")'>";
							data += "<td>" + list[i]['testId'] + "</td>";
							data += "<td>" + list[i]['testTitle'] + "</td>";
							data += "<td>" + list[i]['testName'] + "</td>";
							data += "<td>" + list[i]['testDate'] + "</td>";
							data += "</tr>";
						}

						// 이전버튼 활성화 여부를 결정하는 부분
						if (pagination['prev']) {
							block += "<li class='page-item'><a class='page-link' href='javascript:getPage("
									+ (pagination['startPage'] - 1)
									+ ")'> < </a></li>";
						} else {
							block += "<li class='page-item disabled'><a class='page-link'> < </a></li>";
						}

						// 번호를 표시하는 부분
						for (var i = pagination['startPage']; i < pagination['endPage']; i++) {
							if (page !== i) {
								block += "<li class='page-item'><a class='page-link' href='javascript:getPage("
										+ i + ")'>" + (i + 1) + "</a></li>";
							} else {
								block += "<li class='page-item disabled'><a class='page-link'>"
										+ (i + 1) + "</a></li>";
							}
						}

						if (pagination['next']) {
							block += "<li class='page-item'><a class='page-link' href='javascript:getPage("
									+ (pagination['endPage'])
									+ ")'>  > </a></li>";
						} else {
							block += "<li class='page-item disabled'><a class='page-link'> > </a></li>";
						}
						$("#dataSection").html(data);
						$("#paginationBox").html(block);
					}
				})
	}
</script>

</html>

 


Console

2020-10-19 14:46:55,266 DEBUG [org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor] Written [{pagination=egovframework.example.test.domain.Search@2e77becd, list=[TestVO [testId=264, testTitle=asdf, testContent=asdf, testDate=2020-10-19], TestVO [testId=263, testTitle=fd, testContent=fd, testDate=2020-10-19], TestVO [testId=262, testTitle=fdas, testContent=asdf, testDate=2020-10-19], TestVO [testId=261, testTitle=d d , testContent=df, testDate=2020-10-19], TestVO [testId=260, testTitle= , testContent=asdfasdf, testDate=2020-10-19], TestVO [testId=259, testTitle=d d, testContent=d, testDate=2020-10-19], TestVO [testId=258, testTitle=sdfg, testContent=sdfg, testDate=2020-10-19], TestVO [testId=257, testTitle=sdfg, testContent=sdfg, testDate=2020-10-19], TestVO [testId=256, testTitle=sdfg, testContent=sdfg, testDate=2020-10-19], TestVO [testId=255, testTitle=asdf, testContent=asdf, testDate=2020-10-19]]}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@3e01cad7]
2020-10-19 14:46:55,266 DEBUG [org.springframework.web.servlet.DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'action': assuming HandlerAdapter completed request handling
2020-10-19 14:46:55,266 DEBUG [org.springframework.web.servlet.DispatcherServlet] Successfully completed request

콘솔창에 제이슨 형태로 Convert가 된 것을 볼 수 있다.

 

+ Recent posts