학원에서 Git을 이용해서 저번프로젝트부터 진행했는데 이번 final project를 진행하다보니 비어있던 나의 잔디밭을 확인할 수 있었다.

 

쩝... 인터넷에서 보니 다른 사람들은 다 잔디밭 잘 심어져있는데, 나만 안되어있어서 서운해..

인터넷 찾아보니까 이메일, 사용자명이 다르면 안올라가진다고 한다. 다들 소프트웨어를 통해서 확인해서 바꾸던데, 나는 따로 Git을 깔지 않았고 Spring에서 연결해주는 것으로 하고있었기 때문에(uri와 깃토큰을 이용해서 연결) 나와 맞지 않았다. 어쩔 수 없지 하고 진행하던 중에 발견한 Author 과 Commiter!!!

 

그리고 저 hong 어디서 많이봤던 것 같은데..!!!

Repository 에서 commit history를 보면 항상 hong으로 올라갔었지. 그래..!!! 바꿔보자 하고 바로 수정했더니 커밋이 안된다.

Author 바꾸기를 구글링했다.

https://hijjang2.tistory.com/723

 

[Eclipse] Git - Author 변경하는 방법 ★

1. 현재 상태 Git 에서 Commit 시에 저렇게 Author 와 Committer 부분이 기본 컴퓨터 ID 및 IP 값이 들어가는데 이게 한두번은 직접 변경을 하다가도 할때마다 계속 변경해줘야 하니 굉장히 귀찮다 설정을

hijjang2.tistory.com

이 분의 포스팅을 보고 바꿔주었다.

그리고 시도해보니 이제 드디어 나도 잔디밭을 심을 수 있게되었다.

오호호예!

앗싸..! 혹시 모를 저와같은 현상을 겪는 사람들을 위해서..!!

파이널 프로젝트 진행 중에 ORA-01033 에러가 발생했다. 다행히도 학원에 모든 조원이 나와서 진행했기 때문에 안된다고 말씀드렸더니 한 분께서 UPDATE 후 COMMIT 하지않았다고 말씀하셨다. COMMIT 후에 에러가 발생하지 않게되었다.

https://www.highcharts.com/demo/line-basic

 

Basic line | Highcharts.com

Default Brand Light Brand Dark Dark Unica Sand Signika Grid Light Basic line chart showing trends in a dataset. This chart includes the series-label module, which adds a label to each line for enhanced readability.

www.highcharts.com

<script src="http://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-3d.js"></script>

실습을 위해서는 위 코드를 통해 라이브러리를 가져와야한다.

EDIT IN 버튼(둘 다)을 통해 들어가면 가져올 수 있다.

 

view options 을 통해 간단하게 모달창을 통해 옵션을 볼 수 있다.

Highcharts.chart('container', {

    title: {
        text: 'Solar Employment Growth by Sector, 2010-2016'
    },

    subtitle: {
        text: 'Source: thesolarfoundation.com'
    },

    yAxis: {
        title: {
            text: 'Number of Employees'
        }
    },

    xAxis: {
        accessibility: {
            rangeDescription: 'Range: 2010 to 2017'
        }
    },

    legend: {
        layout: 'vertical',
        align: 'right',
        verticalAlign: 'middle'
    },

    plotOptions: {
        series: {
            label: {
                connectorAllowed: false
            },
            pointStart: 2010
        }
    },

    series: [{
        name: 'Installation',
        data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
    }, {
        name: 'Manufacturing',
        data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
    }, {
        name: 'Sales & Distribution',
        data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
    }, {
        name: 'Project Development',
        data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
    }, {
        name: 'Other',
        data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
    }],

    responsive: {
        rules: [{
            condition: {
                maxWidth: 500
            },
            chartOptions: {
                legend: {
                    layout: 'horizontal',
                    align: 'center',
                    verticalAlign: 'bottom'
                }
            }
        }]
    }

});

실제로 사용된 소스는 아래와 같다.

