2022.08.10 - JSP

sofia·2022년 8월 15일
0

JAVA

목록 보기
16/27
post-thumbnail

📚JSP 세팅

원래 강의에서는 open jdk사용하였지만 삭제하고 java jdk 설치, space_jsp+이클립스 재설치 함

  1. 제어판에서 open jdk삭제(재부팅됨)
  2. java jdk 설치 cmd창으로 버전 확인
  3. D:space_jsp 생성
  4. 이클립스 재설치(기존 D드라이브에 있는거 말고, C드라이브에 재설치)
  5. D:space_jsp 연결
  6. 이클립스 실행하여 new dynamic web project 생성

실험삼아 test용으로 jsp 생성
ctrl+n ⇒ jsp file 선택, test라고 이름 짓고 finish

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	test~
</body>
</html>

ctrl + F11

그러면 자체적으로 이클립스 내에서 웹사이트 오픈됨


📚1장 서블릿과 JSP 프로그래밍(chater 01 PPT)

📘웹 어플리케이션 동작 순서


1. 웹 브라우저 주소란에 URL를 입력하여 요청
2. 웹서버에는 웹브라우저의 요청이 있을 경우 응답해야함. 요청한 페이지는 웹 서버에서 바로 제공하지 않고, 웹 어플리케이션 서버(WAS : Web Application Server)에서 다양한 로직이나 데이터 베이스와의 연동을 통해서 완성되어야지 제공가능
3. WAS는 웹 서버가 클라이언트에게 제공할 페이지를 완성하기 위해서 필요한 로직이나 DB와의 연동과 데이터 처리를 담당
4. 로직이나 데이터 베이스 작업 처리 결과를 웹 서버로 보냄
5. 웹서버는 이를 결과를 클라이언트 측 웹브라우저에 응답함

  • 구성 요소
  1. 웹브라우저: 사용자(클라이언트)가 요청한 웹 서버의 결과를 화면에 출력하는 어플리케이션
  2. 웹서버: 웹 브라우저의 요청을 받아 들여서 그에 대한 결과를 웹 브라우저에 응답해주는 역할로, 요청에 필요한 페이지의 로직이나 DB와의 연동을 위해서 어플리케이션 서버에 처리 요청함
    (EX 아파치,IIS 등)
  3. 웹 어플리케이션 서버 WAS : 요청한 페이지의 로직이나 DB와의 연동을 처리하는 부분
    (EX 웹로직, 웹스파이어, 제우스 ,Planet, Oracle 9iAS 등)
  4. 데이터 베이스 DB : 데이터를 저장하는 곳

📘JSP(Java Server Pages)란?

  1. HTML코드에 Java코드를 넣어 동적 웹페이지를 생성하는 웹어플리케이션 도구
  2. JSP가 실행되면 Servlet(서블릿)으로 변환되어 WAS에서 동작되면서 필요한 기능 수행하고 생성된 데이터를 웹페이지와 함께 클라이언트로 응답함.

📘Servlet 생성

  • Servlet이란?
    :자바 플랫폼에서 동적인 웹을 개발할 때 사용하는 기술로, 웹에서 java프로그래밍 가능.
    웹 요청(Request)과 응답(Response)의 흐름을 간단한 메서드 호출만으로 체계적으로 다룰 수 있게 해주는 기술


패키지에 examples, 클래스에 Hello 작성

package examples;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Hello
 */
@WebServlet("/Hello")
public class Hello extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Hello() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

  • 보면 가끔씩 실행하면 재 작성한 코드가 반영이 안될때가 있는데, 그때는 아래의 Tomcat을 우클릭해서 restart 누르고 재실행 하면 됨.

📚2장 Servlet의 동작원리와 Life Cycle(chater 02 PPT)

📘Servlet 프로그램의 작성법

🎈 JAVA 코드 안에 HTML코드 작성

public class HelloWorld extends HttpServlet { }
HttpServlet 상속 받음

  • Get 방식
    225자 이하
    • URL에 파라미터를 넘기는 방식으로 아이디나 비밀번호등이 노출되어 보안상의 문제 발생)
<form method="get" action="servlet/Method">
<input type="submit" value="get 방식으로 호출하기" >
</form>
  • Post 방식
    225자 이상
    • body영역에 데이터를 실어보냄
    • 요즘엔 Post방식을 사용함.(보안상의 문제로 사용함)
<form method="post" action="servlet/Method">
<input type="submit" value="post 방식으로 호출하기" >
</form>
  • 응답 방식
    resp.setContentType("text/html;charset=euc-kr");
  • 출력 통로
    PrintWriter out = resp.getWriter();
    ⇒메소드 호출해서 객체 생성, PrintWriter타입
    out.println("<html>");
    out.close();

