앞서 배웠지만 31강에서는 쿠키를 얼마나 유지시킬 것인지를 설정하는 방법에 대해서 배운다.
브라우저가 닫혔다.
그러면 쿠키는 어떻게 되었을까?
기본적으로 Cookie의 maxAge를 설정하지 않으면 브라우저의 생존주기와 같아진다.
쿠키의 가장 큰 장점은 브라우저가 닫혀도 기반을 서정하면 그 기간동안 값이 유지되도록 할 수 있다는 것
그렇다면 브라우저가 닫혔는데 쿠키는 어디에 저장되어 있는 걸까?
브라우저 안에 있다가 외부파일로 저장된다.
valueCookie.setPath("/calc2");
//만료날짜까지 valueCookie가 유지
valueCookie.setMaxAge(24*60*60);
//opCookie 브라우저 닫히면 사라짐
opCookie.setPath("/calc2");
value의 만료날짜와 op의 만료날짜를 보자
이제 Microsoft Edge 브라우저는 닫고 다시 설정을 들어가면 만료날짜가 남은 value 쿠키가 남아있다.
만약에 cnt에 3을 1년동안 저장하고 싶다
우리는 저 3개 중에 어떤 것을 사용할까?
기간이 이렇게 길어지면 무조건 Cookie에 저장한다.
Session은 1년동안 쓸 수 없다.
사용자의 식별 아이디가 107이라고 하자 만약에 이 사용자가 1년동안 남아있고 Session을 닫았다.
똑같은 사용자가 열면 이 때는 107이 아닌 108을 받고 다시 1년동안 Session애 남아있는다. 매우 비효율적이다.
그 전에 우리는 쿠키를 전달받고 다시 뒤로가기 버튼을 통해서 html을 불러왔다. 그 과정에 중간에 빈 화면이 존재했는데
이렇게 말고 바로 html에 화면을 전환하는 방법에 대해서 알아보자.
이 문장을 추가함으로써 사용자는 html주소를 요청한 적이 없음 마치 사용자가 요청한 것처럼 페이지를 가지고 있게 된다.
여기서부터 많이 중요하고 재밌어진다.
사실 우리가 쓰는 계산기는 누적된 값을 보여주는데
이는 동적이라고 할 수 있다.
앞서 말했지만 정적이다= 같은 페이지를 보여준다
동적이다 = 업데이트된 데이터가 반영된 페이지를 보여준다 라고 이해할 수 있다.
그러나 우리가 앞서 배웠던 부분은 모두 정적이었고 이 계산기 예제를 통해서 동적인 것에 대해서 배우기 시작한다.
사실 이 동적인 페이지를 만들기 위해서 jsp가 등장했다.
3을 눌렀으면 3을 심어서 html을 돌려줘야 한다.
정적인 것이 아닌 동적으로
그러나 html은 그게 안되기 때문에 서블릿으로 동적으로 작동하도록 만들어줘야 한다.
따라서 위와 같이 요청이 있을 때 만들어지는 동적인 서버문서를 만들어보자.
먼저 계산기 형식을 가지는 html을 준비하자
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
input{
width:50px;
height:50px;
}
.output{
height:50px;
background:#e9e9e9;
font-size:24px;
font-weight:bold;
text-align:right;
padding:0px 5px;
}
</style>
</head>
<body>
<form action="calc3" method="post">
<table>
<tr>
<td class="output" colspan="4">0</td>
</tr>
<tr>
<td><input type="submit" name="operator" value="CE"></td>
<td><input type="submit" name="operator" value="C"></td>
<td><input type="submit" name="operator" value="BS"></td>
<td><input type="submit" name="operator" value="÷"></td>
</tr>
<tr>
<td><input type="submit" name="value" value="7"></td>
<td><input type="submit" name="value" value="8"></td>
<td><input type="submit" name="value" value="9"></td>
<td><input type="submit" name="operator" value="X"></td>
</tr>
<tr>
<td><input type="submit" name="value" value="4"></td>
<td><input type="submit" name="value" value="5"></td>
<td><input type="submit" name="value" value="6"></td>
<td><input type="submit" name="operator" value="-"></td>
</tr>
<tr>
<td><input type="submit" name="value" value="1"></td>
<td><input type="submit" name="valuer" value="2"></td>
<td><input type="submit" name="value" value="3"></td>
<td><input type="submit" name="operator" value="+"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="value" value="0"></td>
<td><input type="submit" name="dot" value="."></td>
<td><input type="submit" name="operator" value="="></td>
</tr>
</table>
</form>
</body>
</html>
다음에는 JSP를 통해 더 간단히 만들어 볼것이다.
서비스라는 함수에 동적으로 만드는 코드를 넣을 것이다.
정말 생고생이다.
앞서 만들었던 계산기 html을 그대로 복사하고
앞에서 out.write를 넣어 출력해야 하며
또한 동적인 부분은 out.printf로 하여 내용이 동적으로 조절이 가능하도록 하였다.
동적이기 때문에
이렇게 3+4가 계산된 결과가 출력된다.
하지만 html에서는
계산되지 않고 3+4가 그대로 출력된다.
앞서 만든 계산기는 계산은 하지 않고
동적으로 움직이는 계산기 형태만 만들어 놓은 View단이라고 볼 수 있겠다.
이제는 정말로 계산을 하는 서블릿을 구현해야 한다.
전체적으로 calc3.java 에서 데이터를 누적하고-> 이를 쿠키에 저장하여-> 저장된 정보를 calcPage에서 출력하는 흐름으로 갈 것이다.
다시 한번 말하지만 동적인 페이지 구축을 위해서
html파일이 아닌 서블릿으로 구현하였고
따라서 두개의 서블릿을 이용한다
하나는 html을 대신할 뷰단의 서블릿과
나머지 하나는 계산을 실제 실행하고 누적의 역할을 하는 서블릿이다.
보이는 부분은 이렇게 설정하지만
쿠키들을 exp에 누적해서 동적으로 보여주도록 한다.
실제 계산을 담당하는 서블릿인데
이클립스 버전이 높아서 강의에서 제시한 방법으로는
위와 같은 오류가 발생하기 때문에
한자리수 연산만 가능한 간단한 계산이 가능하도록 하는 방법을 넣었다.
계산기의 값을 초기화하는 방법이다.
계산기의 Clear라는 C 버큰을 클릭했을 때 쿠키를 삭제하는 방법에 대해서 알아보자.
이렇게 설정하는게 맞는 것일까?
개발자 도구의 쿠키를 보면 쿠키가 존재한다. 따라서 쿠키 자체를 지워버리는 방법으로 올바르지 않다.
위의 설정에 추가적으로 setMaxAge(0)로 설정한다.
즉 사용하고 즉시 삭제하는 것이다.
먼저 Servlet에서 GET과 POST의 차이를 알아보자
GET : Client의 요청 메시지를 URL에 직접 담아준다. 따라서 URL에서 사용자 입력 정보를 볼 수 잇다.
POST : Client의 요청 메시지는 URL에 직접 담아주지 않고 암호화해서 body에 담아주고 전송한다.
사실 앞에 우리는 이 method의 속성을 POST로 설정한 예시에 대해서 배웠다. 입력값이 너무 긴 경우 URL에 모두 들어가기에 주소가 너무 지저분하기 때문에 POST로 설정하는 방법을 배운적이 있다.
간단한 html을 만들어보자.
get 요청의 경우에는 콘솔창에 "GET 요청이 왔습니다."가 출력되도록
post 요청의 경우에는 콘솔창에 "POST 요청이 왔습니다."가 출력되도록 설정하였다.
여기서 주의할 것은 method의 속성값이 get과 post 소문자이지만 이 인자를 받을 때는 대문자가 되기 때문에 getMethod는 대문자로 값을 받는다.
service() 함수는 get,post 요청인지에 따라
get-> doGet() / post->doPost()를 실행하도록
오버라이딩 할 수 있다.
오버라이딩이란 부모 메소드를 재정의하는 것이다.
선택해야할 것이다.
service()를 오버라이딩 해서 get,post 둘다에 반응할 것인지
아니면 doGet() 혹은 doPost()만 오버라이딩 해서 하나의 요청에만 반응할 것인지
만약에 우리가
위 처럼 super.service(req,resp)를 코드에 추가해서 입력한다면
405에러가 발생하는데 405는 url은 있으나 post를 처리할 수 있는 메서드가 없다는 것이다.
따라서 오버라이딩을 해야한다.
doPost()함수를 오버라이딩하여 오류를 해결한다.
따라서 2가지 방법이 있다.
1. service() 함수를 통해서 doGet()과 doPost()호출되므로 service()를 오버라이딩하기.
2. service() 함수가 아닌 특화된 doGet()과 doPost()를 넣어버리기.
앞서서
GET : Client의 요청 메시지를 URL에 직접 담아준다. 따라서 URL에서 사용자 입력 정보를 볼 수 잇다.
POST : Client의 요청 메시지는 URL에 직접 담아주지 않고 암호화해서 body에 담아주고 전송한다.
이렇게 차이를 말했지만 하나 더 있다.
GET : 데이터 전달이 목적이 아니라 페이지 연결이 주목적
POST : 데이터 전달이 주목적
따라서 서버에 get 요청을 하면 그것을 담당하는 servlet이 calpage를 생성한다 (계산기 UI)
이 계산기 UI에서 숫자 '5'를 누르면 post 요청이 그것을 담당하는 servlet인 calc3를 생성한다.
하지만 으 두개의 서블릿은 하나로 합쳐질 수 있다.
이렇게 두개의 서블릿이 존재하는 것은 쿠키에 대한 문제가 발생한다. setPath()를 지정할 때 우리는 두개의 path를 지정하는 것이 불가능하기 때문에 모든 루트에 쿠키가 가도록 설정할 수 밖에 없다.
하지만 이 페이지를 루트로 설정하기에는 부담이 크다.
따라서 두 개의 servlet을 합치는 방법에 대해서 생각해야 한다.
이렇게 말이다.
드디어 JSP까지 왔다.
이제는 out.write가 아닌 JSP 를 이용한 Servlet 프로그램을 만들어보도록 하자.
Jasper에게 일을 시키고 싶다면 이제 html파일의 확장자를 .jsp로 고쳐 저장하면 된다.
그렇다면 언제 out.write와 같은 형태로 바꿔주는 것일까?
사용자가 이 확장자를 가진 페이지를 요청할 때 바뀐다.
또한 파일명이 url이 된다.
그러나 jsp가 아닌 java나 html은 우리가 따로 지정해야 했다.
실제 파일명은
이와 같이 저장된다.
동적 페이지이기 때문에 아래와 같이 계산해서 보여준다.
<td class="output" colspan="4">${3+4}</td>
개발자 환경에서 소스를 보면 7로 계산되어져 있다.
여기서 드는 의문!
분명히 서블릿 코드로 만들었다. 그렇다면 그 결과물을 볼 수 있을까?
불 수 있다.
브러우저에 보는 문서는 WEB-INFO에 있는 문서가 아니다.
처음 입문하게 될 때는 ctrl+f11을 같이 누르면 브라우저가 떠서 저기가 홈 디렉토리인줄 알지만 그것은 아니다.
이걸 배포하게 되면 그게 실제 톰캣의 홈디렉토리로 옮겨지게 된다.
우리가 사용하는 톰캣이 실제 다른 서비스를 운영할 수도 있기 때문이다. 따라서 실제 워크 디렉토리가 아닌 이클립스가 관리하는 별도의 운영을 위한 곳에 복사본을 두게된다.
여기가 개발할 때 사용되는 임시 배포 디렉토리이다.
실제로 저 파일 들어가면 저 코드는 Jasper가 만든 Servlet 코드이다.
중요한 것! 바로 모든 코드에 out.write를 붙이기 때문에
위와 같이 int x=3 의 코드에 jasper는 out.write를 붙여 계산기 앞에 출력한다.
따라서 <% %>를 붙여야 코드로 인식한다는 것을 기억해라
JSP : 서블릿을 간접적으로 만드는 방법
동적인 페이지를 위해서 out.write를 붙였다.
그러나 너무 귀찮기 때문에 우리는 jsp를 이용하였다.
출력 문장 사이에 java 코드를 끼어넣을 수 있는 몇 가지 코드 블럭에 대해서 알아보자.
.jsp라는 확장자를 가진 문서를 받으면 jasper는 무조건 아래와 같은 .java 파일을 만든다. 우리가 만약에 jsp에 환영합니다. 라고 쓴다면 jspService 지역변수 알고리즘에 out.write("환영합니다.")라고 적힐 것이다.
그러나 우리는 변수나 연산해서 출력하고자 할 때 어떻게 표현해야 하나 의문점을 가진다.
만약에 y의 값은 : y
를 출력하고자 한다면 'y의 값은:'은 그대로 출력하고 'y'은 변수이다.
이 때 jsp에 y의 값은: <% out.print(y)%>로 표현한다.
이보다 간단한 방법은
위와 같이 y의 값은: <% =y%> 이렇게 표현하는 것이다.
그런데 만약에 함수를 정의하고자 할 때는 어떻게 할까? 우리가 배운 앞의 방법은 지역변수 알고리즘에 들어간다.
만약에 함수를 저렇게 정의하면 java 문법에 어긋난다. 왜냐하면 java의 경우 함수 안에 함수를 정의할 수 없기 때문에 따라서 멤버함수로 정의를 하자.
위처럼 표현하면 지역변수 알고리즘에 들어간다. 따라서 저렇게 <% %>안에 넣는 것이 아니라 !를 추가해서 <%! %>이렇게 선언하자
위 예시를 보자 <%@ %>
앞에 @가 붙었다.
이를 우리는 코드블럭이라 하지 않고 Page 지시자라고 한다.
내용이 자바 코드는 아니고 보면 키와 값의 짝으로 되어져 있다.
왜 지시 블록이 필요할까?
출력할 때 UTF-8로 설정하고 브라우저가 그걸 그렇게 인식할 수 있게끔 Contexttype을 보냈다.
과거에는 이렇게 했는데 오류가 뜨는 것을 알 수 있다.
이미 출력이 진행된 것에 대해서 설정하는 것은 잘못된 것이다,
이렇게 설정하면 out.write로 쓰여지게 되기 때문에 @를 붙여서 페이지 시지자로 만들자.
이 page 지시자는 코드보다도 앞서서 설정이 진행된다.
내장객체와 거시서 만들어낸 변수에 대해서 간단히 알아보자.
JSP 외 코드가 있다.
JSP가 만들어낸 servlet에 내가 모르는 변수가 있을 수 있다.
보면 int page =1;로 선언했더니 중복된 지역 변수라는 말이 나온다.
강의만으로 부족해서 내용을 추가적으로 알아봤다.
내장객체란 JSP가 만들어낸 built-in 객체
-JSP가 서블릿 형태로 자동 변환된 클래스의 메서드 _jspService() 내에 지역적으로 선언되어 있음
내장객체 영역이란 각 객체가 저장되는 메모리의 유효기간
사용자 요청과 관련된 기능을 제공하는 내장 객체
주로 클라이언트에서 서버로 전달되는 정보를 처리하려고 사용
클라이언트 웹 브라우저를 최초로 열고난 후 닫을 때까지 요청되는 모든 페이지는 session객체를 공유
application 영역에 한번 저장된 정보는 페이지를 이동하거나, 웹 브라우저를 닫았다가 새롭게 접속해도 삭제되지 않는다.
<%@ 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>
<% for(int i=0;i<10;i++){%>
안녕!!<br>
<% }%>
</body>
</html>
jsp는 for문에서 한문장이라고 무조건 {}안에 넣어야 한다.
위 방법이 아닌 횟수를 입력받는 방법
<%
//response.setCharacterEncoding("UTF-8");
//response.setContentType("text/html; charset=UTF-8");
//paga지시자가 해줬기 때문에 지워주기
//PrintWriter out = response.getWriter();
//이미 out이라는 내장 객체가 존재하기 때문에 지워주기
String cnt_=request.getParameter("cnt");
int cnt=100;
if(cnt_ !=null && !cnt_.equals(""))
cnt=Integer.parseInt(cnt_);
%>
이 부분을 추가하고 내가 직접 ? cnt=3이라고 입력하기
오늘은 지난 시간에 이어서 초간단 JSP를 만들것이다.
복잡하게 만들었을 때의 코드를 우리는 스파게티 코드라고 한다,
이것의 문제점을 알아보고
45강에서는 스파게티 코드의 개선 방법에 대해서 배우자.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
int num=0;
String num_ = request.getParameter("n");
if(num_ != null && !num_.equals("") )
num=Integer.parseInt(num_);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%if(num%2 != 0) { %>
홀수입니다.
<% }
else { %>
짝수입니다.
<%} %>
</body>
</html>
코드 블록의 순서만 맞춰주면 되기 때문에 여러군데 퍼져있는 코드들
어떤 블록이 단일 업무인지
관심있는 코드와 관심없는 코드가 섞어져 있는 코드를 스파게티 코드라고 한다.
위 코드는 입력과 출력이 같이 모여 있다.
JSP를 잘못만들면 코드블록이 매우 복잡해질 수 있다.
좀 더 간편하게 만들수 없을까? MVC model1
코드에 대한 블록을 최소화
입력은 위
출력은 아래
입력코드와 출력코드를 따로 해서 양분화
추가적인 변수가 더 필요하긴 하다.
if문이 출력을 감싸고 있다.
출력은 jsp가 할 수 있도록 바꿔보자
변수가 하나 등장한다.
model이라는 변수이다,
출력을 제어하다가 데이터를 제어한다,
출력을 제어하면 코드 블럭이 여러개 생성되기 때문에
산출물은 model이라는 변수를 이용하자.
코드를 Model이라는 출력 데이터를 이용해서 V아 C를 만드는 방법을 MVC라고 한다.
Model이라는 특수한 변수를 이용하여 출력코드로부터 입력코드를 몰아낼 수 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
int num=0;
String num_ = request.getParameter("n");
if(num_ != null && !num_.equals("") )
num=Integer.parseInt(num_);
String result;
if(num%2 !=0)
result="홀수";
else
result="짝수";
%>
<!-- --------------------- -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=result %>입니다.
입니다.
</body>
</html>
이번 시간은 model2에 대해서 설명한다.
지난 수업의 예시를 model2로 바꾸기
model1은 흩어져있던 java 코드를 Controller에 싹 올려놓았다.
이는 Model이라는 녀석이 있어서 가능했다.
출력을 가능하게 하는 모델
하지만 이는 Controller와 View가 같은 곳에 있으므로 물리적으로 분리되지 않은 방식이다.
CM을 다른 서블릿으로 분리하는 방법을 생각해보자
CM은 사용자 요청이 있을 때 서블릿으로 만들어지는 것이 아니라 V만 사용자 요청이 있을 때 그 때 서브릿으로 만들어진다,
따라서 서블릿으로 만드는게 줄어든다.
CM은 미리 컴파일해서 배치해 놓을 수 있으므로 실행속도가 개선된다.
또한 따로 유지관리가 가능하다.
Controller와 View단에 해당하는 jsp가 있는데
이도 서블릿이다,
이 둘을 연결할 때 forwarding이라는 방법이 사용된다,
서블릿에서 서블릿으로 이전되면서 그 흐름을 이어받아서 코드를 진행할 때 사용되는 forwarding이 있는데 이는 Dispatcher를 통해서 한다,
근데 Controller단을 만들 때마다 공통적인 역할을 하는 Dispatcher도 같이 만들어야 하는데 이는 매우 비효율적이다.
따라서 Controller만 담도록 하는 작업을 한다.
실질적으로 서블릿은 하나만 만들고
일반적인 업무 로지은 별도의 POHO 클래스라고 해서 서블릿 클래스가 아닌 일반적인 클래스로 만든다.
사용자 요청이 들어오면 이 Dispatcher가 적절한 Controller를 찾아서 수행하게 하는 방식으로 한다.
Controller는 여기에 맞는 View를 호출할 수 있도록 Dispatcher는 url mapping에 관한 정보를 알려준다.
package com.newlecture.web;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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("/spag")
public class Spag extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
int num=0;
String num_ = request.getParameter("n");
if(num_ != null && !num_.equals("") )
num=Integer.parseInt(num_);
String result;
//모델이라는 녀셕을 만들어 놓음
if(num%2 !=0)
result="홀수";
else
result="짝수";
request.setAttribute("result", result);
//redirect : 새로운 요청
//forward : 이어가는
// 둘 사이에 이어가는 저장소가 필요->forward
//현재 Spag라고 하는 녀석이 있는데 저쪽 jsp로 전달
RequestDispatcher dispatcher
= request.getRequestDispatcher("spag.jsp");
dispatcher.forward(request,response);
//forward의 관계의 둘 사이의 공유하는 저장소는 request
//상태 유지값 : 페이지내 혼자 페이지 콘텍스트
// forward : request
//세션 : 사용자
//쿠키
//어플리케이션 객체
}
}
<%@ 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>
<%=request.getAttribute("result")%> 입니다.
</body>
</html>
Spag.java에서 ctrl+f11을 눌러 실행
오늘은 저희가 jsp를 MVC로 만들려고 할 때 아주 유용하게 쓸 수 있는 EL에 대해서 배우자
<%@ 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>
<%=request.getAttribute("result")%> 입니다.
</body>
</html>
앞에 배웠던 model2의 View단을 보면
<%=request.getAttribute("result")%> 어쩔 수 앖이 java가 사용 된다.
이를 개선하는 EL표기법 '${cnt}' 에 대해서 자세히 알아보자
<body>
<%=request.getAttribute("result")%> 입니다.
${result}
</body>
List를 상상해보자 얼마나 복잡할까?
Request의 getAttribute함수는 Object를 반환하기 때문에 형변환을 해줘야 하며 첫번째 인덱스 값을 꺼내기 위해서 get(0)을 선언해여 한다.
하지만 EL표기법은 매우 간단하며 이는 array,lit 모두 동일하다.
Map도 살펴보자
Map<String, Object> notice = new HashMap<String, Object>();
notice.put("id",1);
notice.put("title","EL은 좋아요");
request.setAttribute("notice", notice);
오늘은 그 EL이라는 것을 꺼내기 위해서 사용하는 저장소에 대해서 알아보자
예를 들어보자 Count라는 키워드가 Request라는 저장소에 담겨져 있다. 사실 request라는 저장소에서만 이 키워드를 검색하는 것은 아니다.
사실은 4개의 저장소를 사용한다.
앞서 배웠던 내장객체 영역이다.
데이터를 꺼내거나 저장한다.
지난 시간 request forwarding이라는 것을 통해서 두 개의 서블릿이 어떤 어떤 값을 공유할 때 사용한다.
곡 request가 아니더라도 page에 담을 수 있다.
만약에 cnt라는 키워드가 page, request, session, application 모두에 저장되어져 있다면 어떤 저장소에 있는 값을 꺼내게 될까?
오류가 나지 않는다 = 충돌이 되지 않는다 = 우선순위가 있다.
1위 : page
2위 : request
3위: session
4위 : application
따라서 특정 지을 때는 한정사를 사용한다.
${내장객체이름Scope.cnt}
예시를 통해 알아보자
<%=request.getAttribute("result")%> 입니다.
${result}<br>
${names[0]}<br>
${notice.title}<br>
${result}<br>
${param.n}<br>
${header.accept}
accept: 클라이언트가 서버에게 자기가 어떤 환경에 있는지 어떤 정보를 읽을 수 있는지를 알려준다.
번외로 pageContext에 대해서 알아보자
어떤 객체를 얻을 때 : pageContext.getRequest().getMethod()
EL에서 함수를 호출하는 방식이 아닌 속성처럼 사용한다
즉 ${pageContext.request.method}
이렇게 특이하게 사용
즉 get을 빼고 대문자를 소문자로, ()도 뺀다
java를 사용하는 느낌과 메소드를 사용하는 느낌 모두를 뺀다.
EL이라는 구문 안에서 연산자를 사용 가능
< lt(less than) > gt(greater than) 굳이 왜 2개?
이렇게 굳이 영어로 쓰는 이유는 Html 태그에 꺽임새와 비교 연산자 꺽음새의 기호가 같기 때문이다.
하지만 기본적인 html에서는 편한 것을 사용하고 이걸 사용할 수 없는 환경에서는 영어 사용하자