<script type="text/javascript">
// https://www.highcharts.com/demo
$(function() {
	var url = "${pageContext.request.contextPath}/hchart/line1";
	$.getJSON(url, function(data) { // GET 방식이고 JSON 으로
		Highcharts.chart('lineContainer1', {

		    title: {
		        text: '서울 월별 평균 기온'
		    },

		    yAxis: {
		        title: {
		            text: '기온(C)'
		        }
		    },

		    xAxis: {
		        categories: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']
		    },

		    series: data.series

		});
	});
});
</script>

 

제일 중요한 부분이 series 인데, 위에 홈페이지에서 세팅한 대로 값을 넘겨주었다.

 

오늘 배운 것 중에 기억해야할 쿼리!

WITH memberAge AS (
    SELECT m2.userId, TRUNC(MONTHS_BETWEEN(SYSDATE, birth)/12) age
    FROM member m
    JOIN member1 m1 ON m.memberIdx = m1.memberIdx
    JOIN member2 m2 ON m1.userId = m2.userId
    WHERE m.membership = 1

)
SELECT '10대' section, COUNT(*) count  FROM memberAge WHERE age>=10 AND age < 20
UNION ALL
SELECT '20대' section, COUNT(*) count  FROM memberAge WHERE age>=20 AND age < 30
UNION ALL
SELECT '30대' section, COUNT(*) count  FROM memberAge WHERE age>=30 AND age < 40
UNION ALL
SELECT '40대' section, COUNT(*) count  FROM memberAge WHERE age>=40 AND age < 50
UNION ALL
SELECT '50대' section, COUNT(*) count  FROM memberAge WHERE age>=50 AND age < 60
UNION ALL
SELECT '60대' section, COUNT(*) count  FROM memberAge WHERE age>=60 AND age < 70
UNION ALL
SELECT '기타' section, COUNT(*) count  FROM memberAge WHERE age <10 OR age>=70;

 

유저관리 차트에서 나이별로 차트를 보고 싶을 때 사용된다.

공공데이터를 쓰기 위해서는 공공데이터포털에서 인증키를 발급받아야한다.

https://www.data.go.kr/index.do

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

나는 총 2개를 공부용으로 신청했다.

더보기

옆에 활용신청을 눌러서 신청할 수 있다.

 

공공 API 등의 데이터를 XML, JSON 문서를 String 형태로 받기 위한 자바 클래스


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;
import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service("common.apiSerializer")
public class APISerializer {
	private final Logger logger = LoggerFactory.getLogger(getClass());

	// 공공 API 등의 데이터를 XML,JSON 문서를 String 형태로 받기
	public String receiveToString(String spec) throws Exception {
		String result = null;
		
		HttpURLConnection conn = null;
		
		try {
			conn = (HttpURLConnection) new URL(spec).openConnection();
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			StringBuilder sb = new StringBuilder();
			String s;
			while ((s = br.readLine()) != null) {
				sb.append(s);
			}
			result = sb.toString();
		} catch (Exception e) {
			logger.error(e.toString());

			throw e;
		} finally {
			if (conn != null) {
				try {
					conn.disconnect();
				} catch (Exception e2) {
				}
			}
		}

		return result;
	}

	// 공공 API등의 XML 데이터를 String 형태의 JSON으로 변환하여 받기
	public String receiveXmlToJson(String spec) throws Exception {
		String result = null;

		try {
			String s = receiveToString(spec);
			/*
			 * <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId>
			 * <version>20210307</version> </dependency>
			 * 
			 */
			JSONObject job = XML.toJSONObject(s);
			result = job.toString();

		} catch (Exception e) {
			// logger.error(e.toString());
			throw e;
		}

		return result;
	}
}

 

HttpURLConnection 에 요청변수(Request Parameter)와 함께 서비스 URL을 넣으면 

출력결과를 얻을 수 있다. 사이트 밑에 샘플 코드도 제공되어 있으므로 참고하시면됩니다.

 

자바에서 받아온 후 AJAX를 통해 서버에 요청하면 jsp에 뿌려주는 방식으로 진행했다.

 

