JSP : 내장 객체 / application + cookie

부트캠프(END)/Web|2022. 7. 20. 21:38

application : javax.servlet.ServletContext

Servlet 또는 어플리케이션 외부 환경 정보(=Context)를 나타내는 내장 객체.

어플리케이션이 실행되는 서버의 정보와 서버 측 자원에 대한 정보를 얻을 수 있다.

또한 어플리케이션이 실행되는 동안 발생할 수 있는 이벤트의 로그 또한 제공한다.


간단히 말해, 서버의 이름, 버전, 로그파일, 실제 경로 등의 서버 정보를 담고 있다. 

 

application 객체에는 프로젝트에 있는 모든 JSP에서 접근이 가능하다.
즉, 프로젝트가 공유하는 데이터가 있다면 application에 들어가서 처리가 가능하다.
request 객체의 경우 jsp 페이지마다 따로 갖고있기 때문에,

B페이지에서 A페이지의 값을 사용하려면 get/post 방식을 이용해 전송을 해 주어야 한다.

A페이지와 B페이지가 동시에 공통으로 쓸 수 있는 것 → session, application에 저장된 정보들

 

log(message) : 로그 파일에 message를 기록한다. 

→ sysout과 비슷하다. 단, 서버 관리자만 볼 수 있는 메시지를 출력한다!

getServletInfo() : Servlet 컨테이너의 이름과 버전을 반환한다.

getMinorVersion()/getMajorVersion() : 각 Servlet의 버전의 소수점 부분/정수 부분을 반환한다.

getInitParameter() : web.xml에 등록된 내용을 읽어올 수 있다.

***getRealPath() : URL을 로컬 파일 시스템으로 변경해서 반환한다.

여기에 저장하지 않으면 새로고침해야 화면이 전환된다.

 

 

web.xml

<context-param> 태그로 변수를 입력할 수 있다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 
id="WebApp_ID" version="4.0">
  <display-name>0720JSP_application</display-name>
  <context-param>
    <param-name>driver</param-name>
    <param-value>oracle.jdbc.driver.OracleDriver</param-value>
  </context-param>
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:oracle:thin:@localhost:1521:XE</param-value>
  </context-param>
  <context-param>
    <param-name>username</param-name>
    <param-value>user</param-value>
  </context-param>
  <context-param>
    <param-name>password</param-name>
    <param-value>0000</param-value>
  </context-param>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
</web-app>

web.xml에서 값을 읽어오려면...

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%-- Dynamic web module version (Servlet 버전) 4.0 이면 Major = 4, Minor = 0 --%>
    <%=application.getMajorVersion() %><br>
    <%=application.getMinorVersion() %><br>
    <%=application.getServerInfo() %><br>
    <%-- log : 어디서 에러가 났는지, 정상적으로 실행하고 있는지 = 서버 관리자--%>
    <%
        //web.xml에 등록된 값 읽기
        String driver = application.getInitParameter("driver");
        String url = application.getInitParameter("url");
        String username = application.getInitParameter("username");
        String password = application.getInitParameter("password");
        application.log("Driver:"+driver); //이클립스 콘솔에만 노출됨
        application.log("URL:"+url);
        application.log("Username:"+username);
        application.log("Password:"+password);
    %>     
    <%=application.getRealPath("/") %> <%-- Root 경로 확인 (실제로 톰캣이 읽어가는 위치)--%>
    
</body>
</html>

실행 결과

 

 

input.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- Realpath 가 아니면 어떤 일이 일어나는지 보여주지 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%-- "/" 해주면 root라는 의미임. --%>
    <%=application.getRealPath("/") %>
    <form method=post action="input_ok.jsp" enctype="multipart/form-data">
    <%--액션이 일어나면 input_ok로 보낼게--%>
    <input type=file name=upload size=20>
    <button>전송</button>
    </form>
</body>
</html>

 

input_ok.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.oreilly.servlet.*"%>
<%@ page import="com.oreilly.servlet.multipart.*"%>

