BackEnd/WEB

SERVLET_국비_DAY53

Leo.K 2022. 5. 16. 18:17

[웹 프로그래밍]

서버 : 네트워크에서 서비스를 제공하는 컴퓨터로서 서비스를 제공할 수 있는 프로그램이 설치되어야 한다. 

클라이언트 : 네트워크에서 서비스를 제공받는 컴퓨터로서 브라우저가 설치되어야 한다. 

 

[HTTP 프로토콜] -> 정적인 정보만 제공하는 특징이 있다. -> 동적인 정보를 제공하는 프로그래밍 필요 -> CGI

www, 서비스를 제공하지 위한 통신규약이다. 

웹 서비스를 제공하는 Hyper Text Transfer Protocol이다. 

웹 서버와 클라이언트는 HTTP를 통해서 통신한다.

 

[CGI(Common Gateway Interface)]

  • 초기 웹 프로그래밍에 사용되었던 기술이다.
  • 프로세스 단위로 실행되어서(요청에 대한 응답이 프로그램 실행) 서버 부하가 심하다. -> 나중에 스레드 단위 실행으로 바뀌었다.
  • 클라이언트의 다양한 요구를 만족시키기 위해서 웹 서버에서 실행되고 결과값을 클라이언트에게 HTML형태로 전송한다.

 

[웹 애플리케이션]

정의 

  • html, JSP, Servlet, 일반 클래스들이 다수의 컨테이너에서 동작할 수 있고 묶여질 수 있는 자원들의 모음이다. 

디렉토리 구조 -> 반드시 다음과 같은 디렉토리 구조를 유지해야 한다. 

새로운 파일을 생성할 때 주의해야 하는 점이 위의 사진에 정리 되어 있다. 생성하는 파일의 확장자를 확인하여 정확한 폴더에 생성해야 오류없이 실행이 가능하다.

 

[서블릿 정의] Server + Let

웹 응용프로그램을 만드는 자바 기술로서 실행결과 값은 html로 작성된다. 

http 프로토콜로 요청받은 서비스에 대한 응답으로는 html파일을 제공한다. 이때 동적으로 html파일을 만들어야 할수도 있는 데 이러한 응답 처리를 해주는 서비스 객체가 서블릿이다.

특징

  • html의 정적인 문제점을 해결할 수 있는 동적인 특징을 갖는다.
  • 자바언어로 작성되어 자바의 일반적인 특징을 모두 갖는다. 객체지향적이다. 
  • 다른 자바기술과 연동이 가능하다. (JDBC, EJB 등)
  • container라는 특별한 환경에서 실행된다. 
  • Server Side에 적합한 자바기술이다. 
  • 보안모델 적용이 수월하다 
  • 저장 파일의 확장자는 java이고 컴파일된 바이트코드가 container에서 실행된다. 
  • 웹 응용 프로그램이기 때문에 브라우저를 통해서 요청한다.

 

[서비스 객체를 호출하는 방법 2.5]

Dynamic Module Version을 2.5로 생성한다. java는 1.8버전으로 한다.

URL을 Mapping하는 경우 확장자는 아무렇게나 해도 된다. 하지만 공부할때는 서블릿에서 기본적으로 지원하는 .do or .action을 사용한다.

더보기
서비스 객체를 생성하여 실행한 결과

 

Tomcat 2점대 버전의 호출 과정

  1. 사용자에게 서비스 요청이 들어오면 URL이 서버측으로 전달된다. 
  2. web.xml파일에서 URL에 같이 온 패턴을 찾아낸다. 
  3. 해당 패턴의 서블릿 명을 매핑하고 그 결과로 서블릿이 저장된 클래스의 위치를 찾는다. 
  4. 해당 서블릿에 정의된 service메소드를 호출한다.

web.xml -> 서블릿의 환경설정을 기술한 파일, 서블릿이 호출되는 내용이 담긴 파일.

Tomcat 2점대 버전은 반드시 이 파일의 내용을 확인해야 한다.