@RequestMapping(value = "covid", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
	public String covid(@RequestParam String date) throws Exception {
		String result = null;

		int numOfRows = 20;
		int pageNo = 1;
		
		
		String serviceKey = "개개인의서비스키";
		String spec = "http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19SidoInfStateJson";
		
		spec += "?serviceKey=" + serviceKey + "&numOfRows=" + numOfRows + "&pageNo=" + pageNo +
				"&startCreateDt=" + date + "&endCreateDt=" + date;
		
		result = apiSerializer.receiveXmlToJson(spec);
		
		return result;
	}

@RequestMapping에 produces를 통해 "application/json; charset=utf-8" 을 명시해야 깨지지 않음

사이트에서 안내된 파라미터와 샘플데이터를 보고 맞춰서 넣어주어야한다. (대/소문자도 틀리면안됨)

function ajaxFun(url, method, query, dataType, fn) {
	$.ajax({
		type:method,
		url:url,
		data:query,
		dataType:dataType,
		success:function(data){
			fn(data);
		},
		error:function(e) {
			console.log(e.responseText);
		}
	});
}

$(function(){
	$("#btnCovid").click(function(){
		var url="${pageContext.request.contextPath}/parse/covid";
		var date = "20211213";
		var query = "date=" + date; 
		
		var fn = function(data) {
			printCovid(data);
		};
		ajaxFun(url, "get", query, "json", fn);
	});
	
	function printCovid(data) {
		var out="<h3>코로나 발생 현황</h3><hr>";
		
		console.log(data);
		$.each(data.response.body.items.item, function(index, item) {
			if(index == 0 ) {
				out += "기준일시 : " + item.stdDay + "<br>";
			}
			
			out += item.gubun 
				+ " - 전일대비 확진자 증가수 : " + item.incDec
				+ ", 누적확진자 수 : " + item.defCnt
				+ "<br>";
				
		});
		
		$("#resultLayout").html(out);
	}
});

@ResponseBody

핸들러 메소드에서 @ResponseBody 애노테이션이 적용된 경우 반환 객체를 HTTP 응답으로 전송한다.

- 메소드에서 반환하는 자바 객체를 HTTP 응답 몸체로 변환한다.

- 자바 객체를 HTTP 요청의 body 내용으로 매핑하는 역할

HttpMessageConverter를 통해 HTTP 응답 스트림으로 변환

<mvc:annotation-driven/>를 통해 HttpMessageConverter 구현 클래스를 모두 등록할 수 있다.

주요 HttpMessageConverter 구현 클래스

-  StringHttpMessageConverter : 요청 몸체를 문자열로 변환하거나 문자열을 응답 몸체로 변환

(text/plain;charset=ISO-8859-1)

- Jaxb2RootElementHttpMessageConverter : XML 용청 몸체를 자바 객체로 변환하거나 자바 객체를 XML 응답 몸체로 변환(text/xml, application/xml)

- MappingJackson2HttpMessageConverter : JSON 요청 몸체를 자바 객체로 변환하거나 자바 객체를 JSON 응답 몸체로 변환(text/json, application/json)

- ByteArrayHttpMessageConverter : HTTP 메시지와 byte 배열 사이의 변환을 처리(application/octet-stream)

- 스프링 4.0부터는 MappingJackson2HttpMessageConverter를 이용ㅇ하여 자바 객체를 JSON으로 변환하거나 JSON을 자바 객체로 변환하며, 다음의 의존성을 추가해야 한다.

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

- 스프링 3.x 에서는 MappingJacksonHttpMessageConverter를 이용하여 변환 한다.

MappingJacksonHttpMessageConverter는 jackson-mapper-asl, jackson-core-asl의 의존성을 추가해야 한다.

- 스프링 4.0에 추가된 @RestController 애노테이션으로 컨트롤러를 설정하면, @RestController에는 기본적으로 @ResponseBody 애노테이션이 적용되어 메소드 레벨에서 추가하지 않아도 된다.

 

사용 예

1) String을 JSON으로 변환하여 반환