<%
//  String path = "C:\\webDev\\webStudy\\0720JSP\\src\\main\\webapp\\image";
    String path = "C:\\webDev\\webStudy\\.metadata\\"
    +".plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\0720JSP\\image_realpath";
    //실제 톰캣이 읽어가는 주소를 가져오는 게 realPath()

    //업로드(생성자만 등록하면 업로드는 완료)
    MultipartRequest mr = 
    new MultipartRequest(request, path, 1024*1024*100, "UTF-8", new DefaultFileRenamePolicy());
    //화면 이동
    response.sendRedirect("output.jsp");
    
%>

 

output.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<img src="../image_realpath/a.jpg">
</body>
</html>

 

 

Cookie : javax.servlet.http

쿠키는 JSP 내장 객체가 아니라 일반 객체다!

자동 로그인, 최신 방문 정보 출력 등의 기능을 구현하는 데에 사용되며, 로컬에 관련 정보를 저장한다.

 

즉, 각각의 브라우저를 판별할 수 있는 정보가 포함되어 있다!

쿠키가 브라우저에 한 번 저장이 되고 나서 다시 서버로 요청을 할 때는

클라이언트에 저장된 쿠키가 요청에 포함되어 서버로 전송된다.

이 쿠키를 서버가 읽어서 같은 브라우저로부터 온 요청이라는 걸 인식할 수 있게 된다.

단, Object로 저장되는 세션과 달리 쿠키는 문자열 형태로 저장된다.

 

 

쿠키와 관련된 메서드

1. 생성
new Cookie(키,값);  : 쿠키 생성
setPath() : 쿠키 저장경로 지정
setMaxAge() : 쿠키 저장기간 지정(단위:초)
→ response.addCookie()로 client에 쿠키 전송


2. 쿠키 읽기
Cookie[] cookies = request.getCookies(); 로 쿠키 가져옴
getName() : key 읽어오기
getValue() : value 읽어오기


3. 쿠키 삭제
setMaxAge(0) : 저장기간을 0으로 만듬으로써 삭제

 

//쿠키 사용 예시
//- 쿠키 생성
Cookie cookie = new Cookie(key, value);
//- 저장 위치 지정
cookie.setPath("/"); //보통 root에 많이 저장함
//- 기간 설정
cookie.setMaxAge("초 단위"); //60*60*24 -> 하루동안 저장
//- 클라이언트로 전송
response.addCookie();

 

 

 

 

cookie 예제

식당 목록을 띄우고, 해당 식당의 정보를 조회하면 쿠키를 생성하여 저장하고,조회한 식당 목록을 저장하여 아래와 같이 유저에게 보여주는 예제! + 검색도 가능!

 

 

더보기
package dao;
import java.util.*;
import java.sql.*;
import doodoo.conn.*;

public class FoodDAO {
	private Connection conn;
	private PreparedStatement ps;
	private DBConnection dbConn = DBConnection.newInstance();
	
	//목록 출력
	public List<FoodVO> foodListData(String fd, int page){
		List<FoodVO> list = new ArrayList<FoodVO>();
		try {
			conn = dbConn.getConnection();
			String sql = "SELECT fno, poster, name, score, type, address, num "
					+"FROM (SELECT fno, poster, name, score, type, address, rownum as num "
					+"FROM (SELECT fno, poster, name, score, type, address "
					+"FROM food_location WHERE address LIKE '%'||?||'%')) "
					+"WHERE num BETWEEN ? AND ?";
			ps = conn.prepareStatement(sql);
			ps.setString(1, fd);
			int rowSize = 9;
			int start = (rowSize*page)-(rowSize-1);
			int end = rowSize*page;
			ps.setInt(2, start);
			ps.setInt(3, end);
			
			ResultSet rs = ps.executeQuery();
			while(rs.next()) {
				FoodVO vo = new FoodVO();
				vo.setFno(rs.getInt(1));
				vo.setPoster(rs.getString(2));
				vo.setName(rs.getString(3));
				vo.setScore(rs.getDouble(4));
				vo.setType(rs.getString(5));
				vo.setAddress(rs.getString(6));
				
				list.add(vo);
			}
			rs.close();
		}catch(Exception ex) {
			ex.printStackTrace();
		}finally {
			dbConn.disConnection(ps);
		}
		return list;
	}
	//총 페이지
	public int foodTotalPage(String fd) {
		int total = 0;
		try {
			conn = dbConn.getConnection();
			String sql = "SELECT CEIL(COUNT(*)/9.0) "
					+"FROM food_location "
					+"WHERE address LIKE '%'||?||'%'";
			ps = conn.prepareStatement(sql);
			ps.setString(1, fd);
			ResultSet rs = ps.executeQuery();
			rs.next();
			total = rs.getInt(1);
			rs.close();
		}catch(Exception ex) {
			ex.printStackTrace();
		}finally {
			dbConn.disConnection(ps);
		}
		return total;
	}
	
