You are using an outdated browser. Please upgrade your browser to improve your experience.

12/7 css

java-web-project /webapp/ jsp

jsp파일이 자바 소스코드 파일로 바뀐 다음에 그게 컴파일되어서 servlet 인터페이스를 구현한 서블릿이 되는것.

즉 jsp는 서블릿이다.

더 깊은 지식

jsp엔진이 반드시 httphsppage를 구현하게되는데 그게 결국 servlet을 구현한 것이기 때문에 구현한것이된다. _jspservice()안에 jsp로 작성한 코드가 다 들어가게 되어있음.

jsp 구동원리

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

선언부(declaration element)

<%!
// 다음과 같이 상속 받은 메서드를 오버라이딩 할 수 있다.
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 위치는 상관없다. 자바로 컴파일되면 어차피 상단부에 메서드가 생성된다.

지시문(directive element)

<%@ 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 빌트인 객체
- 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");
%>

jsp액션태그

<%-- 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를 가리킨다. 일관성이 없음..

위 태그는 암기해야한다. 왜냐? 일관성이 없기 때문에.. 하지만 다행인건 자동완성 할 때 위 태그들 중에 선택하게 되어있어서 틀릴 일은 없다.

type과 class로 주는 경우가 다름


<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로 하는 방법밖에 없음.

error.jsp

<%@ 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역할과 용법만 제대로 익혀놓으면 된다.


jstl

ex09

jsp ex09

여기서 database를 쓰는 순간 mvc아키텍쳐가 무너진다. jsp는 출력만 담당해야한다! 명심할 것.

jspel

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가 나중임. 그래서 문법이 ㅁ비슷함.


java project jsp -> jspl로 분리하기

project.member,task,board 모두 jspl로 바꿨음

다만 jsp파일에 자바코드를 두기 더 편할경우 그대로 둬도 됨. 어디까지 최우선은 유지보수를 위한것임! 융통성 있게 코드를 선택하자. 모든 객체지향 방법론은 유지보수를 쉽게하는게 목표다~!

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>");

%>