- 문자열을 JSON 반환할 때, 한글을 반환하는 경우 반드시 produces 옵션을 통해 charset을 명시 해야 한다.

@RequestMapping(value = "/user", produces="application/json;charset=utf-8")
@ResponseBody
public String process(@RequestParam String id) {
	String name = service.getName(id);
    return "{\"name\":\"+name+"\"}";
}

 

2) Map<String, Object>을 JSON으로 변환하여 반환

@RequestMapping(value = "/user")
@ResponseBody
public Map<String, Object> process(@RequestParam int idx) {
	Map<String, Object> model = service.readMap(idx);
    return model;
}

@RequestBody

HTTP 요청 몸체를 자바 객체로 전달받음

HTTP 요청의 body 내용을 자바 객체로 매핑하는 역할

POST 형식으로 응답 받는 경우에만 사용할 수 있다.

사용 예 - JSON 형식으로 전송한 요청 파라미터를 전달 받아 JSON 형식으로 응답

- JSON 형식의 요청 파라미터를 member 객체에 전달받아 처리 후, 처리 결과를 가지고 있는 loginMember 객체를 JSON으로 변환하여 응답한다.

@RequestMapping(value = "/member/login", method=RequestMethod.POST)
@ResponseBody
public Member loginSubmit(@RequestBody Member member) throws Exception {
	Member loginMember = memberService.login(member);
    return loginMember;
}

@RestController

@RestController는 @Controller에 @ResponseBody가 추가된 애노테이션이다.

스프링 4.0부터 지원한다.

REST 방식의 데이터 처리를 위해 사용하는 애노테이션

- @RestController는 자바 객체를 JSON/XML 타입으로 반환하는 REST 서비스에 최적화된 컨트롤러

 

@Controller와 @RestController 차이점

- @Controller 

API와 뷰를 동시에 서비스하는 경우에 사용하며, API 서비스는 @ResponseBody를 붙여줘야 한다.

 

- @RestController

뷰가 필요 없는 API를 서비스하는 경우에 사용. @ResponseBody를 포함하고 있다.

 

- @RestController 에서 뷰를 반환해야 하는 경우에는 ModelAndView를 반환한다.

JSON 형식으로 서버에 보낼 때 서버는 {"키":"값", ...} 으로 값을 받게된다.

AJAX 를 왜 쓰느냐 ?

-> Guess : 전체 페이지를 서버로 보내는게 아니라 일부분만 업데이트 할 때 그 부분만 보낼 수 있어서 , 부분적으로 업데이트 하거나 그럴때 쓰임 (맞는지 확인 필수) 요새는 많이 쓰기 때문에 꼭 알아두어야한다!

 

AJAX를 위한 함수 설정

function ajaxFun(url, method, query, dataType, fn) {
	$.ajax({
		type:method,
		url:url,
		data:query,
		dataType:dataType,
		success:function(data) {
			fn(data);
		},
		beforeSend:function(jqXHR) {
		},
		error:function(jqXHR) {
			console.log(jqXHR.responseText);
		}
	});
}

type은 GET/POST 형식인지 

url은 서버 주소 어디로 가는건지

data는 말그대로 어떤 데이터를 보내는지

dataType JSON인지 HTML인지 

 

 

처음 page 로드할 때 list 불러오기

$(function () {
	listPage(1);
});

function listPage(page) {
	var url = "${pageContext.request.contextPath}/nscore/list";
	var query = "pageNo=" + page;
	var fn = function(data) {
		printJSON(data);
	};
	
	ajaxFun(url, "get", query, "json", fn);
}

데이터를 불러옴

 

AJAX - JSON으로 리스트 찍기