웹 브라우저에서 서비스 요청이 들어오면 URL에 있는 서블릿 정보를 확인해서 url-pattern을 찾고 이 패턴에 연결된 서블릿 name을 찾아서 해당 이름을 가진 파일의 클래스 위치를 찾아서 service 메소드를 실행(호출)시킨다

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package action;
 
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class HelloAction
 */
public class HelloAction extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        
        
        //나에게 서비스를 요청한 사람을 찾는 방법
        //접속(요청)자 정보
        //request가 요청자의 정보를 가지고 있는 객체이다.
        String ip = request.getRemoteAddr();
        
        
        System.out.printf("[%s]--HelloAction Call--\n", ip);
    }
 
}
 
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
  <servlet>
    <description></description>
    <display-name>HelloAction</display-name>
    <servlet-name>HelloAction</servlet-name>
    <servlet-class>action.HelloAction</servlet-class>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>HelloAction</servlet-name>
    <url-pattern>/hello.do</url-pattern>
  </servlet-mapping>
 
cs

 

[서비스 객체를 호출하는 방법 3.0] 

Tomcat 3점대 버전은 기본적으로 web.xml이 없다. web.xml은 선택사항으로 작성해서 사용할 수 있고, 3점대 버전은 annotation을 사용한다.

이 Annotation(꼬리표)를 주석 처리하면 Tomcat이 URL-Pattern을 찾아갈 수 없기 때문에 문제가 발생한다. 

3점대 버전은 다음과 같이 두 가지 방식으로 사용할 수 있다.

  1. Annotation
    1. 아래 소스코드를 참고하면 된다.  웹 브라우저에서 서비스 요청이 들어오면 Tomcat이 URL-pattern을 소스 코드의 annotation을 참고해서 찾고, 그 내부에 service메소드를 실행한다. 아래 코드에서는 @WebServlet("/hello.do")이 Tomcat이 참조하게 될 Annotation이다.
  2. web.xml작성(선택)

단, 위 두가지 방식을 동시에 사용하면 에러가 발생한다. -> Life Cycle Exception

라이프 사이클 익셉션이 발생하면 100퍼센트 url패턴에 문제가 있는거다. URL패턴이 잘못되었거나(URL패턴은 반드시 '/'로 시작해야 한다) 위 처럼 두 가지 방식을 동시에 사용해서 (servlet-mapping)매핑되는 호출정보가 중복된 경우이다.  

Tomcat 3점대 버전의 호출 과정

패턴을 찾아서 서블릿을 호출하는 과정은 web.xml을 확인하는 과정과 동일하다. 

서비스 요청 URL에서 패턴을 찾았다면, 그 패턴과 어노테이션이 일치하는 서블릿을 찾아서 호출한다. 

[서비스 객체를 호출해서 html작성하기]

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package action;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class HelloAction
 */
 
//@annotation
//1. 프로그램 주석(꼬리표)
//2. Tomcat 요청주소(URL PATTERN)를 분석한다. -> 해당 서블릿을 구동
//3. LifeCycleException이 발생되면 무조건 url-pattern부분에서 발생된 에러
 
//@WebServlet("/hello.do")
public class HelloAction extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(
            HttpServletRequest request,            //요청 처리 객체(클라이언트 -> 서버측으로 넘어오는 정보를 관리하는 객체)
            HttpServletResponse response        //응답 처리 객체(서버 -> 클라이언트측으로 전달되는 정보를 관리하는 객체)
            
            ) throws ServletException, IOException {
        // TODO Auto-generated method stub
        
        String ip = request.getRemoteAddr();
        System.out.printf("[%s : --HelloAction Call--]\n", ip);
        
        
        //응답처리(response 이용)
        
        //1. 전송 문서 정보        :    mime type + 인코딩
        //                            타입/확장자
        //                            text/xml
        //                            text/json
        //                            image/jpg
        response.setContentType("text/html; charset=utf-8;");
        
        
        //2. 출력 스트림 얻어오기 
        PrintWriter out = response.getWriter();
        
        //3. 동적 HTML생성 전송
        out.println("<html>"); //--> 모든 타입 전송 가능
        //out.write("<html>"); --> 문자열만 전송 가능
        out.println("<head><title>hello 응답</title></head>");
        out.println("<body>");
        out.printf("[%s]님 안녕하세요<br>", ip);
        out.println("</body>");
        out.println("</html>");
    }
 
}
 