📘Servlet의 동작원리 (중요)


쉽게 말하면 서블릿은 자바 클래스로 웹 애플리케이션을 작성 한 뒤, 웹 서버안에 있는 웹 컨테이너에서 실행하고, 컨테이너에서는 서블릿 인스턴스를 생성 후, 서버에서 실행되다가 웹 브라우저에서 서버에 요청(Request)을 하면 요청에 맞는 동작을 수행하고, 웹 브라우저에 HTTP 형식으로 응답(Response)

  • 수업때도 들었지만 잘 이해 못해서 따로 서블릿이랑 jsp 동작 원리 페이지 만들까 싶음
  • 서블릿 컨테이너
    : 서블릿을 담고 관리하는 컨테이너, 클라이언트에서 요청을 하면 HttpServletRequest, HttpServletResponse 두 객체를 생성하여 get, post 여부에 따라 동적인 페이지를 생성하여 응답함.

주요 기능
1. 생명 주기 관리.
2. 통신 지원
3. 멀티스레딩 관리
4. 선언적인 보안관리

📘Servlet life cycle


1. 서빌릿을 로딩하여 서블릿 인스턴스 생성
(이때, 서블릿 인스턴스는 서블릿 라이프 사이클에서 한번만 생성)
2. init() 메소드 호출
init()메소드는 서블릿을 초기화하는 역할로, 마찬가지로 서블릿 라이프 사이클에서 한번만 호출
3. service() 메소드 호출
요청, 응답을 처리하는 메소드로, 요청을 수신하면, service() 메소드를 호출하는 새로운 스레드 생성
여기서 요청이 Get 요청이면 doGet()메소드를 호출,
Post요청이면 doPost() 메소드를 전달함.
service()메소드는 여러번 호출 될 수 있다.
4. destroy()메소드 호출
서블릿을 종료할때 한번만 실행(서블릿 종료 요청이 있을때 실행됨)

📖관련 예제

📖예제 1

  1. 서블릿 생성할때 name 이후, next>를 누르면

  2. 아래와 같은 페이지가 뜬다. 기본적으로 doGet, doPost가 체크 되어있다.

  3. 아래 코드는 해당 사진에 대해서 만들어짐

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/HelloWorld2")
public class HelloWorld2 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		out.println("<html>");
		out.println("<head>");
		out.println("<title>Hello World!</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h1>Hello World222~!!!</h1>");
		out.println("<h1>안녕하세요~!!!</h1>");//한글이 깨졌음
		out.println("</body>");
		out.println("</html>");
		out.close();
	}

}

근데 실제로 하면 한글은 깨져있다. 그래서
resp.setContentType("text/html");이 아니라
` resp.setContentType("text/html;charset=EUC-KR");```를 사용한다.

📖예제 2


로 생성

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class LifeCycle
 */
@WebServlet("/LifeCycle")
public class LifeCycle extends HttpServlet {
	int initCount = 1;
	int serviceCount = 1;
	int destroyCount = 1;
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드는 첫 요청만 호출됨 : "+initCount++);
	}
	
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("service 메소드는 요청때마다 호출됨 : "+serviceCount++);
	}

	public void destroy() {
		System.out.println("destroy 메소드는 톰캣 종료될때만 호출됨 : "+destroyCount++);
	}
}


(새로 고침할때마다 service()메소드는 호출되기 때문에 증가함을 확인 할 수있음


톰캣 종료시 destroy()메소드 호출

📚3장 Servlet에서 한글 처리와 폼 데이터 처리(chater 03 PPT)

📘웹브라우저에 응답하는 페이지의 한글 처리


resp.setContentType("text/html;charset=euc-kr"); 사용

  • UTF-8 : 조합형 방식의 문자집합으로 초성, 중성, 종성을 각각 1바이트로 인식함, 유니코드 인코딩 방식중 하나
  • EUC-KR : 완성형 인코딩방식으로 한글을 2바이트로 사용하는 문자 집합으로 한글과 영어만 사용하는 페이지에 적합

📘폼 태그의 Get/Post 방식

<FORM method="get/post" action="호출할서블릿파일명“>

  • 예제보면서 공부

📖예제 1

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Method")
public class Method extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=euc-kr");
		PrintWriter out = response.getWriter();
		out.println("<h1>get 방식으로 처리됨 </h1>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=euc-kr");
		PrintWriter out = response.getWriter();
		out.println("<h1>Post 방식으로 처리됨 </h1>");
	}

}
}

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<form method="get" action="Method">
		<input type="submit" value = "get 방식으로 호출하기">
	</form>
	<form method="post" action="Method">
		<input type="submit" value = "post 방식으로 호출하기">
	</form>