function printJSON(data) {
	$(".score-list").empty(); // 쌓지않고 페이징 처리를 할 것이므로
	
	var dataCount = data.dataCount;
	var total_page = data.total_page;
	var pageNo = data.pageNo;
	var paging = data.paging;
	
	var str;
	$(data.list).each(function(index, item) {
		var hak = item.hak;
		var name = item.name;
		var birth = item.birth;
		var kor = item.kor;
		var eng = item.eng;
		var mat = item.mat;
		var tot = item.tot;
		var ave = item.ave;
		
		str = "<tr align='center' height='33'></tr>";
		$(str).append("<td>"+hak+"</td>")
			.append("<td>"+name+"</td>")
			.append("<td>"+birth+"</td>")
			.append("<td>"+kor+"</td>")
			.append("<td>"+eng+"</td>")
			.append("<td>"+mat+"</td>")
			.append("<td>"+tot+"</td>")
			.append("<td>"+ave+"</td>")
			.append("<td><span class='btn-update'>수정</span> | <span class='btn-delete'>삭제</span></td>")
			.appendTo(".score-list");
	});
	
}

 

AJAX - JSON 자료 등록

hak=1111&name=유니코드&EE3343

$(function() {
	$("form[name=scoreForm]").submit(function() {
		var query = $(this).serialize();
		var url = "${pageContext.request.contextPath}/nscore/insert";
		
		var fn = function(data) {
			var state = data.state;
			if(state === "true") {
				$(".score-input input").each(function() {
					$(this).val("");
				});
				listPage(1);
				$("#hak").focus();
				
			} else if(state === "notUnique") {
				alert("등록된 학번입니다.");
				return false;
			} else if(state ==="false") {
				alert("추가가 실패했습니다.");
				return false;
			}
		};
		ajaxFun(url, "post", query, "json", fn);
		
		return false; // 서버로 전송하지 못하도록
	});
});

 

AJAX - JSON 자료 삭제

$(function() {
	$("body").on("click", ".btn-delete", function() {
		if(! confirm("자료를 삭제하시겠습니까 ? ") ) {
			return false;
		}
		
		// var hak = $(this).closest("tr").children().first().text();
		var hak = $(this).closest("tr").find("td:first").text();
		var url = "${pageContext.request.contextPath}/nscore/delete";
		var query = "hak="+hak;
		
		var fn = function(data) {
			var state = data.state;
			if(state === "true") {
				listPage(1);
			} else {
				alert("자료를 삭제하지 못했습니다.");
			}
		};
		ajaxFun(url, "post", query, "json", fn);
	});
});

 

AJAX - JSON 자료 수정

$(function() {
	var arr = [];
	
	$("body").on("click", ".btn-update", function() {
		var $tds = $(this).closest("tr").children("td");
		var names = ["hak", "name", "birth", "kor", "eng", "mat"];
		
		var s1, s2;
		$($tds).each(function(idx) {
			if( idx != $tds.length-1 ) {
				arr[idx] = $(this).text(); // 배열에 정보를 다 담음
				
				$(this).empty();
				if(idx < 3 || idx > 5) {
					
					s1 = "";
					if(idx <= 5) {
						s1 = " name='"+names[idx]+"' ";
					}
					
					s2 = "";
					if(idx == 0 || idx >= 6 ){
						s2 = " readonly = 'readonly' ";	
					}
					
					$(this).append("<input type='text' "+ s1 + s2 + " value='"+arr[idx]+"'>");
				} else {
					$(this).append("<input type='number' name='"+names[idx]+"' value='"+arr[idx]+"' min='0' max='100'>");
				}
				
			} else {
				$(this).empty();
				$(this).append("<span class='btn-updateOk'>완료</span> | <span class='btn-updateCancel'>취소</span>")
			}
		});
		
		$($tds[1]).find("input").focus();
		
		// 등록하기 줄의 모든 input과 버튼 비활성화 및 숨기기 
		$(".score-input input").prop("disabled", true);
		$(".score-input button").prop("disabled", true);
		$(".score-input").hide(100);
		
	});
	
	// 수정 완료
	$("body").on("click", ".btn-updateOk", function() {
		var query = $("form[name=scoreForm]").serialize();
		var url = "${pageContext.request.contextPath}/nscore/update";
		
		var fn = function(data) {
			var state = data.state;
			if(state === "true") {
				listPage(1);
				
				$(".score-input input").prop("disabled", false);
				$(".score-input button").prop("disabled", false);
				$(".score-input").show(100);
			} else {
				alert("자료를 수정하지 못했습니다.");
				
				$(".score-input input").prop("disabled", false);
				$(".score-input button").prop("disabled", false);
				$(".score-input").show(100);
			}
		};
		ajaxFun(url, "post", query, "json", fn);
	
	});
	
	// 수정 취소
	$("body").on("click", ".btn-updateCancel", function() {
		var $tds = $(this).closest("tr").children("td");
		$($tds).each(function(idx) {
			if(idx != $tds.length-1) {
				$(this).empty();
				$(this).text(arr[idx]);
			} else {
				$(this).empty();
				$(this).append("<span class='btn-update'>수정</span> | <span class='btn-delete'>삭제</span>")
			}
		});
		
		$(".score-input input").prop("disabled", false);
		$(".score-input button").prop("disabled", false);
		$(".score-input").show(100);
	});
});

 

