Java EE 정리 36
17 Apr 2019
Reading time ~7 minutes
Java EE 정리 36 - Cookie, include, AJAX
Cookie
- 중요하지 않은 정보를 사용자 측 Storage에 저장, 비연결성 해결
-
Cookie
- 세션과 다르게 클래스
- 값 설정, 값 얻기
@RequestMapping(...)
public String method명(HttpServletRequest request, HttpServletResponse response) {
// request객체를 이용해서 Cookie를 얻을 수 있다.
Cookie[] c = request.getCookies();
// 쿠키를 얻고 반복하여 사용
for(int i=0; i<c.length; i++) {
Cookie tc = c[i];
tc.getName();
tc.getValue();
}
// response객체를 이용해서 Cookie를 심을 수 있다.
// 1. Cookie 생성
Cookie nc = new Cookie("이름", "값");
// 2. 생존시간 설정(설정 안하면 Session Storage와 동일, 브라우저 꺼지면 사라짐)
nc.setMaxAge(초*분*시*일);
// 3. 심기
response.addCookie(nc);
// 쿠기 삭제는 값없는 동명의 쿠키를 만들어주고 생존시간을 0으로 설정
}
-
@CookieValue
- 값 얻기
- 매개변수 앞에 선언
public String method명(@CookieValue(value="쿠키이름", defaultValue="쿠키가없을때사용할값") String data, ...) {
// 매개변수(data)를 이용하여 cookie에서 읽어들인 값을 사용할 수 있다.
...
}
Cookie 클래스 사용 예
<!-- main_menu.jsp -->
...
<li><a href="cookie/read_cookie.do">Cookie클래스를 사용한 값얻기</a></li>
<li><a href="cookie/read_an_cookie.do">@CookieValue를 사용한 값얻기</a></li>
...
public class CookieService {
// DB를 사용하지 않는 Service 메소드들
public String nameMsg(String name) {
return "<marquee>"+name+"님 안녕하세요!</marquee>";
}
public int birth(int age) {
Calendar cal = Calendar.getInstance();
return cal.get(Calendar.YEAR)-age+1;
}
}
- 저장된 쿠키를 읽을 땐 HttpServletRequest 객체가 필요
@Controller
public class CookieController {
@RequestMapping(value="/cookie/read_cookie.do",method=GET)
public String readCookie(HttpServletRequest request, Model model) {
// 쿠키를 읽기
Cookie[] cookies = request.getCookies();
// 읽어들인 모든 쿠키를 JSP에서 사용할 수 있다
if(cookies != null) { // 읽어들인 쿠키가 존재
model.addAttribute("rCookie",cookies);
CookieService cs = new CookieService();
Cookie tempCookie = null;
int cnt = 0;
for(int i=0; i<cookies.length; i++) {
tempCookie = cookies[i];
if("JSESSIONID".equals(tempCookie.getName())){
cnt++;
}
if("name".equals(tempCookie.getName())){
model.addAttribute("name",
cs.nameMsg(tempCookie.getValue()));
cnt++;
}
if("age".equals(tempCookie.getName())){
model.addAttribute("birth",
cs.birth(Integer.parseInt(
tempCookie.getValue())));
}
}
if (cnt == 1) // JSESSIONID만 존재하는 경우
model.addAttribute("rCookie",null);
}
return "cookie/read_cookie";
}
}
<!-- cookie/read_cookie.jsp -->
...
<div>
<strong>Model에 들어있는 쿠키들 읽기</strong><br/>
<c:if test="${ empty requestScope.rCookie }">
쿠키가 존재하지 않습니다.<br/>
<a href="add_cookie.do">쿠키 심기</a>
</c:if><br/>
<c:forEach var="cookie" items="${ rCookie }">
쿠키명 : <c:out value="${ cookie.name }"/><br/>
쿠키값 : <c:out value="${ cookie.value }"/><br/>
</c:forEach>
<c:if test="${ not empty requestScope.rCookie }">
쿠키가 존재합니다.<br/>
<strong>쿠키 값</strong><br/>
<c:out value="${ requestScope.name }"/><br/>
<strong>태어난 해</strong> : <c:out value="${ requestScope.birth }"/>
<a href="remove_cookie.do">쿠키 삭제</a>
</c:if><br/>
</div>
...
-
쿠키 심기
- 쿠키를 심을 땐 HttpServletResponse 객체가 필요
- 쿠키는 한글로 값을 저장할 수 없음
- 한글을 쿠키값으로 심을 땐 8859_1로 인코딩해서 심는다
- 쿠키는 브라우저가 열려있으면 계속 생존
- 브라우저 종료 후 생존시간이 적용됨
@Controller
public class CookieController {
@RequestMapping(value="/add_cookie.do",method=GET)
public String addCookie(HttpServletResponse response, Model model) {
// 1. 쿠키 생성
Cookie nameCookie = new Cookie("name","seonui.gong");
Cookie ageCookie = new Cookie("age", "28");
// 2. 쿠키 생존시간 설정
nameCookie.setMaxAge(60*2);
ageCookie.setMaxAge(60*2);
// 3. 쿠키 심기
response.addCookie(nameCookie);
response.addCookie(ageCookie);
// View에서 쿠키가 잘 심어진걸 alert으로 보여주기 위해
model.addAttribute("cookieFlag",true);
model.addAttribute("msg","쿠키가 심어졌습니다.");
return "cookie/read_cookie";
}
...
- script태그 안에서도 JSTL태그 사용이 가능하다
<!-- cookie/read_cookie.jsp -->
...
<script type="text/javascript">
$(function() {
<c:if test="${ cookieFlag }">
alert("${ msg }");
</c:if>
}); // ready
</script>
- JSTP 태그로 forEach하면 쿠키값이 안나온다.. 스크립트릿을 이용해서 출력.
<!-- cookie/read_cookie.jsp -->
...
<div>
<strong>Model에 들어있는 쿠키들 읽기</strong><br/>
<c:if test="${ empty requestScope.rCookie }">
쿠키가 존재하지 않습니다.<br/>
<a href="add_cookie.do">쿠키 심기</a>
</c:if><br/>
<!-- <c:forEach var="cookie" items="${ rCookie }">
쿠키명 : <c:out value="${ cookie.name }"/><br/>
쿠키값 : <c:out value="${ cookie.value }"/><br/>
</c:forEach> -->
<%
Cookie[] rCookie = (Cookie[])request.getAttribute("rCookie");
if (rCookie != null) {
for (Cookie temp : rCookie) {
out.println(temp.getName()+" "+temp.getValue()+"<br/>");
}
}
%>
<c:if test="${ not empty requestScope.rCookie }">
쿠키가 존재합니다.<br/>
<strong>쿠키 값</strong><br/>
<c:out value="${ requestScope.name }" escapeXml="false"/><br/>
<strong>태어난 해</strong> : <c:out value="${ requestScope.birth }" />
<br/>
<a href="remove_cookie.do">쿠키 삭제</a>
</c:if><br/>
</div>
...
- c:out태그에 escapeXml 속성값을 false를 주면 HTML이 적용된다.
-
쿠키 삭제
- 삭제가 안될 수 있으므로 값을 초기화 해준다
// CookieController
...
@RequestMapping(value="/cookie/remove_cookie.do",method=GET)
public String removeCookie(HttpServletResponse response, Model model) {
// 1. 같은 이름의 쿠키를 생성한다.
Cookie nameCookie = new Cookie("name", "");
Cookie ageCookie = new Cookie("age", "");
// 2. 생존시간을 0으로 설정
nameCookie.setMaxAge(0);
ageCookie.setMaxAge(0);
// 3. 쿠키를 심는다.
response.addCookie(nameCookie);
response.addCookie(ageCookie);
model.addAttribute("cookieFlag", true);
model.addAttribute("msg","쿠키가 제거되었습니다.");
return "cookie/read_cookie";
}
...
@CookieValue 사용 예
@Controller
public class CookieController {
@RequestMapping(value="/cookie/read_an_cookie.do",method=GET)
public String anReadCookie(
@CookieValue(value="an_name", defaultValue="")String an_name,
@CookieValue(value="an_age", defaultValue="")String an_age, Model model) {
model.addAttribute("an_name", an_name);
model.addAttribute("an_age", an_age);
return "cookie/an_read_cookie";
}
...
<!-- /cookie/an_read_cookie.jsp -->
...
<div>
<strong>Model에 들어있는 쿠키들 읽기</strong><br/>
<c:choose>
<c:when test="${ empty an_name and empty an_age }">
쿠키가 존재하지 않습니다.
<a href="an_add_cookie.do">쿠키심기</a>
</c:when>
<c:otherwise>
이름 : <strong>${ an_name }</strong>
나이 : <strong>${ an_age }</strong>
</c:otherwise>
</c:choose>
</div>
...
// CookieController
...
@RequestMapping(value="/cookie/an_add_cookie.do",method=GET)
public String anAddCookie(HttpServletResponse response) {
// 1. 쿠키 생성
Cookie nameCookie = new Cookie("an_name","jungyun");
Cookie ageCookie = new Cookie("an_age", "30");
// 2. 쿠키 생존시간 설정
nameCookie.setMaxAge(60*2);
ageCookie.setMaxAge(60*2);
// 3. 쿠키 심기
response.addCookie(nameCookie);
response.addCookie(ageCookie);
return "cookie/an_read_cookie";
}
...
include
- 다른 JSP를 끼워 넣어서 보여줄 때 사용
<jsp:include ...>, <%@ include ... %>, <c:import ... >
-
WebContent에 JSP가 존재하는 경우
- WebContent의 하위 폴더부터 기술
<jsp:include page="date0417/test.jsp"/>
-
WEB-INF/views에 JSP가 존재하는 경우
- WEB-INF부터 기술
<jsp:include page="WEB-INF/views/test.jsp"/>
include 사용 예
- WebContent내에 존재하는 JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div>
<strong>WebContent 하위 폴더에 존재하는 JSP</strong>
</div>
- WEB-INF/views내에 존재하는 JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div>
<strong>WEB-INF/views내에 존재하는 JSP</strong>
</div>
<!-- main_menu.jsp -->
...
<li><a href="include/include.do">JSP include</a></li>
...
@Controller
public class IncludeController {
@RequestMapping(value="/include/include.do", method=RequestMethod.GET)
public String include() {
return "include/use_include";
}
}
<!-- WEB-INF/views/include/use_include.jsp -->
...
use_include.jsp의 코드<br/>
<jsp:include page="/date0417/web_content.jsp"></jsp:include>
<br/>
use_include.jsp의 코드<br/>
<jsp:include page="/WEB-INF/views/include/views.jsp"></jsp:include>
...
AJAX(Asynchronous JavaScript And XML)
-
일반적인 AJAX 요청이 오면 일반적으로 JSP로 응답
- AJAX로 JSON Object 요청 시 JSP에서 JSON을 출력하고 응답해야 한다
- Controller에서 서비스 결과로 JSONObject(JSON simple library 사용)생성
@Controller
class Test {
@RequestMapping("/a.do")
public String method(Model model) {
// JSONObject를 만들고 Model객체에 넣어 전달
...
model.addAttribute("j이름",JSONObject객체)
return "jsp명";
}
}
- 응답하는 JSP에서 값을 출력, 이 출력내용이 AJAX success함수의 파라미터로 들어가지게 됨
${ requestScope.이름 }
- 위처럼 만들어도 되지만 AJAX를 많이 사용하면 결과를 출력하는 JSP파일도 많이 늘어나버림
- @RequestBody를 사용하면 Controller의 처리 결과를 ViewResolver를 거치지 않고 바로 응답할 수 있다
Maven을 이용한 JSON.simple 설치
- Maven을 통해 설치, pom.xml에 dependency노드를 추가해준다
- Alt+F5(Maven Project Update)를 통해 새로운 library를 다운로드!
- 다운받은 jar파일을 WEB-INF/lib에 옮겨줘야 개발뿐만 아니라 서버에서 운용할 때도 문제가 없다
@ResponseBody
- Controller에서 바로 응답되도록 설정하는 Annotation
<!-- main_menu.jsp -->
...
<li><a href="ajax/ajax.do">AJAX 사용</a></li>
...
public class AjaxService {
public JSONObject createJson() {
JSONObject json = new JSONObject();
json.put("name", "정택성");
json.put("type", "대담한 통솔자");
json.put("age", 27);
return json;
}
}
@Controller
public class AjaxController {
@RequestMapping(value="/ajax/ajax.do", method=RequestMethod.GET)
public String getJson() {
AjaxService as = new AjaxService();
JSONObject json = as.createJson();
return json.toJSONString();
}
}
-
실행하면 다음과 같은 결과가 나온다
- ViewResolver가 JSP 찾고 없어서 404에러를 보여줌
- @ResponseBody를 붙여주면 ViewResolver가 JSP를 찾지 않고 결과를 바로 응답한다
@Controller
public class AjaxController {
@ResponseBody
@RequestMapping(value="/ajax/ajax.do", method=RequestMethod.GET)
public String getJson() {
AjaxService as = new AjaxService();
JSONObject json = as.createJson();
return json.toJSONString();
}
}
- AJAX로 결과를 사용하는 예제로 수정
@Controller
public class AjaxController {
@RequestMapping(value="/ajax/ajax.do", method=RequestMethod.GET)
public String getJsonForm() {
return "ajax/ajax_form";
}
@ResponseBody
@RequestMapping(value="/ajax/ajax_process.do", method=RequestMethod.GET)
public String getJsonObject() {
JSONObject json = null;
AjaxService as = new AjaxService();
json = as.createJson();
return json.toJSONString(); // JSP명이 아닌 JSON이 나감
}
}
<!-- ajax/ajax_form.jsp -->
...
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
$.ajax({
url:"ajax_process.do",
dataType:"json",
type:"get",
error:function(xhr) {
alert("문제발생 "+xhr.status);
},
success:function(json_obj){
alert(json_obj);
}
});
});
}); // ready
</script>
...
<div>
<input type="button" value="ajax요청" class="btn"/>
</div>
<div id="view"></div>
...
- AJAX로 받은 결과를 이용하여 화면에 뿌리기
<!-- ajax/ajax_form.jsp -->
...
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
$.ajax({
url:"ajax_process.do",
dataType:"json",
type:"get",
error:function(xhr) {
alert("문제발생 "+xhr.status);
},
success:function(json_obj){
var output="<img src='http://localhost:8080/spring_mvc/common/images/img1_1.png'><br/>"
+json_obj.name+"/"+json_obj.age+"세 ("+json_obj.type+")";
$("#view").html(output);
}
});
});
}); // ready
</script>
...
- 컨트롤러에서 json을 찍어보면 들어온 요청은 한글처리가 되어있음
// AjaxController
...
@ResponseBody
@RequestMapping(value="/ajax/ajax_process.do", method=RequestMethod.GET)
public String getJsonObject() {
JSONObject json = null;
AjaxService as = new AjaxService();
json = as.createJson();
System.out.println(json);
return json.toJSONString();
}
}
-
응답할 때도 한글처리를 해서 깨지는 것을 막는다
- JSP에서 인코딩되지 않고 바로 응답되기 때문에 인코딩 처리를 해줘야 한다
public class AjaxService {
public JSONObject createJson() {
JSONObject json = new JSONObject();
try {
json.put("name", URLEncoder.encode("정택성","UTF-8"));
json.put("type", URLEncoder.encode("대담한 통솔자","UTF-8"));
json.put("age", 27);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return json;
}
public static void main(String[] args) {
AjaxService as = new AjaxService();
System.out.println(as.createJson());
}
}
- JavaScript에서 decode처리를 해주면 한글처리가 된다
<!-- ajax/ajax_form.jsp -->
...
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
$.ajax({
url:"ajax_process.do",
dataType:"json",
type:"get",
error:function(xhr) {
alert("문제발생 "+xhr.status);
},
success:function(json_obj){
var output="<img src='http://localhost:8080/spring_mvc/common/images/img1_1.png'><br/>"
+decodeURI(json_obj.name)+"/"+json_obj.age+"세 ("+decodeURI(json_obj.type)+")";
$("#view").html(output);
}
});
});
}); // ready
</script>
...