</body>
</html>

여기서 알아야하는 건 실행하는 파일은 html 이여야함.
만약에 한글 처리 안하면 한글은 깨짐
response.setContentType("text/html;charset=euc-kr");

📘쿼리 스트링 처리하기

📘Request 객체의 파라미터 관련 메소드

getParameter(String name)
getParameterValues(String name)

String id=req.getParameter("id");

📘쿼리 스트링에 대한 한글처리하기

  • 인코딩(Encoding)
    : 사람이 인지할 수있는 형태의 데이터를 약속한 규칙에 의해 컴퓨터가 사용하는 0과 1로 변환하는 과정

  • 디코딩(Decodoing)
    : 인코딩의 반대

왜 인코딩이 필요한가?
: 웹브라우저와 웹서버는 서로 다른 인코딩 방식을 가지기 때문

req.setCharacterEncoding("euc-kr");

📖예제 2

  • HTML로 입력페이지를 생성하고 데이터 입력(코드 제외)
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/QueryString")
public class QueryString extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		String id="", name="", vclass="", phone1="", phone2="", phone3="";
		id = request.getParameter("id"); //html의 name을 받음
		name = request.getParameter("name"); //html의 name을 받음
		vclass = request.getParameter("class"); //html의 name을 받음
		phone1 = request.getParameter("phone1"); //html의 name을 받음
		phone2 = request.getParameter("phone2"); //html의 name을 받음
		phone3 = request.getParameter("phone3"); //html의 name을 받음
		out.println("<html><head></head><body>");
		out.println("당신이 입력한 정보(get방식)입니다.<br> 아 이 디 : <b>");		
		out.println(id);
		out.println("</b><br> 이름 : <b>"); out.println(name);
		out.println("</b><br> 구분 : <b>"); out.println(vclass);
		out.println("</b><br> 전화번호 : <b>"); out.println(phone1);
		out.println("-"); out.println(phone2);
		out.println("-"); out.println(phone3);
		out.println("</b><br> <a href = 'javascript:history.go(-1)'>다시</a>");
		
		out.println("</body></html>");
	}
}

위와 같은 코드 작성하고 데이터 입력하면 글자 깨짐

(이날 노션 오류가 너무 심해서 이미지가 깨지는 경우가 많았음)

그래서
response.setContentType("text/html;charset=EUC-KR"); 를 추가하고 각 파일의 EUC-KR를 UTF-8로 변경

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/QueryString")
public class QueryString extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		String id="", name="", vclass="", phone1="", phone2="", phone3="";
		id = request.getParameter("id"); //html의 name을 받음
		name = request.getParameter("name"); //html의 name을 받음
		vclass = request.getParameter("class"); //html의 name을 받음
		phone1 = request.getParameter("phone1"); //html의 name을 받음
		phone2 = request.getParameter("phone2"); //html의 name을 받음
		phone3 = request.getParameter("phone3"); //html의 name을 받음
		out.println("<html><head></head><body>");
		out.println("당신이 입력한 정보(get방식)입니다.<br> 아 이 디 : <b>");		
		out.println(id);
		out.println("</b><br> 이름 : <b>"); out.println(name);
		out.println("</b><br> 구분 : <b>"); out.println(vclass);
		out.println("</b><br> 전화번호 : <b>"); out.println(phone1);
		out.println("-"); out.println(phone2);
		out.println("-"); out.println(phone3);
		out.println("</b><br> <a href = 'javascript:history.go(-1)'>다시</a>");
		
		out.println("</body></html>");
	}
}

📘요청(request)객체의 getParameterValues메소드

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MultiPara")
public class MultiPara extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		
//		String item;
		String[] item;
//		item = request.getParameter("item");// 사용자가 입력한 데이터를 가지고 옴
		item = request.getParameterValues("item");
		PrintWriter out = response.getWriter();  //객체생성
		out.println("선택된 항목이");
		
		for (int i = 0; i < item.length; i++) {
			out.println(" : "+item[i]);
		}
		out.println("입니다.");
	}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form method="get" action ="MultiPara">
		<h2>악세서리</h2><br>
		관심항목을 선택하세요...<br>
		<hr>
		<input type="checkbox" name="item" value="신발">신발
		<input type="checkbox" name="item" value="가방">가방
		<input type="checkbox" name="item" value="벨트">벨트<br>
		<input type="checkbox" name="item" value="모자">모자
		<input type="checkbox" name="item" value="시계">시계
		<input type="checkbox" name="item" value="쥬얼리">쥬얼리<br>
		<input type="submit" value="전송">
	</form>
</body>
</html>

📚4장 JSP 원리 분석과 구성요소 (chater 04 PPT)