jsp

<div class="container">

	<div class="title">
	   <h3><span>|</span> 성적 처리</h3>
	</div>
	
	<form name="scoreForm">
		<table class="score-table">
			<thead>
				<tr>
					<th width="80">학번</th>
					<th width="100">이름</th>
					<th width="100">생년월일</th>
					<th width="80">국어</th>
					<th width="80">영어</th>
					<th width="80">수학</th>
					<th width="80">총점</th>
					<th width="80">평균</th>
					<th>변경</th>
				</tr>
			</thead>
			<tbody class="score-input">
				<tr align="center" height="33">
					<td><input type="text" name="hak" id="hak" required="required"></td>
					<td><input type="text" name="name" id="name" required="required"></td>
					<td><input type="text" name="birth" id="birth" required="required"></td>
					<td><input type="number" name="kor" id="kor" min="0" max="100" required="required"></td>
					<td><input type="number" name="eng" id="eng" min="0" max="100" required="required"></td>
					<td><input type="number" name="mat" id="mat" min="0" max="100" required="required"></td>
					<td><input type="text" id="tot" readonly="readonly"></td>
					<td><input type="text" id="ave" readonly="readonly"></td>
					<td>
						<button type="submit" id="btnAdd">등록하기</button>
					</td>
				</tr>
			</tbody>
			<tfoot class="score-list"></tfoot>
		</table>
	</form>
	
</div>

 

Spring - Controller

package com.sp.app.nscore;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sp.app.common.MyUtil;

@Controller("nscore.scoreController")
@RequestMapping("/nscore/*")
public class ScoreController {
	@Autowired
	private ScoreService service;

	@Autowired
	private MyUtil myUtil;
	
	@RequestMapping("main")
	public String main() throws Exception {
		
		return "nscore/main";
	}
	
	// 성적 리스트 : AJAX - JSON으로 결과 전송
	@RequestMapping("list")
	@ResponseBody
	public Map<String, Object> scoreList(
			@RequestParam(value = "pageNo", defaultValue = "1") int current_page,
			@RequestParam(defaultValue = "hak") String condition,
			@RequestParam(defaultValue = "") String keyword) throws Exception {
		
		int rows = 10;
		int dataCount, total_page;
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("condition", condition);
		map.put("keyword", keyword);
		
		dataCount = service.dataCount(map);
		total_page = myUtil.pageCount(rows, dataCount);
		if(current_page > total_page) {
			current_page = total_page;
		}
		
		int start = (current_page -1) * rows + 1;
		int end = (current_page * rows);
		map.put("start", start);
		map.put("end", end);
		
		List<Score> list = service.listScore(map);
		
		String paging = myUtil.pagingMethod(current_page, total_page, "listPage");
		
		Map<String, Object> model = new HashMap<String, Object>();
		
		model.put("list", list);
		model.put("dataCount", dataCount);
		model.put("total_page", total_page);
		model.put("pageNo", current_page);
		model.put("paging", paging);
		
		return model;
	}
	