	//상세 보기
	public FoodVO foodDetailData(int no) {
		FoodVO vo = new FoodVO();
		try {
			conn = dbConn.getConnection();
			String sql = "SELECT fno, poster, name, tel, score, type, price, parking, menu, time, address "
					+ "FROM food_location "
					+ "WHERE fno=?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, no);
			ResultSet rs = ps.executeQuery();
			rs.next();
			vo.setFno(rs.getInt(1));
			vo.setPoster(rs.getString(2));
			vo.setName(rs.getString(3));
			vo.setTel(rs.getString(4));
			vo.setScore(rs.getDouble(5));
			vo.setType(rs.getString(6));
			vo.setPrice(rs.getString(7));
			vo.setParking(rs.getString(8));
			vo.setMenu(rs.getString(9));
			vo.setTime(rs.getString(10));
			vo.setAddress(rs.getString(11));
			
			rs.close();
		}catch(Exception ex) {
			ex.printStackTrace();
		}finally {
			dbConn.disConnection(ps);
		}
		return vo;
	}
}

 

 

detail_before.jsp

 

list.jsp에서 식당 이미지를 클릭하면 해당 식당의 상세 페이지로 넘어 간다. (detail.jsp?no=..로 이동)

페이지를 이동하면 파일이 바뀌기 때문에 이동하기 전에 필요한 정보를 넘겨 주어야 한다.

 

⑴ request에서 받은 no 파라미터의 값을 fno로 받아 주고, 이를 이용해 쿠키를 생성한다.

⑵ 쿠키의 경로와 유효시간을 지정하고, 쿠키를 response에 담아 전송한다.

⑶ 상세 페이지로 이동시킨다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String fno = request.getParameter("no");
	Cookie cookie = new Cookie("f"+fno,fno); //중복이 없다.
	cookie.setPath("/");
	cookie.setMaxAge(60*60*24);
	response.addCookie(cookie); //쿠키 전송
	//페이지 이동
	response.sendRedirect("food_detail.jsp?no="+fno);
%>

 

 

food_detail.jsp

 

상세 페이지에서 사용자가 요청한 값을 보여 준다.

다시 목록으로 돌아갈 때, javascript:history.back()을 사용하지 않는 것에 유의한다. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*, dao.*"%>
<%
	String no = request.getParameter("no");
	FoodDAO dao = new FoodDAO();
	FoodVO vo = dao.foodDetailData(Integer.parseInt(no));
	String address = vo.getAddress();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="table.css">