🎈HTML 코드 안에 Java 코드

📘이클립스의 톰캣 프로젝트와 JSP 컨텍스트 패스

  • JSP 파일은 WebContent에 존재함.

server.xml의 소스 보면 아랫쪽에 적힌 코드

<Context docBase="servletwork" path="/servletwork" reloadable="true" source="org.eclipse.jst.jee.server:servletwork"/>

//서블릿

<Context docBase="jspwork" path="/jspwork" reloadable="true" source="org.eclipse.jst.jee.server:jspwork"/></Host>

//jsp

📘JSP 동작 원리

📘JSP와 서블릿의 처리속도

  • JSP 가 빠름

클래스 파일이 있고 메모리 로드가 있으면 바로 클라이언트 요청을 처리 할 수있기 때문

📘스크립트 요소

  1. 선언문 <%! %>
  • 인스턴스 변수, 메소드, 클래스 정의
  • 선언 후, 변수나 메소드를 이용하여 필요한 동적으로 HTML코드 생성시 사용
  1. 스크립트릿(Scriptlet) <% %>
  • JSP 페이지가 서블릿으로 변환되고 요청될 때 _jspService()안에 선언이 됨
  • 출력하기 위해서 out.println()을 사용
  • 객체 생성가능
  • 메소드 호출(생성은 안됨)
  1. 표현식 <%= %>
  • 보통 결과값을 출력할때 사용
  • 세미클론(;)표시 하지 않음
  • 스크립트릿 코드내에서 out이라는 내장객체를 통해 브라우저에 출력 가능

📖관련 문제 및 예제

📖1

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%! int data = 50; %>
	<% out.println("Value of the variable is : "+data); %>
</body>
</html>

Value of the variable is : 50 출력

📖2

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%! int sum (int a, int b){
		return a+b;
	} //메소드 선언
	%>
	<% //스크립트릿
		int c =3;//변수 선언가능
		out.println("2 + 3 = "+sum(2,3));
	%>
</body>
</html>

2 + 3 = 5 출력

📖3

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%! String makeItLower(String data){
		return data.toLowerCase();
		}
	%>
	
	<%
		out.println(makeItLower("Hello World"));
	%>
</body>
</html>

hello world 출력

📖4

declaration.jsp 파일 생성
선언문 태그에 문자열 변수 선언하여, "Hello, Java Server Pages”를 저장
문자열 변수값을 반환하는 메소드 getString() 작성
getString() 메소드 호출하여 문자열 변수값 출력

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%! 
		String a = "Hello, Java Server Pages";
		String getString(){
		return a;
	} %>
	<% 
		out.println(getString());
	%>
</body>
</html>

📖5

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<center><h3>[ 스크립트릿(scriptlet)에 관한 예제 ]</h3></center>
	<hr>
	<%
		for(int i = 0; i < 5; i++){
			out.println("안녕하세요!");
			out.println("안녕하세요222!");
		}
	%>
	
</body>
</html>


보면 띄어쓰기가 안됨.그럴때에는 <br> 사용

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<center><h3>[ 스크립트릿(scriptlet)에 관한 예제 ]</h3></center>
	<hr>
	<%
		for(int i = 0; i < 5; i++){
			//out.println("안녕하세요!");
			//out.print("안녕하세요222!");
			
	%>
			안녕하세요333!<br>
	<% 
			
		}
	%>
	
</body>
</html>

📖6

연습문제 4-2
scriptlet.jsp 파일 생성
스트립트릿 태그를 이용하여 java.util.Date형 지역변수에 현재 날짜를 저장
현재 날짜값을 출력

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%
		Date now = new java.util.Date();
	%>
	
	<%	
		out.println("Today : "+now);
	%>
</body>
</html>

📖7

expressio.jsp 파일 생성

표현문 태그에 java.util.Calendar 클래스를 이용하여 현재시간을 출력

<%@page import="java.util.Calendar"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<% 
		int hour = Calendar.HOUR_OF_DAY;
		int minute = Calendar.MINUTE;
	
	%>
	현재 시간 : 
	<%=
		hour +"시"+ minute +"분"
	%>

</body>
</html>

📖8 파일 삽입

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%!
		String name="홍길동";
	%>
	<%
		String addr="서울시 송파구 석촌동";
	%>
	
	이름 :
	<%= name %><%--(expression을 이용해서 출력 --%> 
	<br>
	주소 : 
	<%
		out.println(addr);
	%>
	
	<br>
	<%-- 파일 삽입 --%> 
	<jsp:include page="age.jsp"></jsp:include>
	
</body>
</html>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
나이 : 20


📚Reference

참고한 다른 분들의 블로그 또는 관련 링크들

0개의 댓글