cs

 

[서비스 객체에게 파라미터를 전송하는 방법]

query : 요청 파라미터(서버로 전달할 값. 형식> 변수명=값1 & 변수명2=값2 &...)

쿼리를 통해 파라미터를 전송하면 Tomcat이 사용자가 요청한 파라미터 값을 읽어서 url-pattern과 일치하는 서블릿으로 전달한다. 서버에서는 전달받은 파라미터를 수신해서 소스코드에서 파라미터에 해당하는 명령을 수행한 후에 html파일 형식으로 사용자의 요청에 응답한다. 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package action;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class HelloAction
 */
 
//@annotation
//1. 프로그램 주석(꼬리표)
//2. Tomcat 요청주소(URL PATTERN)를 분석한다. -> 해당 서블릿을 구동
//3. LifeCycleException이 발생되면 무조건 url-pattern부분에서 발생된 에러
 
//@WebServlet("/hello.do")
public class HelloAction extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(
            HttpServletRequest request,            //요청 처리 객체(클라이언트 -> 서버측으로 넘어오는 정보를 관리하는 객체)
            HttpServletResponse response        //응답 처리 객체(서버 -> 클라이언트측으로 전달되는 정보를 관리하는 객체)
            
            ) throws ServletException, IOException {
        // TODO Auto-generated method stub
        
        String ip = request.getRemoteAddr();
        System.out.printf("[%s : --HelloAction Call--]\n", ip);
        
        /*
            요청사항을 Query(Parameter)를 통해서 전달한다. 
            /2022_0516_ServletEx2_3x/hello.do
            /2022_0516_ServletEx2_3x/hello.do?nation=kor
            /2022_0516_ServletEx2_3x/hello.do?nation=eng
            /2022_0516_ServletEx2_3x/hello.do?nation=jpn
            /2022_0516_ServletEx2_3x/hello.do?nation=chn
            /2022_0516_ServletEx2_3x/hello.do?nation=ger
            /2022_0516_ServletEx2_3x/hello.do?nation=fra
        */
        
        
        //Parameter 받기
        String nation = request.getParameter("nation");
        
        if(nation==null) nation = "kor";
        
        String message="";
        
        switch(nation) {
            case "kor": message = "[한국어] : 안녕하세요"break;
            case "eng": message = "[영  어] : Hi Everyone!!"break;
            case "jpn": message = "[일본어] : 오겡끼데스까!!"break;
            case "chn": message = "[중국어] : 니하오마!!"break;
            case "ger": message = "[독일어] : 구텐탁!!"break;
            case "fra": message = "[프랑스어] : 봉쥬르!!"break;
            
            default: message = "[국적불명] : 몰라~";
        }
        
        //응답처리(response 이용)
        
        //1. 전송 문서 정보        :    mime type + 인코딩
        //                            타입/확장자
        //                            text/xml
        //                            text/json
        //                            image/jpg
        response.setContentType("text/html; charset=utf-8;");
        
        
        //2. 출력 스트림 얻어오기 
        PrintWriter out = response.getWriter();
        
        //3. 동적 HTML생성 전송
        out.println("<html>"); //--> 모든 타입 전송 가능
        //out.write("<html>"); --> 문자열만 전송 가능
        out.println("<head><title>hello 응답</title></head>");
        out.println("<body>");
        out.printf("[%s]님 [%s]<br>", ip, message);
        out.println("</body>");
        out.println("</html>");
    }
}
cs

 

[서블릿 활용1] -> 사용자의 요청을 받아서 두 수의 사칙 연산을 반환하기

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package action;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class calc
 */