</head>
<body>
  <div class="container">
   <div class="row">
	  <div class="header">
	   <table>
	     <tr>
	         <td align="center">
	           <img src="<%=vo.getPoster() %>" width=100%>
	         </td>
	     </tr>
	   </table>
	  </div>
	  <div class="section">
	    <table class="table_content" width="700">
	      <tr>
	        <td colspan="2">
	          <h3><%=vo.getName() %>&nbsp;
	          <span style="color:orange"><%=vo.getScore() %></span></h3>
	        </td>
	      </tr>
	      <tr>
	        <th width=20%>주소</th>
	        <td width=80% align="left"><%=vo.getAddress() %></td>
	      </tr>
	      <tr>
	        <th width=20%>전화</th>
	        <td width=80% align="left"><%=vo.getTel() %></td>
	      </tr>
	      <tr>
	        <th width=20%>음식 종류</th>
	        <td width=80% align="left"><%=vo.getType() %></td>
	      </tr>
	      <tr>
	        <th width=20%>가격대</th>
	        <td width=80% align="left"><%=vo.getPrice() %></td>
	      </tr>
	      <tr>
	        <th width=20%>영업 시간</th>
	        <td width=80% align="left"><%=vo.getTime() %></td>
	      </tr>
	      <tr>
	        <th width=20%>주차</th>
	        <td width=80% align="left"><%=vo.getParking() %></td>
	      </tr>
	      <%
	      	if(!vo.getMenu().equals("no")){
	      %>
	      <tr>
	        <th width=20%>메뉴</th>
	         <td width=80% align="left">
	         <ul>
	        <%
	        	st = new StringTokenizer(vo.getMenu(),"원");
	        	while(st.hasMoreTokens()){
	        		out.println("<li>"+st.nextToken()+"원</li>");
	        	}
	        %>
	         </ul>
	         </td>
	      </tr>
	      <%} %>
	      <tr>
	        <td colspan="2" align=right>
	          <a href="#">찜하기</a>&nbsp;
	          <a href="#">예약</a>&nbsp;
	          <a href="food_list.jsp">목록</a>&nbsp;
	          <%-- javascript:history.back()하면 쿠키저장 안됨 --%>
	        </td>
	      </tr>
	    </table>
	  </div>
   </div>
  </div>
</body>
</html>

 

 

food_list.jsp

 

jsp 페이지에서 HTML 영역 의 <%..%> 내에 들어가는 자바 코드부터 살펴보자.

 

기본적으로 검색어 fd와 요청한 페이지 page 라는 두 개의 파라미터를 받으며 시작한다.

게시판 짤 때와 마찬가지로 맨 처음 사용자가 들어왔을 때는 이 두 파라미터가 null이므로 기본값을 부여한다.

//데이터받기 => 검색어 , 페이지 
request.setCharacterEncoding("UTF-8");
String fd = request.getParameter("fd");
String strPage = request.getParameter("page");

if (fd == null)
  fd = "역삼";
if (strPage == null)
  strPage = "1";

// 현재 페이지 등록
int curpage = Integer.parseInt(strPage);

 

DAO 에 연결하여 fd와 curpage를 넣고 목록에 출력할 리스트를 받아와 출력한다.

// 결과값 읽기 
FoodDAO dao = new FoodDAO();
List < FoodVO > list = dao.foodListData(fd, curpage);
for (FoodVO vo: list) {
  String poster = vo.getPoster();
  poster = poster.substring(0, poster.indexOf("^"));
  vo.setPoster(poster);
  // 	서울특별시 마포구 연남로1길 11 1F
  String address = vo.getAddress();
  String addr1 = address.substring(address.indexOf(" "));
  String addr2 = addr1.trim().substring(0, addr1.trim().indexOf(" "));
  vo.setAddress(addr2);
}
int totalpage = dao.foodTotalPage(fd);

 

 

그리고 지금까지 상세 페이지를 조회한 적 있는 식당의 정보의 쿠키들을 포함한 목록을 출력한다!

 

⑴ 조회한 적 있는 식당의 리스트를 저장할 cList를 생성한다.

⑵ Cookie 객체의 배열을 만들고 request.getCookies()로 쿠키들을 가져와 담아 준다.

⑶ 최근에 조회한 것부터 보여줄 것이므로 cookies.length-1 부터 0까지 for문을 작성한다.

이 때 쿠키는 모든 URL주소를 다 저장하기 때문에 식당의 정보와 관련된 쿠키만 가져와야 한다.

