본문 바로가기

JAVA SPRING

서블릿 - get, post, @WebServlet, 비즈니스 로직 처리(DAO, VO, 커넥션풀)

1. 서블릿

■ 서블릿이란? : 서버 쪽에서 실행되며 클라이언트의 요청에 따라 동적으로 서비스를 제공하는 자바 클래스. 독자적으로 실행되지 못하고, 톰캣과 같은 JSP/Servlet 컨테이너에서 실행된다. 스레드 방식으로 실행되며 동적인 여러 기능을 제공한다.

 

- Servlet 인터페이스 : Servlet 관련 추상 메서드를 선언한다. init(), service(), destotry(), getServletInfo(), getServletConfig()를 선언한다.

- ServletConfig 인터페이스 : 서블릿 기능 관련 추상 메서드가 선언되어 있다. 

- GenericServlet 클래스 : 상위 두 인터페이스를 구형하여 일반적인 서블릿 기능을 구현한 클래스이다.

- HttpServlet 클래스 : 위 클래스를 상속받아 HTTP프로토콜을 사용하는 웹 브라우저에서 서블릿 기능을 수행한다. 웹브라우저 기반 서비스를 제공하는 서블릿을 만들 때 상속받아 사용한다.

 

□ 서블릿 생명주기 메서드

- init() : 서블릿 요청 시 맨 처음 한번만 호출되며, 초기화 작업을 주로 수행한다.

- doGet(), doPost() : 요청 시 매번 호출되며, 실제 클라이언트가 요청하는 작업을 수행한다.

- destory() : 서블릿이 기능을 수행하고 메모리에서 소멸될 때 호출된다. 마무리 작업을 주로 수행한다.

 

□ 서블릿을 만들고 실행하는 과정 : 서블릿 클래스 만들기 -> 메서드 구현 -> 매핑 작업 -> 웹에서 요청하기

 

 

1. 서블릿 API들은 톰캣의 라이브러리로 제공되므로, 클래스 패스를 설정한다.

 

2. sec01.ex01이라는 이름으로 패키지를 생성한 후, New>Class로 서블릿들을 만든다.

3. FirstServlet를 작성한다.

4. 브라우저에서 서블릿을 요청하려면 패키지 이름까지 포함된 서블릿 클래스 이름인 sec1.ex01.FirstServlet 로 요청해야 한다. 그러나 클래스 이름이 길어지면 입력하기 불편하므로, 서블릿 매핑 방식을 이용하본다. 

서블릿 매핑은 web.xml에서 설정하며, <servlet> 태그와 <servlet-mapping> 태그를 이용한다. 

 

▲ 웹브라우저에서 서블릿 매핑 이름인 /first로 요청하면 <servlet-mapping> 에서 /first를 찾아 name을 알아내, name값인 aaa로 연결할 서블릿을 알아낸다.

 

5. Run On Server. 나는 Tomcat 9.0을 사용하므로 Browse를 눌러 톰캣 폴더를 연결해주었다. 

 

6. 브라우저에서 /first로 요청한 결과. 서블릿 안의 메서드들이 실행되었다. 

 

7. 다수 서블릿 매핑을 학습하기 위해 Web.xml에 매핑 코드를 작성하고, SecondServlet를 만든다.

 

 

호출 성공! 

 

8. 여러 클라이언트가 서블릿을 요청하면 

-요청을 받아서 -> 요청받은 서블릿이 메모리에 존재하는지 확인하고 -> 존재하지 않을 경우 서블릿을 메모리에 로드 한 뒤 결과를 응답한다. 이미 메모리에 존재하는 서블릿이라면 바로 메서드를 호출해서 결과를 응답한다. /first 서블릿을 여러번 재호출하면 초기화 메서드인 init()은 최초에만 실행되고, 이후에는 doGet메서드만 호출하여 서비스된다.

 

9. 애너테이션을 이용해 서블릿 매핑을 학습해본다. web.xml에 일일이 설정하기에는 복잡해진다는 단점이 있으므로 , HttpServlet 클래스를 상속받아 @WebServlet 애너테이션을 사용하여 매핑한다. 

아래 코드에서 @WebServlet("/third") 가 애너테이션을 이용한 매핑이다. 즉, /third로 요청하면 xml을 수정하지 않더라도 다음과 같이 성공적으로 서블릿 요청을 수행할 수 있다.

 

2. 서블릿의 기본 기능

 

■ HttpServletRequest 요청 처리 실습. 

