클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술
- 클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트
html
을 사용하여 요청에 응답한다.
Java Thread
를 이용하여 동작한다.
MVC
패턴에서Controller
로 이용된다.
- HTTP 프로토콜 서비스를 지원하는
javax.servlet.http.HttpServlet
클래스를 상속받는다.
- HTML 변경 시 Servlet을 재컴파일해야 하는 단점이 있다.
- 일반적으로 웹서버는 정적인 페이지만을 제공한다. 동적인 페이지를 제공하기 위해서 웹서버는 다른 곳에 도움을 요청하여 동적인 페이지를 작성해야한다. 여기서 웹서버가 동적인 페이지를 제공할 수 있도록 도와주는 어플리케이션이
Servlet
이며, 동적인 페이지를 생성하는 어플리케이션이CGI
입니다.
- 사용자가
URL
을 입력하면HTTP Request
가Servlet Container
로 전송한다.- 요청을 전송받은
Servlet Container
는HttpServletRequest
,HttpServletResponse
객체를 생성한다.web.xml
을 기반으로 사용자가 요청한URL
이 어느 서블릿에 대한 요청인지 찾는다.- 해당 서블릿에서
service메소드
를 호출한 후 클리아언트의GET
,POST
여부에 따라doGet()
또는doPost()
를 호출한다.doGet()
ordoPost()
메소드는 동적 페이지를 생성한 후HttpServletResponse
객체에 응답을 보냅니다.- 응답이 끝나면
HttpServletRequest
,HttpServletResponse
두 객체를 소멸시킨다.
사용 예시//3. 어떤 경로 요청을 처리할 것인지 경로 설정 // ( 반드시 / 로 시작해야 한다.***) @WebServlet("/fortune") //1. HttpServlet 클래스 상속 public class FortuneServlet extends HttpServlet { //2. service() 메소드 오버라이드 @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //응답 인코딩 설정 resp.setCharacterEncoding("utf-8"); //응답 컨텐트 설정 resp.setContentType("text/html; charset=utf-8"); //클라이언트에게 문자열을 응답할 수 있는 객체의 참조값 얻어내기 PrintWriter pw = resp.getWriter(); pw.println("<!doctype html>"); pw.println("<html>"); pw.println("<head>"); pw.println("<meta Charset='utf-8'>"); pw.println("<title>오늘의 운세 페이지</title>"); pw.println("</head>"); pw.println("<body>"); //오늘의 운세 5개를 미리 준비해 둔다. String[] fortunes={"동쪽으로 가면 귀인을 만나요", "오늘은 집에만 계세요", "너무 멀리가지 마세요", "오늘은 뭘해도 되는 날이에요", "로또가 당첨되요"}; //Random 객체를 생성해서 Random ran=new Random(); //0~4 사이의 랜덤한 정수를 얻어내서 int fortune = ran.nextInt(5); pw.println("<p>"+fortunes[fortune]+"</p>"); pw.println("</body>"); pw.println("</html>"); pw.close(); } }
💡 GET & POST
사용자 데이터 전송방식
- get
URL
창에 "?"뒤에 데이터를 입력하는 방법(쿼리스트링)으로 보낸다.
데이터가 여러 개일 경우 &로 묶어서 보낸다.
데이터 검색에 많이 사용하고 데이터 크기에 한계가 있으며, 보안에 취약하다.
- post
HTTP
헤더의 내용으로 보내는 방식으로 데이터 크기에 제한이 없고, 헤더에 포함되어 보안이 뛰어남📢
Servlet
이 두 방식 중 하나로 전달받으면 해당하는 메소드를 호출한다.
html
에서method
속성을 이용해서 방식을 결정한다. (default : get)
서블릿 매개변수 객체
서버에 서블릿을 만들었다고 해서 스스로 작동하는 것이 아니고 서블릿을 관리해주는 것이 필요한데, 그러한 역할을 하는 것이 바로 서블릿 컨테이너이다. 서블릿 컨테이너는 클라이언트의
요청(Request)
을 받아주고응답(Response)
할 수 있게, 웹서버와 소켓으로 통신하며 대표적인 예로 톰캣(Tomcat)이 있다. 톰캣은 실제로 웹 서버와 통신하여JSP(자바 서버 페이지)
와Servlet
이 작동하는 환경을 제공해줍니다.
- 웹서버와의 통신 지원
- 서블릿 생명주기(Life Cycle) 관리
- 멀티쓰레드 지원 및 관리
- 선언적인 보안 관리
- JSP는
HTML 소스코드
속에자바 소스코드
가 들어가는 구조를 갖는 웹어플리케이션 프로그래밍 기술이다.- HTML속에서 자바코드는
<% 소스코드 %>
또는<%= 소스코드 =%>
형태로 들어간다. 자바 소스코드로 작성된 이 부분은 웹 브라우저로 보내는 것이 아니라 웹 서버에서 실행되는 부분이다.- 웹 프로그래머가 소스코드를 수정 할 경우에도 디자인 부분을 제외하고 자바 소스코드만 수정하면 되기에 효율을 높여준다.
- 컴파일과 같은 과정을 할 필요없이 JSP페이지를 작성하여 웹 서버의 디렉토리에 추가만 하면 사용이 가능하다.
사용 예시<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>member/list.jsp</title> </head> <body> <% List<MemberDto> list=new ArrayList<>(); list.add(new MemberDto(1, "김구라", "노량진")); list.add(new MemberDto(2, "해골", "행신동")); list.add(new MemberDto(3, "원숭이", "상도동")); %> <h1>회원 목록표</h1> <table> <thead> <tr> <th>번호</th> <th>이름</th> <th>주소</th> </tr> </thead> <tbody> <%for (MemberDto member: list) {%> <tr> <td><%=member.getNum() %></td> <td><%=member.getName() %></td> <td><%=member.getAddr() %></td> </tr> <%} %> </tbody> </table> </body> </html>
- 브라우저가 웹 서버에게 JSP에 대한 요청 정보를 전달한다.
- 브라우저가 요청한 JSP가 최초로 요청했을 경우만 JSP로 작성된 코드가 서블릿 코드로 변환됨 (java파일 생성)
- 서블릿 코드를 컴파일해서 실행가능한
bytecode
로 변환한다(class파일 생성)- 서블릿이 실행되어 요청을 처리하고 응답 정보를 생성한다.
- Java DataBase Connectivity의 약자로 JDBC는 자바 언어로 데이터베이스 프로그래밍을 하기 위한 라이브러리이다.
- JDBC는 DBMS에 종속되지 않는 관련 API를 제공한다. JDBC API는
JDK
에서 제공하며 JDBC 프로그래밍을 위해서는JDBC드라이버
가 필요하다- JDBC 드라이버는 각 DBMS 회사에서 제공하는 라이브러리 압축파일이다.
JDBC는 다양한 클래스와 인터페이스로 구성된 패키지
java.sql
와javax.sql
로 구성되어 있다.
- 데이터베이스를 연결하여 테이블 형태의 자료를 참조
- SQL 문을 질의
- SQL 문의 결과를 처리
DBCP
------ DbcpBean public class DbcpBean { //필드 private Connection conn; //생성자 public DbcpBean(){ try { Context initContext = new InitialContext(); Context envContext = (Context)initContext.lookup("java:/comp/env"); //밑에꺼 이클립스에서는 myoracle 임 >> DbcpBean, web.xml, context.xml 다 Oracle 로 바꿔주기 //Servers/context.xml 문서에 설정된 jdbc/myoracle 이라는 이름의 datasource 를 얻어온다. DataSource ds = (DataSource)envContext.lookup("jdbc/Oracle"); //얻어온 datasource 객체를 이용해서 Connection 객체의 참조값을 얻어와서 필드에 저장 conn = ds.getConnection(); //예외가 발생하지 않고 여기까지 실행의 흐름이 넘어온다면 성공 System.out.println("Connection 얻어오기 성공 !"); } catch (Exception e) { e.printStackTrace(); } // webapp > web-inf 에 > lib 에 ojdbc6.jar 붙여넣기 } //Connection 객체를 리턴해주는 메소드 public Connection getConn(){ return conn; } } ------ Dto > getList() public List<GuestDto> getList() { List<GuestDto> list = new ArrayList<>(); Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = new DbcpBean().getConn(); String sql = "SELECT * FROM board_guest ORDER BY num ASC"; pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); while (rs.next()) { GuestDto dto = new GuestDto(); dto.setNum(rs.getInt("num")); dto.setWriter(rs.getString("writer")); dto.setContent(rs.getString("content")); dto.setPwd(rs.getString("pwd")); dto.setRegdate(rs.getString("regDate")); list.add(dto); } System.out.println("getList"); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (rs != null) rs.close(); if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); //Connection 이 Connection Pool 에 반납된다. } catch (Exception e) {} } return list; } ------ Dto > insert() public boolean insert(GuestDto dto) { Connection conn = null; PreparedStatement pstmt = null; int count = 0; try { conn = new DbcpBean().getConn(); String sql = "INSERT INTO board_guest" +" VALUES(board_guest_seq.nextval, ?, ?, ?," +" to_char(sysdate,'yyyy.mm.dd hh24:mi'))"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, dto.getWriter()); pstmt.setString(2, dto.getContent()); pstmt.setString(3, dto.getPwd()); count = pstmt.executeUpdate(); System.out.println("insert"); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } catch (Exception e) { e.printStackTrace(); } } return count > 0; }
아파치서버란 클라이언트에서 요청하는 HTTP요청을 처리하는 웹서버를 의미한다.
아파치서버는 정적타입(HTML, CSS, 이미지 등)의 데이터만을 처리하기 때문에 톰캣이 등장했다.
JAVA EE
기반으로 만들어졌으며,JSP
와Servlet
을 구동하기 위한 서블릿 컨테이너 역할을 수행한다.
아파치서버와는 다르게DB연결
,다른 응용프로그램과 상호 작용
등 동적인 기능들을 사용할 수 있다.
기본적으로 위처럼 아파치와 톰캣의 기능은 나뉘어져 있지만,
톰캣 안에 있는 컨테이너를 통해 일부 아파치의 기능을 발휘하기 때문에 보통 아파치 톰캣으로 합쳐서 부르곤 한다.