따라서, 아까 쿠키를 저장할 때 넣어 준 구분자 f로 시작하는 쿠키만을 가져와 no를 cList에 저장한다.

//쿠키가 저장된 식당 리스트
List < FoodVO > cList = new ArrayList < FoodVO > (); 
//쿠키 가져오기
Cookie[] cookies = request.getCookies();
//쿠키는 왔다갔다했던 모든 URL주소를 다 저장한다. 그 안에서 식당과 관련된 것만 골라낼 수 있어야 함.
//그래서 food_detail.jsp 에서 fno로 구분을 지었죠...
if (cookies != null) {
  for (int i = cookies.length - 1; i >= 0; i--) {
    //최신꺼니까 맨 마지막것부터 가져와야함.
    if (cookies[i].getName().startsWith("f")) {
      String no = cookies[i].getValue();
      FoodVO vo = dao.foodDetailData(Integer.parseInt(no));
      cList.add(vo);
    }
  }
}

 

화면에 적절히 뿌려서 보여 주면 끝!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ page import="dao.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
   <div class="container">
     <div class="row">
       <div class="find">
        <form method=post action="food_list.jsp">
         Search:<input type=text size=30 name=fd>
         <input type=submit value="검색">
        </form>
       </div>
     </div>
     <div style="height: 30px"></div><!-- 위 아래 간격 -->
     <div class="row">
       <div class="food_list">
       <%
          for(FoodVO vo:list)
          {
       %>
       <%-- Response가 전송할 수 있는 것은 HTML과 Cookie뿐이다.
       	한 개의 JSP에서는 두 개를 동시에 전송할 수 없다.
       	 --%>
        <a class="food" href="detail_before.jsp?no=<%=vo.getFno()%>">
          <img src="<%=vo.getPoster() %>" style="width:230px;height: 150px">
          <div class="food_name"><%=vo.getName() %>&nbsp;
          <span style="color:orange"><%=vo.getScore() %></span></div>
          <div class="food_name"><%=vo.getType() %>-<%=vo.getAddress() %></div>
        </a>
        <%
          }
        %>
       </div>
     </div>
     <div style="clear: both;"></div>
     </div>
     <div style="text-align: center">
       
         <%
            for(int i=1;i<=totalpage;i++)
            {
         %>
               [<a href="food_list.jsp?page=<%=i%>&fd=<%=fd%>"><%=i %></a>]
         <%
            }
         %>
     </div>
   <h1>최근 본 맛집-Cookie</h1>
   <a href="cookie_delete.jsp">쿠키삭제</a>
   <hr>
   <div>
     <%
       int k=0;
       for(FoodVO vo:cList){
    	   if(k>9)
    		   break;
     %>
     	<%-- 여기는 이미 쿠키에서 넘어온 거니까 다이렉트로 넘어가게 한다. 
     	detail_before가 아니라... --%>
     	<a href="food_detail.jsp?no=<%=vo.getFno()%>">
     	<img src="<%=vo.getPoster().substring(0,vo.getPoster().indexOf("^")) %>" width=100 height="100">
     	</a>
     <%
     	k++;
       } %>
   </div>
</body>
</html>

 

 

cookie_delete.jsp

쿠키 삭제는 setMaxAge() 메서드를 사용해 저장기간을 0으로 수정 후 다시 추가해 주면 된다. 간단!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	Cookie[] cookies = request.getCookies();
	if(cookies!=null){
		for(int i=0; i<cookies.length; i++){
			if(cookies[i].getName().startsWith("f")){
				cookies[i].setPath("/");//저장된 위치에서
				cookies[i].setMaxAge(0);//저장기간을 0으로 만들기
				response.addCookie(cookies[i]);
			}
		}
	}
	
	response.sendRedirect("food_list.jsp");
%>

 

끝!

 

'부트캠프(END) > Web' 카테고리의 다른 글

jspBean  (0) 2022.07.21
JSP : 액션 태그  (0) 2022.07.19
JSP : 내장 객체 / request, response, pageContext  (0) 2022.07.18

댓글()