26일차(2)/jsp(2) : Servlet, jsp 비교
Step01_Servlet
Dynamic web project 생성
- 생성시 target runtime에 Tomcat server의 버전이 지정되어 있어야 한다.
- java resources-src 폴더 안에 index.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index.html</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1>인덱스 페이지입니다.</h1>
<ul>
<li><a href="fortune">오늘의 운세 보기</a></li>
<li><a href="fortune.jsp">오늘의 운세 보기2</a></li>
<li><a href="friends/list">친구 목록보기</a></li>
<li><a href="friends/list.jsp">친구 목록보기2</a></li>
</ul>
</div>
</body>
</html>
- bootstrap에 있는 간단한 css를 추가해주었다. → 링크
- 프로젝트 생성 후 프로젝트 설정을 변경하고 싶다면 우클릭-Properties
- Target Runtimes에서 현재 설정된 값 확인 가능!
(tomcat 9.0으로 바꿈. 9.0 파일을 다시 받아서 eclipse에 넣어주면 된다.)
- 폴더를 생성하면 기본 라이브러리 두 개가 있다. 이 안에 필요한 클래스들이 들어있다.
1) JRE System Library : java 기초 라이브러리
2) Server Runtime :서버 관련해서 작업하기 위해 필요한 라이브러리가 들어있다.(웹 프로그래밍용 클래스들)
- Java resources 폴더 안에 test.servlet 패키지 생성
<FortuneServlet> 클래스 생성
package test.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/fortune")
public class FortuneServlet extends HttpServlet {
//생성자
public FortuneServlet() {
System.out.println("오잉 생성자가 호출되었네?");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//클라이언트에게 출력할 수 있는 객체의 참조값 얻어오기
PrintWriter pw=response.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>");
String[] fortuneToday={"lucky!", "soso~", "unlucky.."};
Random ran=new Random();
int ranNum=ran.nextInt(3);
pw.println("<h1>"+fortuneToday[ranNum]+"</h1>");
pw.println("</body>");
pw.println("</html>");
pw.close();
}
}
- 우리가 만든 객체가 클라이언트가 /fortune 주소에 대한 요청을 하면 응답하도록 할 것!
- <a> 안에 들어가는 경로가 /로 시작하지 않으면 상대경로이다.
- 저 위치에 fortune이 들어간다!
- 앞의 프로젝트 경로를 context path 라고 한다.
- 클래스에 HttpServlet 을 상속한다.
- service를 입력해서 메소드를 override한다.
- 상단에 @WebServlet 추가!
- 이것을 어노테이션annotation이라고 한다. 요청이 들어왔을 때 이것으로 응답하겠다는 의미이다.
- getwriter 메소드를 지역변수에 담고, printwriter타입으로 받아준다.(import 필요)
- 다시 run 해보면 클라이언트가 호출한 페이지에 내가 만든 클래스가 연결되어 응답하는 것을 볼 수 있다.
- 해당 페이지의 소스를 열어보면 html 형식은 아니다. 따라서 html 형식으로 맞추어준다.
- 출력되는 내용을 html 형식으로 입력하면 소스에서도 이렇게 보인다.
- 맨 위에서 utf-8 형식이라고 알려주었기 때문에 한글도 오류가 발생하지 않는다.
- 클래스를 정해진 양식으로 만들기만 했는데, 적정 시점에 호출되어서 중요한 역할을 하고 있다!
- 객체가 생성되는지 확인하고 싶다면? 파일에 생성자를 만들어준다.
//생성자
public FortuneServlet() {
System.out.println("오잉 생성자가 호출되었네?");
}
- 어느 시점에 생성자가 작동하는지 알고싶다면 syso 사용!
- 서버를 종료했다가 index.html 을 다시 실행하고 콘솔창을 보면 생성자는 아직 사용되지 않은 상태.
- '오늘의 운세보기' 링크를 누르는 순간 객체가 생성되는 것을 볼 수 있다.(콘솔창에 출력됨)
- /fortune 요청이 오는 순간 응답하기 위해서 생성자가 만들어지는 것!
- 링크를 누를 때마다 객체가 생성되지는 않는다. 하나만 생성해두고 사용한다.
- 메인메소드도 만들지 않았지만 필요한 시점에 객체가 생성되어 사용된다.
- 이미 어플리케이션은 만들어져 있고, 그중 일부 동작만 프로그래밍하는 것이다.
부분 프로그래밍에 익숙해지기!
- html 형식으로 작성하는 것은 불편하지만, 어떤 logic을 섞을 수가 있다.
- servlet으로 만들었다면 java 프로그래밍이 들어갈 여지가 있다.
java 배열을 만들 수도 있고, DB에서 불러와서 랜덤하게 나오도록 할 수도 있다.
- 상속, override, @WebServlet 은 반드시 들어가야 하지만,
우리가 만드는 java 객체의 기능은 마음대로 정의할 수 있기 때문에 그 안에서는 자유롭게 코딩할 수 있다.
- 여러가지 운세 내용 값이 랜덤하게 나오게 하고 싶다.
- 운세 몇 종류를 배열[ ] 에 담아놓고 배열 안의 값이 랜덤하게 출력되도록 하기!
package test.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//3. 어떤 경로 요청을 처리할 것인지 경로 설정(반드시 /로 시작해야한다***)
@WebServlet("/fortune")
public class FortuneServlet extends HttpServlet {//1.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 ran=new Random();
//0~4 사이의 랜덤한 정수 얻어내기
int ranNum=ran.nextInt(5);
pw.println("<p> 오늘의 운세: "+fortunes[ranNum]+" </p>");
pw.println("</body>");
pw.println("</html>");
pw.close();//닫아주기
}
}
- 경로는 반드시 / 로 시작해야 한다!★★★
- /로 시작하지 않으면 아예 열리지도 않는다.
- 안에 어떤 작업을 해두면 객체의 참조값(req, resp)은 알아서 전달된다.
전달된다는 가정 하에 작성하면 된다.
- 객체의 설계도를 납품하는 느낌이라고 생각하면 된다! 적절한 시점에(호출되었을 때) 실행될 수 있도록.
- req 요청에 관련된 객체
- resp 응답에 관련된 객체
- printwriter 문자열을 출력해주는 기능을 가지는 객체
- java의 syso를 사용하면 콘솔창에 출력됐는데, printwriter는 웹서버에 요청을 한 클라이언트에게 출력된다.
- 이 메소드에 전달되는 값을 printwriter가 출력해주는 구조이다.
- run 하고 우클릭-페이지 소스보기 에서 새로고침하면
<p> 부분의 문자만 계속 달라지는것을 볼 수 있다.
- 클래스로 생성한 객체가 준비작업을 하고 응답을 해준다.
그때그때 다른 내용을 로딩하는 로직을 넣어준 것. (fortunes[ranNum])
** 같은 내용을 .jsp 로 만들어보기
- jsp 파일 생성! jsp : java server page
<fortune.jsp>
<%@page import="java.util.Random"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/fortune.jsp</title>
</head>
<body>
<%
//오늘의 운세 5개를 미리 준비해 둔다.
String[] fortunes={"동쪽으로 가면 귀인을 만나요",
"오늘은 집에만 계세요",
"너무 멀리가지 마세요",
"오늘은 뭘해도 되는 날이에요",
"로또가 당첨돼요"};
Random ran=new Random();
//0~4 사이의 랜덤한 정수 얻어내기
int ranNum=ran.nextInt(5);
%>
<p>오늘의 운세: <%=fortunes[ranNum]%></p>
<p>오늘의 운세: <%out.print(fortunes[ranNum]); %></p>
</body>
</html>
- 여기서는 또 emmet이 작동하지 않는데, window-preference 들어가면 jsp에서도 작동하도록 설정할 수 있다.
- Emmet에 들어가면 emmet이 작동할 파일 확장자들이 들어있는 칸이 있는데, 여기에 .jsp 를 입력해주면 된다.
- <% %> 으로 처리된 맨 위의 한줄은 안 보이고, 나머지는 html servlet 파일과 같다.
<% %> : 자바 코딩을 할수있는 공간을 만들어준다. 이 <> 안은 java 문법의 영역!
- 이전에 작성한 java 내용을 가져오고, 필요한 부분은 import 해준다.
- <%@ @> 형태로 특이하게 import 되는것을 볼수있음
<p>오늘의 운세: <%=fortunes[ranNum] %> </p> 로 넣어준다.
- servlet과 동일하게 작동한다. jsp의 내용도 그대로 클라이언트한테 온다.
- Servlet은 여러 로직을 섞을 수 있지만 html 작성이 너무 번거롭다.
- jsp는 상대적으로 java 문법으로 코딩하기도 쉽고 사용이 간편하다.
<% %> 의 작성법을 배우는것이 jsp, 서버 프로그래밍을 배우는 것이다.
- jsp는 대체 뭐지? html도 아니고 java class도 아니고...
→ 모양은 이렇지만, java class로 바뀌어 작동하는 것이다.
\web_work\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\Step01_Servlet\org\apache\jsp
- 탐색기에서 위 경로로 들어가보면 두개의 파일이 있다.
- fortune.jsp 파일만 만들었는데 fortune_jsp.java 라는 java class 파일이 자동으로 생성된 것이 보인다.
- 클래스로 바뀌었을 때 어떤 모양을 가지는지 확인하기!
- fortune_jsp.java 파일을 열어서 비교해본 것! java 문법으로 쓰여진 일반 클래스이다.
- 이 클래스에서 상속하고 있는 HttpJspBase 는 HttpServlet과 비슷한 것이다.
- jsp로 만든 페이지도 결국 servlet역할으로 변환된다는 의미이다.
- 생성자와 필드가 있다.
- _jspService 메소드는 servlet의 service() 메소드와 비슷하다.
- 더 아래로 내려보면 jsp에서 작성한 내용을 servlet 으로 만든것과 동일하게 변환해놓은 것을 볼 수 있다!
- out 은 jsp 에서의 출력 객체. printwriter 역할을 한다.
- <% %>에 작성한 코드는 고스란히 클래스 안으로 옮겨진다.
- 그렇기 때문에 java 문법에 맞추어 작성해야 하는 것!
- <%= %> 은 더 변환되지 않고 클라이언트한테 그대로 출력된다.
1) <p>오늘의 운세: <%=fortunes[ranNum]%></p>
2) <p>오늘의 운세: <%out.print(fortunes[ranNum]); %></p>
- out.print를 넣어 이렇게 작성할 수도 있는데, 당연히 1번이 더 편하다...
- 클래스에서 열어보면 위와 같은 차이가 있다. 결과적으로는 같다!
- 딱 어떤 위치에 어떤 값(참조값)을 출력해주고 싶을 때 <%= 이라는 문법을 사용한다.
- 이렇게 클래스파일과 비교하면서 학습하면 jsp파일에 대한 이해도가 높아진다.
- 자동완성 앞의 작은 원형 L은 로컬 변수를 가리킨다.
- jsp페이지 영역의 <% %> 이 영역 안에서 그냥 . 찍어서 호출해 사용할 수 있는 객체들이 있다.
- 8개의 기본 객체가 들어있다. 웹프로그래밍 하는데에 필요한 객체들이 편한 개발을 위해 기본으로 들어있다.
- servlet 안에서는 req, resp라고 정의된 변수밖에 사용할 수 없는데,
jsp에는 8개의 미리 정의된 변수를 사용할 수 있다.
** 친구 목록 추가하기
- 연결되는 페이지가 404가 아니게 하려면 무엇을 만들어야하는가? : Servlet
(jsp 파일은 경로의 끝이 .jsp가 되어야 한다.)
- /friend/list 로 된 Servlet을 만들면 된다!
<FriendServlet> 클래스 생성
package test.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/friends/list")
public class FriendServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//친구목록 (sample data)
List<String> names=new ArrayList<>();
names.add("바나나");
names.add("딸기");
names.add("복숭아");
//응답 인코딩 설정
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>");
//names에 들어있는 친구 목록을 활용해서 친구 목록을 출력해 보세요.(ul, li 요소 활용)
pw.println("<ul>");
for(String tmp:names) {
pw.println("<li>"+tmp+"</li>");
}
//for(i=0, i<names.size();, i++){
//pw.println("<li>"+names.get(i)+"</li>")}
pw.println("</ul>");
pw.println("</body>");
pw.println("</html>");
pw.close();//닫아주기
}
}
- <> 제너릭타입을 확인한 뒤 확장 for문으로 돌면서 list를 출력해 준다.
- 출력하면서 <li> 요소 안에 넣어주기!
for(타입종류 변수명:배열명){ }
같은 내용 jsp 파일로 만들기
<list.jsp>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//친구목록 (sample data)
List<String> names=new ArrayList<>();
names.add("바나나");
names.add("딸기");
names.add("복숭아");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/friend/list.jsp</title>
</head>
<body>
<ul>
<%
for(String tmp:names){
out.println("<li>"+tmp+"</li>");
}
%>
</ul>
<ul>
<% for(String tmp:names){ %>
<li><%=tmp %></li>
<%} %>
</ul>
</body>
</html>
- /friends/list.jsp 이라면 friends 폴더를 만들고 그 안에 list.jsp파일 만들어주기!
- jsp는 해당 경로에 물리적으로 위치시켜주면 된다.
- 작성한 HTML 요소들은 out.write 로 출력된다.
- <% %> 안에 있는 내용은 그대로 옮겨준다.
- 개행, 공백기호도 인식되어 그대로 출력된다.
- 분리한 내용도 각각 나누어져서 출력됨!
- <%= tmp 도 그대로 그 자리에 출력된다.(out.print로 바뀌어서)
- jsp 페이지로 만든 홈페이지는 홈페이지 주소에서도 발견된다.
- 웹페이지에 업로드되는 내용이 기본 틀은 같지만 상세내용은 조금씩 달라지기 때문에,
DB에서 읽어와 정보를 수정할 수 있도록 jsp 페이지로 만드는 경우가 많다.
참고) eclipse 템플릿 만들기
- Windows-Preferences-Templates-New에서 저장해두면
- 작성할 때 저장한 템플릿의 이름만 입력하면 템플릿을 불러와 쓸 수 있다.
'국비교육(22-23)' 카테고리의 다른 글
27일차(2)/jsp(4) : servlet, jsp 비교 (0) | 2022.11.15 |
---|---|
27일차(1)/jsp(3) : servlet, jsp 비교 (table, form) (0) | 2022.11.15 |
26일차(1)/jsp(1) : Eclipse Server, Emmet 설정 등 (0) | 2022.11.13 |
25일차(3)/CSS(5) : Bootstrap, Form, Grid, Flex (1) | 2022.11.10 |
25일차(2)/CSS(4) : Text, CSS가중치, Unit 외 (0) | 2022.11.09 |