- <form> 태그를 사용한다. 로그인창에서 ID와 비밀번호를 입력받아 HttpServletRequest로 처리한다. 

 

 

1. method="get"방식으로, url에 전송 정보가 첨부되도록 login.html을 작성하였다. <form> 태그에서 action 속성은 입력된 데이터를 전송할 서블릿이나 JSP를 지정하는 역할을 하며, 서블릿으로 전송할 때는 매핑 이름을 사용한다.

 

2. LoginServlet을 작성하였다. 

HttpServletRequest 클래스의 getParameter() 메서드로 전송된 ID와 비밀번호를 받아온다. 즉, 웹브라우저에서 전송한 정보를 톰캣 컨테이너가 HttpServletRequest 객체를 생성한 후 doGet()으로 넘겨준다. 

이후 request.getParameter을 통해 <input>태그의 name 속성값으로 전송된 값들을 받아 , String user_id 와 user_pw에 저장한다. 

 

3. 로그인창 실행.

 

 

4. 여러개의 값을 전송할 때의 요청을 처리해본다. 하나의 name 으로 여러 값을 서블릿으로 요청한다.  

 

5. @WebServlet에 /input을 설정한다. 하나의 값을 얻을때는 request.getParameter을, 여러개의 값을 얻을때는 request.getParameterValues("네임") 을 사용해야 한다. 반복문을 통해 name으로 받은 값들을 출력하면..

6. 체크한 값들이 성공적으로 전달되었다. 

 

7. 전송된 데이터가 많아 일일이 name의 값을 기억하기 힘들 때는 어떨까? 이때는 getParameterNames()메서드를 사용한다. 먼저 input.html에서 action값을 수정해 새로운 서블릿으로 연결되도록 하고.. 

 

8. 서블릿을 새로 작성한다. 이때, Enumeration 타입으로 request.getParameterNames()를 사용해 name속성들만 받아와, 반복문을 통하여 하나씩 출력한다. 참고로 Enumeration은 다음 내용이 있는지 확인하는 hasMoreElements() 메서드와 그 값을 가져오는 nextElement() 메서드가 있다. 

 

■ HttpServletRequest 응답 처리 실습

 

- 서블릿에서는 doGet()이나 doPost() 메서드 안에서 응답을 처리한다. javax.servlet.http.HttpServletResponse 객체를 이용하고, setContentType()을 이용해 클라이언트에게 전송할 데이터 종료를 지정한다. 클라이언트와 서블릿의 통신은 자바 I/O의 스트림을 이용한다. 

 

톰캣에서 미리 설정해놓은 데이터 종류들을 MIME-TYPE라고 한다. HTML의 경우이는 text/html, 일반 텍스트는 text/plain, XML데이터 전송시는 application/xml을 지정한다. 

 

서블릿이 클라이언트에게 응답하는 과정 : setContentType()로 MIME-TYPE 지정> 데이터를 출력할 PrintWritter객체 생성 > 출력 데이터를 HTML 형식으로 만들기 > 데이터 출력

 

 

1. login.html을 재활용한다. action을 login2로 수정해서 새로운 서블릿을 만들것이다.

2. @WebServlet("/login2")로 매핑된 새로운 서블릿을 만든다. 응답은 'HttpServletResponse' 객체를 이용한다. 

request.setCharacterEncoding("utf-8"); 으로 전송된 데이터의 인코딩을 설정하고,
response.setContentType("text/html;charset=utf-8"); 으로 응답할 데이터가 html임을 설정한다. 
PrintWriter out = response.getWriter(); HttpServletResponse객체의 getWriter()을 이용해 출력 스트림 PrintWriter객체를 받아온다. 

 

그 다음 브라우저로 출력할 데이터를 문자열로 연결해서 HTML 태그로 만들고, PrinWriter의 print()를 이용해 웹브라우저로 출력한다. 

 

3. 결과

■ doGet(), doPost(), doHandle() 실습

 

- GET 방식 : URL 주소에 데이터를 붙여서 전송하는 방식. URL 뒤에 name=value 형태로 전송된다. doGet()으로 전송된 데이터를 처리한다.

- POST 방식 : 전송하는 데이터를 숨겨서 전송하는 방식. doPost() 를 이용해 데이터를 처리한다. 

 

get 방식과 post 방식은 다른 글에서 다뤄보았었기 때문에.. doHandle() 을 호출해서 모든 기능을 구현하는 예제로 대체한다. 

 

 

1. login.html을 또 재활용한다. action을 login4로 수정하고, 새로운 서블릿을 만들것이다.. 지금은 method가 get 방식이다.

