개요
GenericServlet을 확장한 HttpServlet 클래스 이용하여 서블릿 생성
클라이언트 요청을 GET, POST등으로 구분하여 처리
리다이렉트, 리프래시를 다루는 방법 학습
초기화 매개변수를 이용 설정 정보를 외부 파일에 두는 방법 및 서블릿에서 참고하는 방법
JDBC를 이용하여 데이터베이스회원 정보를 등록, 조회, 변경, 삭제
데이터베이스에서 데이터 가져오기
데이터베이스를 사용하기 위한 요소
1) JDBC 드라이버 : 데이터베이스를 요청, 전달, 결과를 받을 때 사용할 도구 자바에서 제공하는 DB와 통신하는 기술 자바에 데이터 베이스 접근하기 위해 필요
2) SQL : 데이터베이스에 명령을 내릴 언어
1. 회원 목록 조회 구현
샘플 데이터 생성
-- 샘플 테이블 생성 create table MEMBERS ( MNO integer not null comment '일련번호', EMAIL VARCHAR(40) not null comment '이메일', PWD VARCHAR(100) not null comment '암호', MNAME VARCHAR(50) not null comment '이름', CRE_DATE DATETIME not null comment '가입일', MOD_DATE DATETIME not null comment '마지막암호변경일' ) COMMENT '회원기본정보'; -- 제약조건, 인덱스 등 설정 ALTER TABLE MEMBERS ADD CONSTRAINT PK_MEMBERS PRIMARY KEY ( MNO ); CREATE UNIQUE INDEX UIX_MEMBERS ON MEMBERS (EMAIL ASC ); ALTER TABLE MEMBERS MODIFY COLUMN MNO INTEGER NOT NULL AUTO_INCREMENT COMMENT '회원일련번호'; -- 샘플데이터 입력 INSERT INTO MEMBERS(EMAIL, PWD, MNAME, CRE_DATE, MOD_DATE) VALUES ('s2@test.com','1111','임꺽정',NOW(),NOW()); INSERT INTO MEMBERS(EMAIL, PWD, MNAME, CRE_DATE, MOD_DATE) VALUES ('s3@test.com','1111','일지매',NOW(),NOW()); INSERT INTO MEMBERS(EMAIL, PWD, MNAME, CRE_DATE, MOD_DATE) VALUES ('s4@test.com','1111','이몽룡',NOW(),NOW()); INSERT INTO MEMBERS(EMAIL, PWD, MNAME, CRE_DATE, MOD_DATE) VALUES ('s5@test.com','1111','성춘향',NOW(),NOW());
SQL
JDBC 드라이버 준비
Type1 JDBC 드라이버 : 자바 실행환경 (Java Runtime Environment) 에 기본 포함 ODBC 드라이버를 사용
Type4 JDBC 드라이버 : MySQL 통신 프로토콜에 맞추어 데이터베이스와 직접 통신 ⇒ ODBC 드라이버를 필요로 하지 않음
서블릿 만들기
@WebServlet("/member/list") public class MemberListServlet extends GenericServlet { @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { DriverManager.registerDriver(new com.mysql.jdbc.Driver()); conn = DriverManager.getConnection("jdbc:mysql://ec2-52-79-233-2.ap-northeast-2.compute.amazonaws.com/workbook?serverTimezone=Asia/Seoul", "workbook", "password"); stmt = conn.createStatement(); rs = stmt.executeQuery("select * from MEMBERS"); response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html><head><title>회원목록</title></head>"); out.println("<body><h1>회원목록</h1>"); while (rs.next()) { out.println( rs.getInt("MNO") + "," + rs.getString("MNAME") + "," + rs.getString("EMAIL") + "," + rs.getDate("CRE_DATE") + "<br>"); } out.println("</body></html>"); } catch(Exception e){ throw new ServletException(e); }finally { try {if (rs != null) rs.close();} catch(Exception e) {} try {if (stmt != null) stmt.close();} catch(Exception e) {} try {if (conn != null) conn.close();} catch(Exception e) {} } } }
Java
1) JDBC 관련 객체 선언
Connection conn = null; Statement stmt = null; ResultSet rs = null;
Java
2) JDBC API 예외 발생 대비
try { } catch(Exception e){ throw new ServletException(e); }finally { }
Java
서블릿에서 발생한 예외는 서블릿 컨테이너에 던짐
3) DriverManager가 사용할 JDBC 드라이버 등록
DriverManager.registerDriver( new com.mysql.jdbc.Driver()) // new com.mysql.jdbc.Driver() == java.sql.Driver 인터페이스 구현체
Java
java.sql.Driver 인터페이스 구현체
DriverManager에 등록됨
getMajorVersion(), getMinorVersion() : JDBC 드라이버 버전 제공
acceptsURL() : JDBC URL이 드라이버에서 사용가능한지 알려줌
connect() : 데이터베이스와 연결 수행 > Connect 객체 반환
4) DriverManager가 사용할 JDBC 드라이버 등록
DriverManager.registerDriver( new com.mysql.jdbc.Driver()) // new com.mysql.jdbc.Driver() == java.sql.Driver 인터페이스 구현체
Java
5) 데이터베이스에 연결
conn = DriverManager.getConnection("jdbc:mysql://ec2-52-79-233-2.ap-northeast-2.compute.amazonaws.com/workbook?serverTimezone=Asia/Seoul", "workbook", "password");
Java
DriverManager.getConnection(JDBC URL, DBMS 사용자 ID, DBMS 사용자 PW);
** JDBC URL의 구조
jdbc:mysql:thin:@localhost:3306:studydb // jdbc:mysql = 사용할 JDBC 드라이버 // thin = 드라이버 타입 // @localhost:3306 = 서버주소, 포트번호 // studydb = db 서비스 id
Java
⇒ java.sql.Connection 인터페이스 구현체 반환 : SQL을 실행할 객체를 얻을 수 있음
주요메서드
1) SQL문 실행 객체 반환 : createStatement(), prepareStatement(), prepareCall()
2) 트랜잭션 처리 수행 : commit(), rollback()
6) SQL 실행 객체 준비
stmt = conn.createStatement();
Java
⇒ java.sql.Statement 인터페이스 구현체 반환 : 데이터베이스에 질의하는 객체
주요 메서드
1) executeQuery() : 결과가 만들어지는 SQL문 실행 시 사용 (주로 SELECT 문에서 실행)
2) executeUpdate() : DML, DDL 실행시 사용
3) execute() : SELECT, DML, DDL 모두사용가능
4) executeBatch() : addBate()로 여러개의 SQL 등록, 한번에 실행
7) 데이터베이스에 SQL문 보내기
rs = stmt.executeQuery("select * from MEMBERS");
Java
⇒ java.sql.ResultSet 인터페이스 구현체 반환
주요 메서드
1) first() : 서버에서 첫번째 레코드 가져오기
2) last() : 서버에서 마지막 레코드 가져오기
3) previous() : 서버에서 이전 레코드 가져오기
4) next() : 서버에서 다음 레코드 가져오기
5) getXXX(컬럼명) : 특정 컬럼을 타입에 맞추어 가져오기 (getInt,getString,getDate ... )
6) updateXXX() : 특정 컬럼의 값을 변경
7) deleteRow() : 현재 레코드 지우기
8) select 결과 가져오기
while (rs.next()) { out.println( rs.getInt("MNO") + "," + rs.getString("MNAME") + "," + rs.getString("EMAIL") + "," + rs.getDate("CRE_DATE") + "<br>"); }
Java
rs.next() : t/f를 반환 다음이 있을 경우, rs 객체는 해당 레코드를 가져옴
9) JDBC 프로그래밍의 마무리
finally { try {if (rs != null) rs.close();} catch(Exception e) {} try {if (stmt != null) stmt.close();} catch(Exception e) {} try {if (conn != null) conn.close();} catch(Exception e) {} }
Java
finally에 자원을 해제하기 좋음
자원 해제 시 자원 선언의 역순으로 처리
개요
서블릿 프로그램의 핵심은 Servlet 인터페이스를 이해하는 것
Servlet을 먼저 배운 다음 HttpServlet을 사용하는 방법을 배워야 함
CGI 프로그램과 서블릿
1.CGI의 이해
CGI : 웹서버와 프로그램이 주고받는 규칙
CGI프로그램: CGI 규칙에 따라 웹서버와 데이터를 주고 받도록 작성된 프로그램
[웹브라우저] ——요청→ [웹서버] —————실행→ [프로그램] [웹브라우저] ←응답—— [웹서버] ←결과(CGI 규칙)- [프로그램]
2. 서블릿
: 자바로 만든 CGI 프로그램
다른 CGI와 다른점 : 웹서버와 직접 데이터를 주고받지 않음, 전문 프로그램에 의해 관리됨
서블릿 컨테이너
: 서블릿의 생명주기를 관리하는 프로그램
서블릿 컨테이너가 서블릿을 대신하여 CGI 규칙에 따라 웹 서버와 데이터를 주고 받음
⇒ 더 이상 개발자가 CGI 규칙을 신경 쓸 필요가 없어짐
대신, 서블릿 컨테이너와 서블릿 사이의 규칙을 알아야 함
[웹서버] ————요청위임→ [서블릿 컨테이너] ——실행→ [서블릿(.class)] [웹서버] ←결과(CGI 규칙) — [서블릿 컨테이너] ←결과(Servlet 규칙)- [서블릿(.class)]
** 서블릿 컨테이너에 형식을 맞추어서 올리는 이유는 서블릿 컨테이너가 웹서버에 CGI규칙에 맞추어서 결과를 보내기 때문
웹프로젝트 준비
1. 웹 프로젝트 생성
View Original
http ://127.0.0.1:9999/web01 (웹어플리케이션 이름)/Hello(서블릿이름)
WebConent : 웹 컨텐트 파일을 저장할 작업 폴더, 서버에 자동 배치할 때 이 폴더의 내용물을 서버의 배치 폴더로 복사
2. 웹프로젝트 폴더 구조
View Original
src : 자바 소스 파일 두는 곳, 서블릿 클래스나 필터,프로퍼티 파일, 리스너 등 필요한 모든 자바 클래스 파일을 두는 곳
build/classes : .class 파일이 놓이는 곳
WebContent/WEB-INF : 웹 애플리케이션의 설정과 관련된 파일을 두는 곳 이 폴더는 클라이언트에서 요청할 수 없음 ⇒ HTML,JS,CSS 등 파일 두면 안됨
WebContent/WEB-INF/web.xml : 웹 애플리케이션의 배치 설명서 (DD 파일)
서블릿이나 필터, 리스너, 매개변수, 기본 웹페이지 등 웹어플리케이션 컴포넌트의 배치 정보 작성
서블릿 컨테이너는 클라이언트 요청을 처리할 때 이 파일의 정보를 참고
(서블릿을 실행하기전 참고) 서블릿 클래스 찾거나 필터 실행하여 수행
WebConent/WEB-INF/lib
: jar를 두는 폴더 ( jar : 클래스 파일 + 프로퍼티 파일을 모아놓은 보관소)
서블릿 만들기
1. 서블릿 작성
public class HelloWorld implements Servlet{ ServletConfig config; @Override public void init(ServletConfig config) throws ServletException { System.out.println("init() 호출"); this.config = config; } @Override public void destroy() { System.out.println("destroy() 호출함"); } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("service() 호출됨"); } @Override public ServletConfig getServletConfig() { System.out.println("getServletConfig() 호출됨"); return this.config; } @Override public String getServletInfo() { System.out.println("getServletInfo() 호출됨"); return "version=1.0; author=jh; copyright=jh"; } }
Java
2. javax.servlet.Servlet 인터페이스
Servlet 인터페이스를 구현해서 컨테이너가 그에 해당하는 서블릿( CGI 프로그램 .class)을 호출
1) 생명주기에 관련 메서드 : init() , service, destroy()
init() : 서블릿 컨테이너가 서블릿을 생성한 후 초기화 작업 수행하는 메서드 클라이언트의 요청을 처리하기 전 준비 작업 ex) DB 연결, 외부스토리지 서버 연결, 프로퍼티 로딩 등
service() : 클라이언트가 요청할 때 마다 호출하는 메서드 실질적으로 서비스 수행(할일 작성)
destroy() : 서블릿 컨테이너가 종료되거나 웹 애플리케이션이 멈출 때 수행 ex) 확보한 자원을 해제, 데이터 저장 등 마무리 작업 수행
2) Servlet 인터페이스 기타 메서드 : getServletConfig(), getServletInfo()
getServletConfig() : 서블릿 설정 정보를 다루는 ServletConfig 객체를 반환 서블릿 이름, 서블릿 초기 매개변수, 서블릿 환경정보 등 얻을 수 있음
getServletInfo() : 서블릿 작성자에 대한 정보, 권리 등을 담은 문자열을 반환
3. 서블릿 배치 정보 작성
배치 설명서 파일(DD 파일) (WEB-INF/web.xml)에 서블릿을 등록
서블릿 컨테이너가 찾을 수 있도록 등록하는 과정
<!-- 서블릿 선언 --> <servlet> <servlet-name>Hello</servlet-name> <servlet-class>lesson03.servlets.HelloWorld</servlet-class> </servlet> <!-- 서블릿을 URL과 연결 --> <servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/Hello</url-pattern> </servlet-mapping>
XML
등록되어 있지 않다면 ?
[웹서버] ————요청위임 (이 과정에서 찾지 못함)→ [서블릿 컨테이너] ——실행→ [서블릿(.class)]
1) 서블릿 선언 <servlet>
servlet-name : 서블릿의 별명 (서블릿과 이름이 같을 필요 없음)
servlet-class : 패키지이름을 포함한 서블릿 클래스명
2) 서블릿 URL 부여 <servlet-mapping>
serlet-name : 별명으로 서블릿을 가져옴
url-pattern : 서블릿을 요청할 때 클라이언트가 사용할 URL (/ = 컨텍스트 루트 의미)
4. 서블릿 구동 절차
서블릿 컨테이너 HelloWorld
1) 요청 ——> 2) 서블릿인스턴스 없으면 클래스 로딩 ————————> 인스턴스 생성 ———————> 생성자 호출 ————————> init() 호출 ————————> 3) service() 호출 ——————> <—— 4)응답 5)컨테이너 종료 → 6) destory() 호출 ——————>
컨테이너는 서블릿 인스턴스를 가지고 있음
요청이 오면 인스턴스를 먼저 확인하고 없으면 클래스를 로딩
서블릿 인스턴스는 하나만 생성되어 사용되기 때문에 인스턴스변수에 특정 사용자를 위한 데이터를 보관해서는 안됨
클라이언트가 보낸 데이터를 일시적으로 보관하기 위해서 서블릿 인스턴스 변수를 사용하면 안됨
5. 웰컴 파일들
디렉토리 기본 웹 페이지
컨텍스트 루트 디렉토리( ex. http:// 127.0.0.1:9000/web03)에 요청 시 응답
WEB-INF/web.xml 일부분
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list>
XML
위와 같은 파일명 하나를 선택해서 WebContent 하위에 생성하면 자동으로 불러옴
이클립스로 톰캣서버를 실행하면 웹어플리케이션은 WTP (Web Tool Platform) 플러그인이 관리하는 임시 폴더에 배포됨
Path : .metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/web03
View Original
GenericServlet 사용
GenericServlet 추상 클래스를 사용하여 서블릿 생성
웹브라우저에서 서블릿으로 데이터를 보내는 방법
서블릿에서 데이터를 꺼내는 방법
서블릿에서 작업한 결과를 웹브라우저로 보내는 방법
1. GenericServlet이 없던 시절 (문제상황)
서블릿 만들 때 마다 servlet 인터페이스에 맞게 구현 (5개의 메서드)
⇒ 그렇지만, 클라이언트 요청 마다 호출 되는 service() 외에는 반드시 구현해야 할 필요가 없음
⇒ 빈 메서드를 구현하는 식으로 인터페이스를 맞춤 (ex. public void destroy(){ })
2. GenericServlet 의 용도
GenericServlet = 추상 클래스 (하위 클래스에게 공통의 필드와 메서드를 상속해 주고자함)
service() 를 제외한 init(), destroy(), getServletConfig(), getServletInfo() 미리 구현
// GenericServlet 구현 public class HelloWorld extends GenericServlet{ @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("servlet 호출됨"); } }
Java
3. ServletRequest
service() 매개변수 중 하나, 클라이언트 요청 정보를 다루는 객체
getParameter() : GET, POST 요청에 들어온 매개변수 가져옴
getRemoteAddr() : 서비스를 요청한 클라이언트의 IP 주소를 반환
getScheme() : URI 형식의 스킴을 반환 ** scheme : 자원을 식별하는 최상위 분류 기호 (ex. http, ftp,file, news 등)
getProtocol() : 요청 프로토콜의 이름과 버전 (ex. HTTP/1.1)
getParameterNames() : 요청 정보에서 매개변수 이름만 추출하여 반환
getParameterValues() : 요청 정보에서 값만 추출하여 반환
getParameterMap() : 요청 정보에서 매개변수들을 Map에 담아 반환
getCharacterEncoding() : POST 요청의 매개변수에 대해 문자 집합을 설정 ** 주의 : 처음 getParameter() 호출하기 전 이 메서드를 호출해야만 적용됨
GET 요청 매개변수에 대해서 문자 집합 설정 방법 매개변수가 URI에 포함되어서 옴 ⇒ 서블릿컨테이너에서 URI의 인코딩 형식 설정 (URIEncoding=" ")
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
XML
4. ServletResponse
응답과 관련된 기능 제공
인코딩 타입 설정, 문자집합 지정, 출력 데이터 임시 보관하는 버퍼 크기 조정, 데이터 출력하기 위한 출력 스트림 준비
setContentType() : 출력할 데이터의 인코딩 형식과 문자 집합 지정 클라이언트가 올바르게 화면 출력을 할 수 있도록 지정
response.setContentType("text/plain");
Java
setCharacterEncoding() : 출력할 데이터의 문자 집합 지정
response.setCharacterEncoding("UTF-8");
Java
getWriter() : 클라이언트로 출력할 수 있도록 출력 스트림 객체 반환 ** 참고 : 이미지, 동영상 같은 바이너리 데이터 출력은 getOutputStream()
PrintWriter writer = response.getWriter();
Java
5. @WebServlet 애노테이션을 이용한 서블릿 배치 정보 설정
web.xml 대신 애노테이션을 이용해 배치 정보 작성
() 안에 Servlet의 URL 정보 작성
@WebServlet("/calc") public class CalculatorServlet extends GernericServlet { ... }
Java
<!-- web.xml에 등록되어있는 정보를 주석처리해도 정상 작동--> <!-- <servlet> <servlet-name>CalculatorServlet</servlet-name> <servlet-class>lesson03.servlets.CalculatorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CalculatorServlet</servlet-name> <url-pattern>/calc</url-pattern> </servlet-mapping> -->
XML
6. @WebServlet 애너테이션의 주요 속성
name : 서블릿의 이름을 설정, 기본값은 "" @WebServlet(name="서블릿이름")
urlPatterns : 서블릿의 URL 목록 설정, 속성값으로 String , {} @WebServlet(urlPatterns="/calc") @WebServlet(urlPatterns={"/calc","calc.do", "calculator.action"})
value : urlPatterns 와 같은 용도 (생략가능) @WebServlet(value="/calc") @WebServlet("/calc")

+ Recent posts

"여기"를 클릭하면 광고 제거.