재밌고 어려운 IT를 이해해보자~!
JSP2 본문
복습...
.jsp 페이지 내부에서 모든 로직을 작성
-> 유지보수에 불리한 방법
로직을 JAVA Bean 클래스로 생성
.jsp 페이지 내부에서 Bean 클래스의 객체를 인스턴스화(new)하여 사용
->유지보수에 유리한 방법, 실습때 활용한 방법
기능을 수행하는 로직을 Servlet 클래스에 작성하고,
action 속성에 그 Servlet 경로를 작성하는 방식
+) 서블릿에 직접 로직이 작성 x
로직이 모듈화된 클래스를 서블릿에서 호출하여 사용 O
-> 실습땐 안쓰지만...not bad?
★ .jsp 파일이 컴파일되면 Servlet .java 가 된다!!!!!
서블릿은 클래스의 한 종류이며,
not POJO 이다!
알면 좋은것들~
각종 HTML input type
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>input 태그</title>
</head>
<body>
<form action="generic.html" method="GET">
<input type="checkbox" checked name="apple">
<input type="checkbox" name="apple">
<input type="checkbox" name="apple"> <br>
<input type="radio" checked name="banana">
<input type="radio" name="banana"> <br>
<input type="hidden" value="사용자의 화면에 보이지않는 input" />
사용자의 입력 : <input type="text" disabled readonly placeholder="글자를 입력하세요." /> <br>
<input type="date" /> <br>
<input type="email" required /> <br>
<input type="file" /> <br>
<input type="number" min="1" max="3" value="2" /> <br>
<input type="password" /> <br>
<input type="range" /> <br>
<input type="submit" value="보내기" /> <br>
</form>
</body>
</html>
HTML이 꺽쇠 < > 안에 들어 있는 것을 기본적으로 내용이 아닌 '태그'로 해석하기 때문이다.
그래서 &문자를 이용해서 특수 문장 부호를 html 문서가 인식하게끔 표현 해줘야 하는데 사용되는 것으로 보면 된다!
HTML 특수 문자 리스트모음!
https://inpa.tistory.com/entry/HTML-%F0%9F%93%9A-%EF%BC%86nbsp-%EF%BC%86amp-%EF%BC%86lt-%EF%BC%86gt-%EF%BC%86quot-%EC%9D%98%EB%AF%B8
.jsp 코드 공간 분리
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>스크립트릿 사용</title>
</head>
<body>
<%
// JAVA 코드 공간
for(int i=1;i<=5;i++){
out.println(i+" <br>");
}
%>
<hr>
<%
for(int i=1;i<=5;i++){ //자바공간
%>
<%=i%> <br> <!-- HTML공간 -->
<%
} //자바공간
%>
</body>
</html>
에러 발생시 예외처리
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="error/error.jsp" %> <!-- error.jsp로 연결 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>에러가 발생할 수 있는 코드를 작성</title>
</head>
<body>
<%
String str="apple";
int num=Integer.parseInt(str);
// 에러의 유무보다는,
// 에러가 발생했을때에 사용자의 서비스가 끊기지않도록 안내하는것이 중요!
%>
</body>
</html>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%> <!-- 사용자한텐 안보이지만 유지보수엔 좋다. 현재 페이지가 Error라는 뜻 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>현재 에러가 발생했습니다!</h1>
<h2>빠르게 수정하도록 하겠습니다~^^7</h2>
<a href="https://www.naver.com/"> 메인으로 이동하기</a>
</body>
</html>
내장 객체
[ JSP 내장 객체 ]
개발자가 객체를 별도로 생성하지 않아도 JSP에서 바로 사용할 수 있는 객체
컨테이너가 JSP를 서블릿으로 변환할 때 자동으로 객체가 생성됨
request, response, out, page, config, application, pageContext, exception, session
JSP 내장객체
.jsp 가 컴파일되면 Servlet 클래스 파일이 되는데,이때 제공되는 객체들을 "JSP 내장객체"라고 한다!
사용자에게 화면을 제공하는 용도로 사용하는 객체
: out, response
사용자가 입력한 값을 저장하는 용도로 사용하는 객체
: request, session, application
>> scope(유효범위)가 다름!
request
요청 단위
새로운 요청을 하면, 기존 request 정보가 사라짐
session ☆
브라우저 단위 / 시간 단위
창을 닫으면, 기존 session 정보가 사라짐
일정 시간이 흐르면, 기존 session 정보가 사라짐
세션은 한번 실행했던 브라우저 자체를 닫아야한다 탭을 닫는거로는 안된다~
application
서버 단위
서버를 꺼야(톰캣을 종료해야) application 정보가 사라짐
음.........아마 F11로 재실행하면 톰캣이 초기화 되는 것 같다!!!!!!!!!!!!!!!!!!!!!
[ session ]
.getAttribute("값 이름") 으로 값을 받아올수있음
없는 값이면 null 반환
[ application ]
Object 단위로 데이터를 저장할 수 있음
캐스팅(형변환) 이슈를 잘 확인해야함!
내장객체의 영역이란?
각 객체가 저장되는 메모리의 유효기간으로 4가지의 영역으로 구성된다.
영역 크기 순으로 application > session > request > page 순이다.
각 영역의 접근범위는 다르지만, 제공하는 메소드는 모두 동일하며 "영역명.메소드명()"과 같은 형태로 사용할 수 있다.
내장 객체는 말 그대로 JSP가 기본적으로 내장하고 있어서 따로 선언하거나 만들어줄 필요 없이 바로 사용 가능한 객체이다.
당연한 말이지만 모두 Java의 클래스 객체이므로 서블릿에서도 동일하게 사용이 가능하다.
서블릿에서는 자동으로 생성되는 내장 객체는 아니지만 대부분 get 메소드를 이용해 객체를 얻어낼 수 있다.
▶ 내장객체 기본 메소드
void setAttribute(String name, Object value)
: 각 영역에 속
첫번째 인수는 속성명, 두번째 인수는 정할 값
값의 타입은 Object이므로 모든 타입의 객체 저장 가능
object getAttribute(String name)
: 영역에 저당된 속성값을 얻어옴
object로 자동 형변환되어 저장되므로 원래 타입으로 형변환 사용
void removeAttribute(String name)
: 영역에 저장돈 속성을 삭제
삭제할 속성명이 존재하지 않더라도 에러는 발생하지 않음
1. 사용자 요청별로 생성됐다 처리되면 사라지는 객체
request (javax.servlet.http.HttpServletRequest)
response (javax.servlet.http.HttpServletResponse)
out (javax.servlet.jsp.jspWriter)
브라우저에서 서버로 요청을 하고 서버에서 브라우저로 회신해주고 나면 이 객체들은 모두 사라집니다. Request, Response 객체는 하나의 요청을 처리하는 스레드에서 모든 JSP와 서블릿이 공유합니다. out은 서블릿에 공유되지 않기 때문에 서블릿에서 바로 클라이언트로 출력해주기 위해서는 PrintWriter의 출력 스트림을 따로 생성해줘야 합니다.
* 서블릿에서 출력 스트림 생성 방법
PrintWriter out = response.getWriter();
out.println("~~");
2. 사용자(브라우저) 별로 유지되는 객체
Session
[ session - javax.servlet.http.HttpSession 객체 ]
session은 브라우저가 완전히 꺼질 때까지 해당 브라우저의 고유 식별자(id)를 서버에 저장해두고 같은 브라우저에서 요청이 왔는지 알아볼 수 있게 해주는 객체이다.브라우저 하나당 한 개의 session 객체를 가진다.
새로운 브라우저 식별자가 들어오면 새로운 session 객체를 생성해놨다가 같은 식별자를 가진 브라우저가 다시 요청하면 해당 session 객체를 다시 전달해준다.
소멸 시점은 isInvalid() 메소드로 무효화 해주거나 지정한 유효 시간이 지나 자동으로 무효화 될 때
Session 심화~
session 객체는 클라이언트와 서버와의 관계를 유지해주는 수단이다.
그냥 세션(Session)이라는 용어는 '연결된 상태'라는 의미이며 채팅 프로그램을 만들 때처럼 일반적으로 자바를 이용해 클라이언트-서버 간 프로그램을 작성할 때는 소켓을 이용해 통신을 연결한다.
이 경우 서버의 서버소켓과 클라이언트의 소켓이 연결된 상태를 세션이 맺어졌다고 표현!
그리고 클라이언트 또는 서버에서 해당 연결을 끊지 않는 한 세션이 계속 맺어진 상태로 있으며 세션이 끊길 경우 통신이 종료되고 다시 연결하기 위해서는 프로그램을 재구동 해서 다시 세션을 맺어줘야 한다.
하지만 HTTP 프로토콜은 계속 세션을 맺은 상태로 클라이언트와 서버가 연결돼 있는 것이 아니라 클라이언트가 서버에 요청을 할 때 세션이 맺어지고 서버에서 클라이언트로 응답을 보낸 이후 세션이 끊긴다!
서버 입장에서는 요청에 따른 응답을 하고 나면 클라이언트와의 연결이 끊어지므로 더 이상 클라이언트에 대해 신경쓰지 않게 된다.
하지만 이렇게 세션이 매번 끊어져버린다면, 예를 들어 웹 사이트에서 클라이언트가 로그인을 요청하고 서버가 해당 계정을 확인한 뒤 로그인이 완료된 다음 페이지를 보여주더라도 계속해서 클라이언트가 로그인된 상태를 유지하기 어렵게 되기 때문에, 세션이 끊어지더라도 지속적으로 서버측에서 클라이언트에 대한 접속 정보를 가지고 있음으로써 로그인을 유지할 수 있게 해주는 객체가 바로 JSP의 내장객체이자 자바의 HttpSession 객체인 session 이다.
로그인 뿐만 아니라 지속적인 관계를 유지해야하는 서비스에서 session 객체를 활용할 수 있습니다.
* 쿠키(Cookie)와 세션(Session)의 차이점
쿠키는 서버가 보내준 특정한 정보를 클라이언트(브라우저) 측에서 가지고 있는 방식
로그인의 예를 들면 로그인을 통과했을 경우에만 특정 정보값과 계정정보를 클라이언트측에 저장하게 하고 로그인 된 이후의 페이지에 대한 요청이 올 때는 클라이언트의 쿠키 정보에 로그인을 통과한 정보가 있는지를 판단하고 계정정보를 가져와 해당 계정에 관한 정보를 출력해주는 방식으로 사용 가능하다.
하지만 클라이언트측에서 인증 정보를 가지고 있는 경우는 보안이 취약하다는 단점이 있으며, 해당 정보를 조작해서 서버의 인증을 우회하는 방식 등이 사용됨
하지만 세션의 경우는 서버에서 클라이언트에 대한 정보를 가지고 있다는 점에서 쿠키와 다르다.
서버에서 정보를 관리함으로써 쿠키에 비해 보안을 향상시킨 방법
따라서 로그인 인증과 같은 민감한 정보에 대해서는 쿠키보다 세션 방식을 사용하는 것이 좋다.
또한 쿠키는 저장할 수 있는 데이터의 한계가 있는 반면 세션은 서버에 저장되는 정보이기 때문에 저장할 수 있는 데이터의 한계가 없다는 장점도 있다.
세션 객체는 컨테이너에서 자동으로 생성해준다. 세션의 단위는 브라우저이다.
같은 PC에서도 다른 브라우저로 접속하면 다른 사용자로 인식한다. 크롬에서 로그인하고 익스플로러도 다시 켜보면 로그인이 안돼있는 것이 이 때문!
또 브라우저가 완전히 다 닫히고 다시 열리게 되도 식별자가 달라서 다른 세션으로 인식한다. 하지만 브라우저가 완전히 닫히지 않은 상태에서 창을 하나 더 열 때는 같은 브라우저로 인식합니다 .예를 들어 크롬창을 두 개 열어서 한쪽에서 로그인을 하고 다시 껐다 키더라도 다른 하나의 창을 끄지 않았기 때문에 같은 브라우저로 인식해 session 객체를 새로 생성하지 않는다.
같은 브라우저를 여러 개 키고 하나의 브라우저로 로그인을 했을 때 다른 브라우저에서도 로그인이 돼 있는 것은 이 때문입니다.
세션 정보는 계속 유지해줄 수도 있지만 대부분 권고되는 보안 규정에 따라 30~60분 사이로 세션이 유지되는 최대 시간을 조절해 주는 경우가 많다. 디폴트는 대부분 30분으로 web.xml에 <session-timeout> 태그에 기술되어 있다. 이 부분에서 시간을 조정해주거나 메소드를 통해 재조정해줄 가능
<session-config>
<session-timeout>30</session-timeout>
</session-config>
컨테이너는 브라우저에서 요청이 들어오면 session 객체를 생성해준다고 했다.
이 때 브라우저의 고유 식별자(ID)를 받아서 같은 식별자를 가진 session 객체가 있으면 해당 객체를 가져다 쓰고, 없으면 새로 만들어준다. 그리고 session 객체를 계속 보관하고 있다가 유효시간이 지나면 무효화를 시키고 무효화가 되기 전이라면 기존 session 객체가 남아있으므로 이미 인증이 된 클라이언트가 맞는지 구분할 수 있게 된다.
새로 생성된 객체는 isNew() 메소드에서 'true'를 반환하지만, 만약 한번이라도 다른 JSP 페이지나 서블릿을 거쳐서 왔다면 이미 세션이 생성된 상태가 되어 'false'를 반환하게 되므로 사용 시 주의해야합니다.
내장 객체 : Session
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 내장객체 : session</title>
</head>
<body>
<%
if(session.isNew()){
out.println("<script>alert('세션을 새로 만듦!');</script>");
session.setAttribute("userName", "작은 티모");
// 기본 제공 시간 30분 (맞음!)
}
%>
<h1><%= session.getAttribute("userName") %>님, 안녕하세요! :D</h1>
</body>
</html>
3. JSP/서블릿마다 하나씩 생성되는 객체
config (javax.servlet.ServletConfig)
ServletConfig 객체는 web.xml 파일에서 특정 JSP/서블릿에 초기화 파라미터를 매핑시켜둔 값을 가지고 있는 객체이다. JSP/서블릿이 메모리에 로드되는 시점에 실제 생성되는 객체인데, 동일 JSP/서블릿은 딱 하나의 ServletConfig 객체를 가진다. 따라서 따로 다른 클래스나 JSP에 객체 또는 값을 전달하지 않는 한 해당 객체는 지정된 JSP/서블릿에서만 사용할 수 있는 딱 하나의 객체이다. 같은 요청을 처리하는 동일 스레드에서도 다른 클래스나 JSP끼리 자동으로 공유되고 그러지 않는다!
각자 하나씩 가지고 있습니다.
JSP나 서블릿이 수정돼서 다시 컴파일을 거친 후 메모리에 로드되면 이 객체도 다시 생성되는데, 어차피 web.xml 파일의 값은 컨테이너를 재가동 시켜야 다시 가져올 수 있으므로 초기화 파라미터 값은 변하지 않아 별 의미는 없다. 그냥 생명주기도 컨테이너의 생명주기와 같다고 생각하면 된다.
* 서블릿에서 ServletConfig 객체 얻는 방법 (상속받은 HttpServlet에 있는 메소드)
4. 컨테이너 구동 시 생성되는 객체
application (javax.servlet.ServletContext)
▶ application 영역 (가장 큰 영역)
: 한 번 저장되면 웹 애플리케이션이 종료될 때까지 유지된다. → application 객체를 사용
- 웹 애플리케이션은 단 하나의 application 객체를 생성하며 클라이언트가 요청하는 모든 페이지에서 application 객체를 공유한다.
- application 객체는 웹 서버를 시작할 때 만들어지며, 웹 서버를 종료할 때 삭제 됨
- 따라서 application 영역에 한 번 저장된 정보는 페이지를 이동하거나, 웹 브라우저를 닫았다가 새롭게 접속해도 삭제되지 않는다.
application 영역에 속성 저장 : application.setAttribute(속성명, 값);
application 영역에 속성 읽기 : application.getAttribute(속성명);
ServletContext 객체는 어플리케이션(프로젝트 단위)이 딱 하나만 가지고 있는 객체입니다. 컨테이너에서 프로젝트를 구동시킬 때 프로젝트 단위로 딱 하나씩 만들어서 줍니다. 따라서 이 객체는 프로젝트 단위 내의 모든 JSP와 서블릿에서 공유되는 객체입니다.
기본적으로는 컨테이너의 내외부 환경에 대한 정보를 가지고 있는데 Attribute 객체를 임의로 추가할 수 있어서 정보 공유의 수단으로 많이 사용됩니다.
* 서블릿에서 ServletContext 객체 얻는 방법 (ServletConfig 객체의 메소드로 얻을 수 있음)
ServletConfig conf = this.getServletConfig();
ServletContext application = conf.getServletContext();
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 내장객체 : application</title>
</head>
<body>
<%
application.setAttribute("count", 0);
%>
<a href="test08.jsp">방문자 수 확인하기</a>
</body>
</html>
test08.jsp로 연결~
test08.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>
<%
Integer count=(Integer)application.getAttribute("count");
count++;
application.setAttribute("count",count);
%>
<h1>방문자 수 : <%=application.getAttribute("count")%>명</h1>
</body>
</html>
쇼핑몰 만들기 예제!
test09.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쇼핑몰 예제</title>
</head>
<body>
<h1>로그인 페이지</h1>
<form method="POST" action="test10.jsp">
ID <input type="text" name="mid" placeholder="ID를 입력하세요." required> <br><br>
<input type="submit" value="로그인">
</form>
</body>
</html>
타이틀 : 쇼핑몰 예제 -> 웹에는 출력안됨!
<h1> 제목태그 사용 "로그인 페이지" 생성 자동 줄바꿈 되는듯?
input type "text" 를 통해서 유저에게 "mid"이름을 가지고 있는 택스트 입력받기
placeholder, required을 통해서 입력받는 란에 공백이면 "ID를 입력하세요." 출력
<br>태그를 이용해 줄바꿈
input type ="submit" 으로 "로그인" 텍스트가 있는 버튼생성되고 유저에게 받은 mid를
POST 방법으로 test10.jsp에게 전달!
test10.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>
<%
String mid=request.getParameter("mid");
session.setAttribute("mid", mid);
%>
<h1>상품목록</h1>
<hr>
<%=session.getAttribute("mid")%>님, 안녕하세요! :D
<hr>
<form action="test12.jsp" method="POST">
<select name="product">
<option>탕후루</option>
<option>붕어빵</option>
<option>마라탕</option>
<option>민트초코</option>
<option>파인애플피자</option>
</select>
<input type="submit" value="장바구니에 추가">
</form>
<hr>
<a href="test11.jsp">최종 결제하기</a>
</body>
</html>
getParameter를 통해 :name이 "mid인 파라미터를 요청해서 자바 변수 mid 에 대입.
세션에 받았던 변수 mid를 "mid"로 저장.
HTML에
<%= %> 표현식을 사용해 세션에 저장했던 "mid"를 문자열상태로 출력하고 그뒤에 님, 안녕하세요! :D 출력
티모박제!
"product"라는 토글메뉴를 select를 통해 만들고 그 옵션에는
탕후루, 붕어빵, 마라탕, 민트초코, 파인애플피자가 들어있다.
input type "submit" 의 "장바구니에 추가" 버튼을 만들고 그버튼을 누르면 POST방식으로 test12.jsp에 전달!
최종 결제하기 링크를 만들고 그걸 누르면 test11.jsp로 이동!
test12.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.ArrayList" %>
<% request.setCharacterEncoding("UTF-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>장바구니에 상품을 추가</title>
</head>
<body>
<%
ArrayList<String> cart=(ArrayList<String>)session.getAttribute("cart");
if(cart == null){ // 첫구매라서 장바구니가 없었다면
cart=new ArrayList<String>();
session.setAttribute("cart",cart);
}
String product=request.getParameter("product");
cart.add(product);
%>
<script>
alert('<%=product%>이(가) 추가되었습니다! :D');
history.go(-1);
</script>
</body>
</html>
세션에 값 저장하기
setAttribute(String name, Object value)
setAttribute는 name, value 쌍으로 객체 Object를 저장하는 메서드다.
세션이 유지되는 동안 저장된다.
session.setAttribute(이름, 값)
이렇게 사용할 수 있다.
타이틀 : 장바구나에 상품을 추가 -> 웹에는 출력안됨!
문자열을 담은 배열리스트에 세션의 "cart"이름을 가지고있는 Attribute를 저장. 그 이후.
문자열 배열리스트로 캐스팅 (defualt는 Object를 담는 듯 하다)
첫 구매라서 장바구니에 담긴게 없다면 장바구니는 생성되있지 않은상태 (null)
(장바구니는 상시 생성해놓지 않는방법)
cart라는 문자열 배열리스트 생성.
세션에 "cart"라는 이름으로 cart값 저장.
자바 변수 product에 유저에게 받은 "product"이름을 가진 파라미터를 대입.
cart 배열리스트에 자바변수 product add
자바스크립트언어로
alert를 띄워주는데 이때 <%= %> 표현식을 통해 product이름을 문자열형태로 출력하고 그뒤에 이(가) 추가되었습니다! :D 출력
그이후 전화면으로 돌아가기 -> history.go(-1)
test12.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.ArrayList" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>결제 페이지</h1>
<%
ArrayList<String> cart=(ArrayList<String>)session.getAttribute("cart");
if(cart == null){
out.println("결제할 상품이 없습니다!");
// 상품 구매 페이지로 이동
}
else{
for(String data:cart){
out.println(data+"<br>");
}
}
%>
</body>
</html>
결제 페이지 제목 생성
"cart"이름을 가지고 있는 세션 생성후 문자열 배열리스트로 캐스팅하여
문자열 배열리스트 카트에 저장. -> 이건 상품 장바구니에 넣을때도 했던애인데 페이지 바뀌면서 넘어갈때마다 일단
받아줄 장소는 만들어놔야 하나보다.
카트가 비어있으면
"결제할 상품이 없습니다" 출력
아니면
카트 배열리스트 전부출력
println이어도 줄바꿈은 안되나보다 따라서 data 뒤에 줄바꿈 추가!
*참조
'코리아IT핀테크과정' 카테고리의 다른 글
JSP 3 (0) | 2024.01.08 |
---|---|
JSP practice (0) | 2024.01.06 |
JSP (2) | 2024.01.04 |
JavaScript (3) | 2024.01.04 |
WebApp, HTML 1 (0) | 2023.12.27 |