23-03-07(1) Servlet, JSP
※복습
1. Servlet
java코드 base
controller는 servlet으로 구현
2. JSP
html문서 (화면담당)
소스코드가 혼잡스러움
3. DTO
하위에는 VO가 있음 (VO의 예시) 회원, 게시판, 댓글))
멤버의 값이 변화
EX) 페이지 객체
3-1) VO
- 지정된 값 불변
- 변화될 값이 많을경우 VO로 처리
EX) 회원, 게시글
4. DAO
- db접근
* OSI 7 layer
- 네트워크에서 사용되는 언어
- 네트워크 프로토콜이 통신하는 구조
- 7개의 단계가 있음 (계층도)
1계층 : 물리계층 (최하위 계층) : 랜카드
2계층 : 데이터링크 계층
3계층 : 네트워크 계층
4계층 : 전송 계층 : TCP, UDP
5계층 : 세션 계층 : TLS, SSL(채팅관련)
6계층 : 표현 계층
7계층 : 응용계층 (최상위 계층) : HTTP, SMTP
5. WS, WAS
5-1) WS (Web Server)
- http 처리 (apache, nginx)
5-2) WAS (Web Application Server)
- JAVA기반의 web application server
5-3) WAS와 WS를 같이 쓰는 이유
- 정적인처리, 동적인처리를 분리하여 효율적으로 서버를 운영하려고 하기 때문
- 동적 data 처리 : JSP, Servlet
- 정적 data 처리 : CSS, HTTP
- 하나의 웹서버에서 두개의 다른 언어의 어플리케이션을 사용하는 경우
- 로드밸런싱(분산처리)이 필요한 경우
- 보안을 강화하는 경우
6. tomcat(무료) 구조
7. web.xml
8.
* 서버가 구동할때 계속해서 다른서버를 구동시키는경우 서버 강제종료하는 방법
1. 관리자 권한으로 cmd 실행
2, netstat -ao 입력
3. 적절한 때 Ctrl + C로 실행중지
4. 해당 포트에 대한 PID를 확인
5. taskkill -f -pid pid번호
※ 참고
*
로직 : Service
모델 / Component : DAO, DTO, VO
model 1 : only JSP
model 2 : MVC pattern
* 알아두면 좋을것
웹투비, TmaxOs
※ JSP
- dynamic web project 생성
- web.xml 안맹글어도 됨
- web app폴더에서 작업
1. jsp 생성시 템플릿 설정
우측하단 JSP Templates 클릭
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>2023. 3. 7.오전 10:45:07</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
</body>
</html>
입력
1. JSP
1-1) directive
- 지시자(선언문), 최상단에 쓰임(1번행)
1-1-1) page
- import 가능
1-1-2) include
- 공통구문, 어디에 써도 상관없지만 상단에 자주 쓰임
1-1-3) taglib
- 추가적인 tag 라이브러리 (JSTL)
1-2) scriptlet
- 자바코드영역
1-2-1) <% %>
- 지역구간
1-2-2) <%! %>
- 전역구간
1-3) expression
- 표현식
- 수정했을시 x가 뜰 경우 복사하고 지웠다가 다시 붙여넣으면 됨
- <%= %> 단독적으로 아무것도 안쓰고 사용할 수 없음 print랑 같기 때문에.
예제) jsp파일에 자바코드 추가, mariadb회원목록을 가져와 웹에서 회원조회
1. lib폴더에 lombok, mariadb 추가
2. index.jsp파일 생성
오류)
1. 라이브러리를 닫았을때(lib에 mariadb를 가져오지 않을시) 500오류
- conn 객체가 에러
* NullPointException
- null객체에 멤버를 엑세스 할때 발생
- 변수를 엑세스하거나 메서드를 호출하거나
- conn.createStatement() : conn이 null인지 체크
- stmt.executeQuery(sql) : stmt가 null인지 체크
- 이제 이클립스 콘솔 확인
-
- Class.forName일때 못찾은것
- 그래서 conn에서 실행을 못한것이고 트라이캐치에서 문제가 발생한 것이다
- 해결방법은
- 두친구를 lib폴더에 넣으면 된다.
2.
* 저장시 자동 빌드
*오류가 생겼을시(빨간x박스) 닫아놓을수 있는 방법
프로젝트(폴더) 우클릭 후 Close Project를 누르면 된다.
반대방법은 우클릭후
Open Project를 누르면 된다.
2. 내장객체
2-1) request
- 요청
-
<%@page import="java.util.Enumeration"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>2023. 3. 7.오후 12:10:28</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<%
// ip ban
if(request.getRemoteAddr().equals("192.168.0.240")) {
out.println("<h1>당신의 ip는 ban되었습니다</h1>");
return;
}
%>
<h1>request</h1>
<%
// 중요메서드
String cp = request.getContextPath();
Cookie[] cookies = request.getCookies();
Enumeration<String> headerNames = request.getHeaderNames();
request.getMethod(); //Method
request.getRemoteAddr();
request.getRemoteHost();
HttpSession session2 = request.getSession(); // 세션객체 내장객체에 세션이 있어서 이름이 겹침
request.setAttribute("abcd", "1234");
request.getAttribute("abcd"); // js의 dom에도 있음
// request.removeAttribute("abcd"); // 어트리뷰트 제거
%>
<p>request.getContextPath() <%=cp%></p>
<p>request.getMethod() : <%=request.getMethod()%></p>
<p>request.getRemoteAddr() : <%=request.getRemoteAddr()%></p>
<p>request.getRemoteHost() : <%=request.getRemoteHost()%></p>
<p>request.getAttribute("abcd") : <%=request.getAttribute("abcd")%></p>
<%
System.out.println(request.getRemoteAddr());
System.out.println(request.getRemoteHost());
// 사용자 정보 가져오기
while(headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
out.print("<h2>" + name + "::" + request.getHeader(name));
}
%>
</body>
</html>
2-2) response
- 응답
*
1. HTTP의 특징
- 무상태(상태 없음) : 해결하기 위한 방법 => cookie, session
* cookie, session
1. 공통점
- 웹 통신간 유지하려는 정보를 저장하기 위해 사용하는 것
2. 쿠키
- 응답에 쿠키를 만들어서 보냄 (response에 addCookie가 있는 이유임 / request에 getCookie가 있는 이유)
- 개인pc에 저장 (클라이언트 pc)
3. 세션
- 접속중인 웹서버에 저장됨
↓ 참고
https://hahahoho5915.tistory.com/32
- 비연결
- html을 전송하기 위한 목적
- 응답 완료시 연결이 끊김
↓ 참고
TCP 특징
- 연결
- byte, 정보 전송 목적 (파일전송 등등)
- 전화라고 생각하면 편함(채팅),
- 수신자와 송신자의 지속적인 연결이 되어있음
UDP 특징
- 비연결
- 정보 전송의 목적
- 택배로 생각하면 편함(혹은 스트리밍, 방송, 게임)
2-3) page
* cookie
- 4kb(너무 작음)
- file 형태라서 노출이 쉬움
- html5는 쿠키를 잘 쓰지 않고 로컬스토리지를 사용함
쿠키를 사용하여 하루동안 팝업창을 열지않는 예제 만들기)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>2023. 3. 7.오후 1:13:38</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style type="text/css">
.container {height: 800px; background: orange;}
.popup {width: 420px; position: absolute; top:300px; right:200px; display: none;}
.popup label {display: block; background: navy; color: white; margin-top: -4px; padding: 8px;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js" integrity="sha512-3j3VU6WC5rPQB4Ld1jnLV7Kd5xr+cq9avvhwqzbH/taCRNURoeEpoPBK9pDyeukwSxwRPJ8fDgvYXd6SkaZ2TA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
$(function() {
$(".popup :checkbox").change(function() {
$(".popup").hide();
//alert($.cookie("myCookie"));
//alert($.cookie("myCookie2"));
$.cookie("popup", "daily", {expires:1});
});
if(!$.cookie("popup")){
$(".popup").show();
}
// session cookie
/// session의 lifecycle 브라우저가 닫히면 쿠키가 삭제
})
</script>
</head>
<body>
<div class="container">
<h1>본문</h1>
</div>
<div class="popup">
<img alt="" src="https://image.yes24.com/momo/scmfiles/AdvertFiles/202303/2577446_230302083629.jpg" ><label>
<input type="checkbox">하루동안 이 창 보지 않기 </label>
</div>
<%
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
out.println("<p>" + cookie.getName() + "::" + cookie.getValue() + "::" + cookie.getMaxAge());
}
Cookie cookie = new Cookie("jsp", "cookie");
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
%>
</body>
</html>
JSESSIONID :
*localstorage
1. 로컬스토리지
- 영구적인 형태의 공간
2. 세션스토리지
- 세션이 끝날때 저장된 데이터가 지워짐
로컬스토리지 위 쿠키예제처럼 만들기)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>2023. 3. 7.오후 1:13:38</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style type="text/css">
.container {height: 800px; background: orange;}
.popup {width: 420px; position: absolute; top:300px; right:200px; display: none;}
.popup label {display: block; background: navy; color: white; margin-top: -4px; padding: 8px;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js" integrity="sha512-3j3VU6WC5rPQB4Ld1jnLV7Kd5xr+cq9avvhwqzbH/taCRNURoeEpoPBK9pDyeukwSxwRPJ8fDgvYXd6SkaZ2TA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
$(function() {
$(".popup :checkbox").change(function() {
$(".popup").hide();
//$.cookie("popup", "daily", {expires:1});
localStorage.setItem("sto_popup", "daily");
});
if(!localStorage.getItem("sto_popup")){
$(".popup").show();
}
// session cookie
/// session의 lifecycle 브라우저가 닫히면 쿠키가 삭제
})
</script>
</head>
<body>
<div class="container">
<h1>본문</h1>
</div>
<div class="popup">
<img alt="" src="https://image.yes24.com/momo/scmfiles/AdvertFiles/202303/2577446_230302083629.jpg" ><label>
<input type="checkbox">하루동안 이 창 보지 않기 </label>
</div>
<%
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
out.println("<p>" + cookie.getName() + "::" + cookie.getValue() + "::" + cookie.getMaxAge());
}
Cookie cookie = new Cookie("jsp", "cookie");
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
%>
</body>
</html>
2-4) session
- 웹 컨테이너에서 클라이언트의 정보를 서버에 보관하는 기능
- jsp사용시 세션이 그냥 생김(기본값 / 난수로 생기지만 중복값은 없음)
- 세션 유지시간은 30분이다.
- 세션이 생성되는 순간부터 세션이 만료되는 순간까지 존재
- setMaxInactiveInterval 사용시 세션유지시간 변경 가능
2-4-1)
*03-06 login 예제에서 logout 추가하기
1. login.jsp 수정
2. controller 패키지에 Logout클래스 추가
3. logout 클래스에서 추가된 내용 login.jsp 수정하기
<%@page import="vo.MemberVo"%>
<%@ 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>
<h3>login 구현</h3>
<%=session.getAttribute("member")%>
<%
if(session.getAttribute("member") == null) {
%>
<form method="post">
<input type="text" name="id" placeholder="id입력">
<input type="password" name="pw" placeholder="pw입력">
<button>로그인</button>
</form>
<!-- <p>${member}</p> -->
<%
}
else {
MemberVo vo = (MemberVo) session.getAttribute("member");
%>
<h3>어서오세요 <%=vo.getName()%>님</h3>
<form action="logout"">
<button>logout</button>
</form>
<%
}
%>
</body>
</html>
package controller;
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;
@WebServlet("/logout")
public class Logout extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().invalidate();
resp.sendRedirect("login");
}
}