Java Web #1

황현근·2023년 6월 1일
0

Acorn-Academy

목록 보기
21/28
post-thumbnail

Servlet(서블릿)

Servlet이란

클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술

Servlet의 특징

  • 클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트

  • html을 사용하여 요청에 응답한다.

  • Java Thread를 이용하여 동작한다.

  • MVC 패턴에서 Controller로 이용된다.

  • HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.

  • HTML 변경 시 Servlet을 재컴파일해야 하는 단점이 있다.
  • 일반적으로 웹서버는 정적인 페이지만을 제공한다. 동적인 페이지를 제공하기 위해서 웹서버는 다른 곳에 도움을 요청하여 동적인 페이지를 작성해야한다. 여기서 웹서버가 동적인 페이지를 제공할 수 있도록 도와주는 어플리케이션이 Servlet이며, 동적인 페이지를 생성하는 어플리케이션이 CGI입니다.

[Servlet 동작방식]

  1. 사용자가 URL을 입력하면 HTTP RequestServlet Container전송한다.
  2. 요청을 전송받은 Servlet ContainerHttpServletRequest, HttpServletResponse 객체를 생성한다.
  3. web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾는다.
  4. 해당 서블릿에서 service메소드를 호출한 후 클리아언트의 GET, POST여부에 따라 doGet() 또는 doPost()를 호출한다.
  5. doGet() or doPost() 메소드는 동적 페이지를 생성한 후 HttpServletResponse객체에 응답을 보냅니다.
  6. 응답이 끝나면 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)

서블릿 매개변수 객체


Servlet Container(서블릿 컨테이너)

서버에 서블릿을 만들었다고 해서 스스로 작동하는 것이 아니고 서블릿을 관리해주는 것이 필요한데, 그러한 역할을 하는 것이 바로 서블릿 컨테이너이다. 서블릿 컨테이너는 클라이언트의 요청(Request)을 받아주고 응답(Response)할 수 있게, 웹서버와 소켓으로 통신하며 대표적인 예로 톰캣(Tomcat)이 있다. 톰캣은 실제로 웹 서버와 통신하여 JSP(자바 서버 페이지)Servlet이 작동하는 환경을 제공해줍니다.

Servlet Container 역할

  1. 웹서버와의 통신 지원
  2. 서블릿 생명주기(Life Cycle) 관리
  3. 멀티쓰레드 지원 및 관리
  4. 선언적인 보안 관리

JSP

  • JSPHTML 소스코드 속에 자바 소스코드가 들어가는 구조를 갖는 웹어플리케이션 프로그래밍 기술이다.
  • 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가 최초로 요청했을 경우JSP로 작성된 코드가 서블릿 코드로 변환됨 (java파일 생성)
  • 서블릿 코드를 컴파일해서 실행가능한 bytecode변환한다(class파일 생성)
  • 서블릿이 실행되어 요청을 처리하고 응답 정보를 생성한다.

JDBC API

  • Java DataBase Connectivity의 약자로 JDBC는 자바 언어로 데이터베이스 프로그래밍을 하기 위한 라이브러리이다.
  • JDBC는 DBMS에 종속되지 않는 관련 API를 제공한다. JDBC API는 JDK에서 제공하며 JDBC 프로그래밍을 위해서는 JDBC드라이버가 필요하다
  • JDBC 드라이버는 각 DBMS 회사에서 제공하는 라이브러리 압축파일이다.

JDBC API 클래스

JDBC는 다양한 클래스와 인터페이스로 구성된 패키지 java.sqljavax.sql로 구성되어 있다.

  • 데이터베이스를 연결하여 테이블 형태의 자료를 참조
  • SQL 문을 질의
  • SQL 문의 결과를 처리

JDBC를 이용한 데이터베이스 연동과정

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;
    }

Apache & Tomcat

Apache

아파치서버란 클라이언트에서 요청하는 HTTP요청을 처리하는 웹서버를 의미한다.
아파치서버는 정적타입(HTML, CSS, 이미지 등)의 데이터만을 처리하기 때문에 톰캣이 등장했다.

Tomcat

JAVA EE 기반으로 만들어졌으며, JSPServlet을 구동하기 위한 서블릿 컨테이너 역할을 수행한다.
아파치서버와는 다르게 DB연결, 다른 응용프로그램과 상호 작용동적인 기능들을 사용할 수 있다.

💡 아파치 톰캣으로 부르는 이유

기본적으로 위처럼 아파치톰캣의 기능은 나뉘어져 있지만,
톰캣 안에 있는 컨테이너를 통해 일부 아파치의 기능을 발휘하기 때문에 보통 아파치 톰캣으로 합쳐서 부르곤 한다.

0개의 댓글