[웹 프로그래밍]
서버 : 네트워크에서 서비스를 제공하는 컴퓨터로서 서비스를 제공할 수 있는 프로그램이 설치되어야 한다.
클라이언트 : 네트워크에서 서비스를 제공받는 컴퓨터로서 브라우저가 설치되어야 한다.
[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점대 버전의 호출 과정
- 사용자에게 서비스 요청이 들어오면 URL이 서버측으로 전달된다.
- web.xml파일에서 URL에 같이 온 패턴을 찾아낸다.
- 해당 패턴의 서블릿 명을 매핑하고 그 결과로 서블릿이 저장된 클래스의 위치를 찾는다.
- 해당 서블릿에 정의된 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점대 버전은 다음과 같이 두 가지 방식으로 사용할 수 있다.
- Annotation
- 아래 소스코드를 참고하면 된다. 웹 브라우저에서 서비스 요청이 들어오면 Tomcat이 URL-pattern을 소스 코드의 annotation을 참고해서 찾고, 그 내부에 service메소드를 실행한다. 아래 코드에서는 @WebServlet("/hello.do")이 Tomcat이 참조하게 될 Annotation이다.
- 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 |