	// 성적추가 : AJAX - JSON으로 결과 전송
	@RequestMapping(value = "insert", method = RequestMethod.POST)
	@ResponseBody // 메소드에서 반환하는 자바객체를 HTTP응답으로 변환하여 전송
	public Map<String, Object> scoreSubmit(
			Score dto
			) throws Exception {
		String state = "false";
		
		try {
			service.insertScore(dto);
			state = "true";
		} catch (DuplicateKeyException e) { // 중복학번일 경우
			state = "notUnique";
		} catch (Exception e) {
		}
		
		// @ResponseBody 애노테이션으로 인하여 Map 객체는 JSON으로 변환되어 전송된다.
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("state", state);
		return model;
	}
	
	// 자료 수정 : AJAX - JSON
	@RequestMapping(value = "update", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> updateScore(
			Score dto) throws Exception {
		String state = "false";
		
		try {
			service.updateScore(dto);
			state = "true";
		} catch (Exception e) {
		}
		
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("state", state);
		return model;
	}
	
	// 자료 삭제 : AJAX -JSON
	@RequestMapping(value = "delete", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> deleteScore(
			@RequestParam String hak) throws Exception {
		String state = "false";
		
		try {
			service.deleteScore(hak);
			state = "true";
		} catch (Exception e) {
		}
		
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("state", state);
		return model;

	}
	
}
package com.sp.app.test1;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller("test1.testController")
@RequestMapping("/test1/*")
public class TestController {
	@RequestMapping("main")
	public String main() throws Exception {	
		return "test1/main";
	}
	
	// Map을 리턴하면 모델을 설정
	@RequestMapping("hello")
	public Map<String, Object> execute() throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("msg", "Map 인터페이스를 리턴 타입으로 포워딩 JSP에 값 전달");
		return map;
	}
	
	// void를 리턴하는 경우는 뷰가 필요 없는 경우(다운로드 등)
	@RequestMapping("hello2")
	public void execute2(
			HttpServletRequest req,
			HttpServletResponse resp) throws Exception {
		// HttpServletResponse가 있으면 뷰를 자동 설정 하지 않음.
		try {
			String a = req.getParameter("name");
			
			resp.setContentType("text/html; charset=utf-8");
			PrintWriter out = resp.getWriter();
			out.print("<script>alert('" + a + "님 반가워요');history.back();</script>");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@RequestMapping("calc")
	public String calcForm(
			@RequestParam String num,
			Model model) throws Exception {
		
		try {
			int n = Integer.parseInt(num);
			int s = 0;
			for(int i=1; i<=n; i++) {
				s+=i;
			}
			model.addAttribute("msg", "결과:"+s);
		} catch (Exception e) {
			return "redirect:/test1/error"; // 리다이렉트
		}
		return "test1/hello";
	}
	
	@RequestMapping("error")
	public String errorForm() throws Exception {
		return "test1/error";
	}
}
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> 리턴 타입 </h3>

<p>
	<a href="${pageContext.request.contextPath}/test1/hello">확인</a>
</p>

<p>
	<a href="${pageContext.request.contextPath}/test1/hello2?name=kim">확인</a>
</p>

<p>
	<a href="${pageContext.request.contextPath}/test1/calc?num=a">계산</a>
</p>


<!-- 

  - @RequestMapping 메소드의 리턴 타입
    String : 뷰의 이름 -> ModelAndView 로 변환하여 처리
	ModelAndView : 모델과 뷰의 이름 설정 
	req.setAttribute("이름", 값); <-- 모델
	Map, Model, ModelMap : 모델을 설정, 뷰는 viewResolver가 등록된 경우 뷰의 이름은 자동으로 uri를 이용하여 설정한다.
		uri가 test1/hello 이면 JSP이면 /WEB-INF/views/test1/hello.jsp 가 됨
	void : HttpServletResponse 파라미터가 존재하지 않으면 뷰가 자동으로 설정
 -->


</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

	<p> 시스템 점검 중입니다. </p>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<p> ${msg} </p>


</body>
</html>

+ Recent posts