2. 서블릿 작성. get과 post 메소드 요청이 들어오면, doHandle(request, response)를 통해 Handle로 처리를 떠넘긴다.

그리고 doHandle()은 이전 작업과 마찬가지로 인코딩, 메서드 호출 로그, getParameter를 통한 값 받아오기를 수행하여 print로 출력하도록 만든다.

3. get 방식 그대로 요청해보도록 하겠다. 

콘솔창을 통해 doGet 메서드가 doHandle 메서드를 호출했고, 최종적으로 Handle 메서드가 get 방식을 처리했음을 알 수 있다. 

4. method 를 post 로 고쳐 post 방식도 Handle로 처리할 수 있는지 확인해본다. 

 

■ 자바스크립트로 서블릿 요청하기

 

서블릿에 요청할 때 <form> 에서 직접 요청하는 것이 아닌, 자바스크립트 함수를 호출하고 유효성 검사를 한 후, 조건에 맞으면 자바스크립트 함수에서 서블릿을 요청하도록 한다. 

 

 

1. login2.html을 작성한다. 

 

function fn_validate(){  // 자바스크립트 함수
      var frmLogin=document.frmLogin; // <form> 태그의 name 속성에 할당되어 있는 값을 이용해 폼 태그 객체를 받아온다.
      var user_id=frmLogin.user_id.value; // input 태그의 name 속성들의 값을 받아 저장한다. 
      var user_pw=frmLogin.user_pw.value;

      if((user_id.length==0 ||user_id=="") ||(user_pw.length==0 ||user_pw=="")){ //아이디 또는 비밀번호의 길이가 0이면,
 alert("아이디와 비밀번호는 필수입니다."); //경고창을 띄운다.
      }else{ // 그렇지 않으면 
frmLogin.method="post"; //메소드를 post로,
frmLogin.action="login5"; //action 을 login5로 설정해 서블릿을 요청하고
frmLogin.submit();  // 전송한다. 
      }

 

    <input type="hidden" name="user_address" value="서울시 성북구" /> 는 hidden 태그를 이용해 화면에는 보이지 않도록 하여 값을 서블릿으로 전송하는 코드이다. 

 

 

2. 서블릿을 작성한다. 

 

3. 아이디 또는 비밀번호를 입력하지 않으면 경고창이 뜨고, 모두 입력하고 로그인을 누르면 성공적으로 서블릿이 요청된다. 

 

 

■ 구구단 실습

 

1. gugu.html 작성. 

 

2. 서블릿 작성. getParameter("dan") 값을 정수형으로 받아온다.

 

3. 8을 입력했을때의 결과.

 

 

2. 서블릿의 비즈니스 로직 처리

 

서블릿의 비즈니스 처리 과정 : 클라이언트로 요청 받기 > 데이터베이스 등의 로직 처리 > 처리 결과 돌려주기

서블릿의 데이터베이스 연동 과정 : 클라이언트로 요청 받기 -> MemberServlet은 요청을 받은 후 MemberDAO 객체를 생성해 listMembers() 메서드를 호출 > listMembers()에서 다시 connDB() 메서드 호출하여 DB와 연결한 후 SQL문 싫애해 회원정보 조회 > 조회 정보 MemberVO 속성에 설정한 후 ArrayList에 저장 > ArrayList를 MemberServlet로 반환한 후, ArrayList의 MemberVO를 차례대로 가져와 회원정보를 HTML 태그 문자열로 만들기 > 출력 

 

* DAO : DataBase Access Object. 데이터베이스의 data에 접근하기 위한 객체. DataBase 접근을 하기 위한 로직과 비지니스 로직을 분리하기 위해 사용한다. 

* VO : Value Object (값 표현)

 

 

1. sql plus를 실행시킨다. 이때 저런 오류가 나면, 컴퓨터관리 - 시스템에서 표시한 서비스들이 실행되고 있는지 확인한다. 

2. 쿼리를 작성해 테이블과 데이터를 만든다. 

 

3. jdbc 드라이버를 설치한다. 

4. 멤버 서블릿을 작성한다. 이때 SQL문으로 조회할 DAO객체를 생성하고, listMembers() 메서드로 회원정보를 조회한 뒤 for문과 ,<tr> 태그를 이용해 리스트 정보를 담은 표 형태로 웹브라우저에 출력한다. 

 

 

 

5. DAO 클래스를 작성한다. 회원 정보 조회 SQL문을 실행해 조회한 레코드들의 컬럼 값을 다시 VO 객체의 속성에 설정하고, AllayList에 저장한 뒤 호출한 곳으로 반환한다. 

 

*ResultSet객체는 한번에 한 행씩 리턴하는 질의어 결과이다. next()로 한 행씩 이동한다. 

 

6. VO 클래스를 작성한다. 이는 값을 전달하는 데 사용되는 클래스이다. 조회한 레코드의 컬럼값을 속성에 저장해야 하므로 컬럼 이름과 동일한 자료형, 이름으로 속성을 선언한 뒤 getter/setter을 각각 생성한다. 

 

▲ 무사히 조회된 모습. 멤버 서블릿에서 조회한 정보를 출력하기 위해 memberVO를 사용했다. 즉, DAO에서 데이터를 조회하여 조회한 값을 VO객체에 설정해주면, VO는 받은 값들을 속성에 저장하고 서블릿이 조회할 수 있게 한다. 

 

 

PrepareStatement를 이용한 실습. 이 인터페이스는 SQL문을 미리 컴파일해서 재사용하므로 훨씬 빠르게 데이터베이스 작업을 수행할 수 있다는 장점이 있다. 

 

 

1. DAO를 작성한다. 이때, PrepareStatement() 메서드에 SQL문을 전달해 객체를 생성하고, executeQuery() 메서드를 호출해 미리 설정한 SQL문을 실행한다.

 

■ 커넥션풀 실습

 

- 커넥션풀 : 미리 데이터베이스와 연결시킨 상태를 유지하는 기술.

- JNDI : 필요한 자원을 키/값 쌍으로 저장한 후 필요할 때 키를 이용해 값을 얻는 방법. 즉, 웹브라우저에서 name/value 쌍으로 전송한 후 서블릿에서 getParameter(name)으로 값을 가져올 때 사용한다. 

 

 

1. 톰캣에서 커넥션풀을 사용하려면 DBCP 라이브러리를 받아야 한다. 

 

 

2. context.xml 에서 <Resource> 태그를 이용해 톰캣 실행 시 연결할 데이터베이스를 설정한다. 자바 클래스에서는 다음과 같이 name 속성의 jdbc/oracle로 DataSource에 접근한다. 

 

- name : JNDI 이름

- auth : dlswmd wncp

- username : DB 접속 ID

- password : DB 접속 PWD

- url : 접속할 DB주소 및 포트번호, SID 

 

3. 회원 정보 조회 실습. DataSource를 이용해 DB와 연동하는 DAO 클래스를 수정한다. 생성자에서 톰캣에서 미리 생성한 DataSource를 name 값인 jdbc/oracle을 이용해 미리 받아온다. 마지막으로 서블릿에서 listMembers()메서드를 호출하면 getConnection()메서드를 호출하여 DataSource에 접근한 후 데이터베이스와의 연동 작업을 수행한다.

 

 

4. 조회 결과

 

※ DataSource를 이용한 회원 정보 등록 및 삭제 실습 

 

 

1. 회원가입창을 만든다. 아이디, 비밀번호, 이름, 이메일을 입력받으며, 하나라도 입력되지 않았을 경우를 대비하여 입력되어있는지를 검사하는 함수 fn_sendMember()을 작성해 자바스크립트에서 서블릿을 요청하도록 만든다. 

 

2. 서블릿을 작성한다. command값을 가져와 addMember이면 전송된 회원 정보를 받아온다. 

회원 정보를 MemberVO 객체에 설정한 후, DAO의 메서드로 전달해서 SQL문을 이용해 테이블에 추가한다. 

3. 회원정보를 추가해본다. 

 

4. 삭제 기능을 추가한다. delete문의 첫 번째 ? 에 전달된 ID를 인자로 excuteUpdate() 메서드를 호출한다. 

pstmt.setString(1,id) // 첫 번째 ?에 전달된 ID를 인자로 넣는다.

pstmt.excuteUpdate() // delete문을 실행해 테이블에서 해당 ID의 회원정보를 삭제한다. 

 

마지막에 추가했던 chali의 삭제 버튼을 누르자, 성공적으로 데이터가 삭제되었다.

 

'JAVA SPRING' 카테고리의 다른 글

JSP 스크립트, 액션 태그  (0) 2021.07.27
서블릿 확장 API, 쿠키와 세션, 필터와 리스너  (0) 2021.07.23
HTTP method, MY Batis 실습  (0) 2021.07.19
웹 프로그래밍 - 2일차  (0) 2021.07.09
웹프로그래밍 - 1일차  (0) 2021.07.09