@WebServlet("/calc.do")
public class calc extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    /**
     * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
     */
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub    
        // /calc.do?su1=11&su2=22
        // 서블릿으로 넘겨지는 파라미터정보는 무조건 String으로 넘어온다. 
        
        //html을 먼저 실행하지 않고 서버부터 시작을하면 에러발생 -> 요청을 받아야 그에 대한 처리를 하고 응답을 하는것이기 때문
        //html을 먼저 실행해서 요청에 따른 파라미터 값을 읽어와야 하는데, 서버부터 실행하면 int su1 ~ 에서 numberFormatexception이 발생한다. 
        //사용자의 호출을 받지 않았고, 그러므로 파라미터 값을 받지 않아서 request.getParameter를 수행해도 null값이 온다.
        
        String str_su1 = request.getParameter("su1");
        String str_su2 = request.getParameter("su2");
        
        int su1 = Integer.parseInt(str_su1);
        int su2 = Integer.parseInt(str_su2);
        
        //응답 처리 
        response.setContentType("text/html; charset=utf-8;");
        
        //출력객체 
        PrintWriter out = response.getWriter();
        
        //HTML결과 전송
        out.println("<html>");
        out.println("<head><title>계산결과</title></head>");
        out.println("<body>");
        out.println(":::::계산 결과:::::<br>");
        out.printf("%d + %d = %d<br>", su1, su2, (su1+su2));
        out.printf("%d - %d = %d<br>", su1, su2, (su1-su2));
        out.printf("%d * %d = %d<br>", su1, su2, (su1*su2));
        if(su2==0) {
            out.print("0으로 나눌 수 없습니다.<br>");
        }else {
            out.printf("%d / %d = %d<br>", su1, su2, (su1/su2));
            out.printf("%d %% %d = %d<br>", su1, su2, (su1%su2));
        }
        out.println("<a href='calc.html'>다시하기</a>");
        out.println("<body>");
        out.println("</html>");
    }
 
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
 
<script type="text/javascript">
    var regex = /^[0-9]{1,}$/;
 
 
    function send(f){
        //입력된 값에 대한 유효성 체크
        var su1 = f.su1.value;        
        var su2 = f.su2.value;        
        
        if(regex.test(su1)==false || regex.test(su2) == false){
            alert("적어도 하나 이상의 숫자만 입력하세요.");
            f.su1.value='';
            f.su2.value='';
            f.su1.focus();
            return;
        }
        
        
        //지정된 action으로 데이터 전송
        f.submit();
    };
 
</script>
</head>
<body>
<form action="calc.do"> <!-- form서브밋 하는 경우 id값이 아니라 name속성이 넘어간다.-->
수1:<input type="text" name="su1"><br>
수2:<input type="text" name="su2"><br>
<input type="button" value="계산해줘" onclick="send(this.form);"> <!-- this(인풋버튼)를 소유한 폼 -->
</form>
</body>
</html>
cs

[중요]

  • 서블릿이 호출되는 방법 -> web.xml, annotation
    • 사용자가 서비스를 요청한다. 
    • 톰캣이 URL주소에서 URL-pattern을 찾는다. 
    • 패턴에 해당하는 서블릿을 호출한다. 
    • 서블릿에 정의된 service메소드를 실행하여 사용자의 요청에 응답한다.
      • 파라미터값 받기
      • 전송문서에 대한 정보 보내기 
      • 출력 스트림 생성하기 
      • 동적으로 HTML 생성하기
  • request -> 요청 처리 객체
  • response ->  응답 처리 객체
  • 사용자가 서비스 요청을 하기 편한 구조로 프로그램을 작성해야 한다.
  • 파라미터를 전달하는 방법
    • 사용자의 입력 정보를 쿼리 형태로 전송한다. 
    • 이때 각 태그는 id속성이 아닌 name속성을 사용한다. id속성은 클라이언트 페이지에서 구분하기 위함이고, name 속성은 파라미터값을 서버로 전달할 때, 해당 태그의 내용을 구분하는데 사용한다. 
    • 서버에서는 전달받은 파라미터를 형변환해서 사용한다. (무조건 String형으로 넘어옴)

'BackEnd > WEB' 카테고리의 다른 글

JSP_국비_DAY55  (0) 2022.05.18
서블릿_국비_DAY54  (0) 2022.05.17
UML_국비_DAY52  (0) 2022.05.13
JSP_국비_DAY48  (0) 2022.05.09
JSP_국비_DAY47  (0) 2022.05.06