java-web-project /webapp/ jsp
jsp파일이 자바 소스코드 파일로 바뀐 다음에 그게 컴파일되어서 servlet 인터페이스를 구현한 서블릿이 되는것.
즉 jsp는 서블릿이다.
더 깊은 지식
jsp엔진이 반드시 httphsppage를 구현하게되는데 그게 결국 servlet을 구현한 것이기 때문에 구현한것이된다. _jspservice()안에 jsp로 작성한 코드가 다 들어가게 되어있음.
1) 웹브라우저 ==> 서블릿 컨테이너
- JSP 실행 요청
예) http://localhost:8080/java-web/jsp/ex01.jsp
2) 서블릿 컨테이너가 실행
2.1 JSP의 서블릿 객체를 찾는다
2.2 있으면,
2.2.1 그 서블릿 객체를 호출한다. service() ---> _jspService()
2.3 없으면,
2.3.1 JSP 엔진을 이용하여 JSP 파일을 가지고 서블릿 자바 소스 파일을 생성한다.
2.3.2 자바 컴파일러를 이용하여 소스 파일을 컴파일 한다.
2.3.3 서블릿 객체를 생성한다. - init() 호출 ---> jspInit()
2.3.4 그 서블릿 객체를 호출한다. - service() 호출 ---> _jspService()
2.4 JSP 파일이 변경된 상태라면,
2.4.1 다시 "2.3"을 반복한다.
3) 서블릿 컨테이너 ==> 웹브라우저
- 서블릿 실행 결과를 응답
JSP 파일을 가지고 생성한 서블릿 소스(.java)와 클래스 파일(.class)의 위치
- org.eclipse.wst.server.core/tmpx/work/...
정리!
- JSP 파일은 Python이나 PHP 처럼 직접 그 스크립트가 인터프리팅 되는 것이 아니다.
- JSP 엔진의 역할은 JSP 파일을 분석하여 서블릿 클래스를 생성하는 것이다.
- 즉 JSP 파일이 직접 실행되지 않는다!
JSP
- 자바 서블릿 클래스를 만드는 재료로 사용된다.
- 그래서 서블릿 클래스를 만드는 "틀"이라 해서 "템플릿(template)"이라 부른다.
- JSP를 템플릿 기술이라 부르기도 한다.
JSP 공부법
- JSP를 작성할 때 사용하는 특정 태그들이 어떤 자바 코드를 생성하는지 이해하는 것이 중요하다.
JSP 실행을 요청하기
- JSP 파일이 있는 위치를 지정한다.
예) http://localhost:8080/java-web/jsp/ex01.jsp
JSP를 변경한 후 실행을 요청하기
- 그냥 JSP 파일이 있는 위치를 지정하면 된다.
- 위에서 설명한대로 JSP 구동 원리에 따라 동작된다.
JSP 엔진이 서블릿을 만들 때 지켜야할 규칙:
- JSP 파일을 가지고 서블릿을 만들 때 HttpJspPage를 구현해야 한다.
- 클래스 계층도
Servlet
- init(ServletConfig):void
- destroy():void
- service(ServletRequest, ServletResponse):void
- getServletInfo():String
- getServletConfig():ServletConfig
+---> JspPage
- jspInit():void
- jspDestroy():void
+---> HttpJspPage
- _jspService(HttpServletRequest, HttpServletResponse):void
jsp템플릿데이터
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex02</title>
</head>
<body>
<h1>템플릿 데이터(template data)</h1>
<pre>
- JSP 파일에 그냥 작성하는 텍스트는 자바 출력 코드를 생성한다.
- 예)
out.write("템플릿 데이터")
out.print("템플릿 데이터")
</pre>
</body>
</html>
위 코드가 컴파일되며 이렇게 바뀐다.
out.write("<!DOCTYPE html>\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta charset=\"UTF-8\">\r\n");
out.write("<title>ex02</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("<h1>템플릿 데이터(template data)</h1>\r\n");
out.write("<pre>\r\n");
out.write("- JSP 파일에 그냥 작성하는 텍스트는 자바 출력 코드를 생성한다.\r\n");
out.write("- 예) \r\n");
out.write(" out.write(\"템플릿 데이터\")\r\n");
out.write(" out.print(\"템플릿 데이터\")\r\n");
out.write("</pre>\r\n");
out.write("</body>\r\n");
out.write("</html>");
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"% trimDirectiveWhitespaces="true"%>
trimDirectiveWhitespaces=”true”
<%=name%>
값을 리턴하라는 jsp문장(expression element)
문장을 실행한 후 뭔가 값을 리턴한다 : expression
<%!
// 다음과 같이 상속 받은 메서드를 오버라이딩 할 수 있다.
public void jspInit() {
System.out.println("ex06.jsp의 jspInit()");
}
public void jspDestroy() {
System.out.println("ex06.jsp의 jspDestroy()");
}
%>
<body>
<h1>선언부(declaration element)</h1>
100,000,000 입금 = <%=calculate(100000000)%>
</body>
<%!
double interest = 0.025; // 인스턴스 변수
private String calculate(long money) { // 인스턴스 메서드
return String.format("%.2f", money + (money * interest));
}
%>
declaration 위치는 상관없다. 자바로 컴파일되면 어차피 상단부에 메서드가 생성된다.
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.Statement"%>
무언가를 지시하는것. import문은 자바에서 import로 바뀐다는것만 기억하기.
jsp는 autoflush가 tru이다. false로 설정하는 멍청한 짓 하지 말 것.
이름=<%=pageContext.getAttribute("n")%>, ${n}<br>
,를 기준으로 앞문장과 뒷문장은 같은 뜻이다.
특별한 태그를 쓰기 위해서는 import를 해줘야한다.
jsp외부 태그를 입포트 하기 위해선 url을 이용하고 접두어를 정의해준다.
import문장
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
태그를 쓰는 방법
<c:forEach items="홍길동,임꺽정,유관순,안중근,윤봉길,김구,김원봉" var="n">
이름=<%=pageContext.getAttribute("n")%>, ${n}<br>
</c:forEach>
JSP 빌트인 객체
- JSP를 가지고 서블릿 클래스를 만들 때 _jspService() 메서드에서 기본으로 준비하는 객체
- JSP 엔진은 반드시 다음과 같은 이름으로 레퍼런스를 선언해야 한다.
즉 서블릿 컨테이너(ex: 톰캣, jetty, resin 등)에 상관없이 이름이 같다.
1) request - HttpServletRequest => _jspService() 파라미터이다.
2) response - HttpServletResponse => _jspService() 파라미터이다.
3) pageContext - PageContext => _jspService()의 로컬 변수이다.
4) session - HttpSession => _jspService()의 로컬 변수이다.
5) application - ServletContext => _jspService()의 로컬 변수이다.
6) config - ServletConfig => _jspService()의 로컬 변수이다.
7) out - JspWriter => _jspService()의 로컬 변수이다.
8) page - 서블릿 객체를 가리킨다. 즉 this 이다. => _jspService()의 로컬 변수이다.
9) exception - Throwable => _jspService()의 로컬 변수이다.
- 이 변수는 JSP 페이지가 <%@ page isErrorPage="true"%>로 설정되었을 때만 존재한다.
- 주로 오류가 발생되었을 때 실행되는 JSP 페이지인 경우 위 설정을 붙인다.
<%
// JSP에서 기본으로 준비한 변수를 사용할 수 있다.
request.setAttribute("aaa", "okok");
session.setAttribute("bbb", "nono");
application.setAttribute("ccc", "haha");
out.println("okok");
%>
<%-- bitcamp.vo.Board 객체 생성하기 --%>
<jsp:useBean id="b1" class="com.eomcs.web.vo.Board" scope="page"/>
위 코드는 보드객체를 생성하는 태그이다. 하지만 근래 와선 expression을 쓰기 때문에 거의 볼일은 없으니 한 번 쯤은 알아둬야한다.
<jsp:useBean id="s1" type="java.lang.String" scope="application"/>
<%-- 자바코드로 표현해보면,
String s1 = (String)application.getAttribute("s1");
--%>
<jsp:useBean id="s2" type="java.lang.String" scope="session"/>
<%-- String s2 = (String)session.getAttribute("s2"); --%>
<jsp:useBean id="s3" type="java.lang.String" scope="request"/>
<%-- String s3 = (String)request.getAttribute("s3"); --%>
<jsp:useBean id="s4" type="java.lang.String" scope="page"/>
<%-- String s4 = (String)pageContext.getAttribute("s4"); --%>
위 페이지는 pageContext를 가리킨다. 일관성이 없음..
위 태그는 암기해야한다. 왜냐? 일관성이 없기 때문에.. 하지만 다행인건 자동완성 할 때 위 태그들 중에 선택하게 되어있어서 틀릴 일은 없다.
<jsp:useBean id="list" type="java.util.ArrayList<String>" scope="page"/>
<%-- 자바코드로 표현해보면,
java.util.ArrayList<String> list =
(java.util.ArrayList<String>) pageContext.getAttribute("list");
if (list == null) {
throw new Exception("ArrayList 꺼내기 오류!");
}
--%>
<%
for (String s : list) {
out.println(s + "<br>");
}
%>
위의 코드에서 type부분을 class로 바꿔줄 수 있다.
<jsp:useBean id="list" class="java.util.ArrayList" scope="page"/>
위 코드에서 제네릭을 쓸 수가 없다. 그래서 반복문도 타입을 바꿔줘야한다.
<%
for (Object obj : list) {
out.println(n + "<br>");
}
%>
클래스인경우 null일때 객체생성, type일경우 null일대 예외를 던진다는 것만 기억하기
servlet jsp에서 forward, include하는방법은 requestDispatcher로 하는 방법밖에 없음.
<%@ page
language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
trimDirectiveWhitespaces="true"
errorPage="ex20_error.jsp"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
errorpage로 포워딩 시키지 않으면 실행하던 페이지에서 바로 에러가 뜬다. error.jsp를 만들어 포워딩 시키면 원하는 에러의 출력문구를 예쁘게 볼 수 있다.
포워딩한 error페이지
<%@ page
language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
trimDirectiveWhitespaces="true"
isErrorPage="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex20</title>
</head>
<body>
<h1>오류 발생!</h1>
<%=exception.getMessage()%>
</body>
</html>
<%--
오류가 발생했을 때 실행되는 JSP 페이지는
exception이라는 변수를 통해 오류 내용을 받을 수 있다.
단, isErrorPage 속성이 true이어야 해당 변수가 준비된다.
--%>
isErrorPage=”true”로 설정을 해줘야만 <%=exception.getMessage()%>
태그를 쓸 수 있다.
jsp는 어렵게쓰라고 만든게 아니다. mvc아키텍쳐 내에서의 jsp역할과 용법만 제대로 익혀놓으면 된다.
ex09
jsp ex09
여기서 database를 쓰는 순간 mvc아키텍쳐가 무너진다. jsp는 출력만 담당해야한다! 명심할 것.
I18N(Internationalization 의 약자) => 프로그램을 짤 때 여러 언어를 고려해서 코딩하는 것을 말한다. => 특히 화면에서 버튼에 제목이나 라벨을 출력할 때 특정 언어로 고정된 값을 출력하지 않고, 외부 파일(예: label_ko_KR.properties)에서 읽어 온 값을 출력하도록 프로그래밍 하는 것.
L10N(Localization 의 약자) => 특정 언어에 대해 라벨 텍스트를 담은 프로퍼티 파일(예: label_ko_KR.properties)을 작성하는 것을 말한다.
ognl 표기법 : 프로퍼티만 적으면 일반객체에서 값을 꺼내쓸 수 있음…………………………..
OGNL
<%
Member member = new Member();
member.setNo(100);
member.setName("홍길동");
member.setEmail("hong@test.com");
member.setTel("1111-2222");
pageContext.setAttribute("member", member);
%>
${member.getNo()}<br>
${member.no}<br>
${member.name}<br>
${member["no"]}<br>
${member['no']}<br>
POJO : 간단한 객체는 폼나는 명칭이 없기 때문에 붙인 이름. 말 그대로 해석을 하면 오래된 방식의 간단한 자바 오브젝트라는 뜻임
plain old java object
바닐라js = 순수 js임 완전 맣ㄹ장난!!!!!!! 라이브러리 다운받으면 놀라운게 뭐냐면 0byte라는거 ㅋㅋ
jstl이 먼저고 mybatis가 나중임. 그래서 문법이 ㅁ비슷함.
project.member,task,board 모두 jspl로 바꿨음
다만 jsp파일에 자바코드를 두기 더 편할경우 그대로 둬도 됨. 어디까지 최우선은 유지보수를 위한것임! 융통성 있게 코드를 선택하자. 모든 객체지향 방법론은 유지보수를 쉽게하는게 목표다~!
<fmt:parseDate value="2020-04-14" pattern="yyyy-MM-dd" var="d1"/>
<fmt:parseDate value="04/14/2020" pattern="MM/dd/yyyy" var="d2"/>
<%
Date date1 = (Date)pageContext.getAttribute("d1");
Date date2 = (Date)pageContext.getAttribute("d2");
out.println(date1.toString() + "<br>");
out.println(date2.toString() + "<br>");
%>