0507 | Servlet&Jsp (1) // WAS/servlet/톰캣 개념, URL매핑, 응답시 서블릿 출력형식
[1] servlet & jsp 의 학습목표
자바프로그램 > (+서블릿. HTML코드 출력문제) > 자바웹프로그램 > (+JSP.스파게티 코드문제) > JSP MVC > SPRING MVC
[2] 웹서버프로그램과 servlet
✔ 기존문제점
: 클라이언트 - 서버 프로그램의 동기화 문제 - 클라이언트 서버 업데이트의 어려움 & 자료전송문제 (소켓, RPC...)
✔ 해결
: 웹은 이미 전송이 가능한 환경을 가질 수 있으며 서버도 바로 반응 가능 ▶ 서버프로그램에 웹 HTTP 프로그램을 얹을 구상을 하게 됨 (Get request & Response)
: 클라이언트가 HTTP를 통해 REQUEST ▶ 웹서버가 받아서 코드 찾기 ▶ WAS를 통해 DB에서 출력 ▶ 다시 웹서버에 얹어서 RESPONSE
1-1) WAS (WEB APPLICATION SERVER)
: 클라이언트 요청에 따라 웹서버에서 찾아낸 코드를 실행하여 DB에서 자료를 뽑아와야하는데, 이때 코드를 실행할 수 있는 환경
1-2) SERVER APP (SERVER APPLICATION)
: 웹서버가 요청을 받아 해당 코드를 찾는 곳이자 동적으로 문서를 만들기 위한 코드들이 모인 곳. 이 코드를 가지고 DB로 간다.
1-3) 서버환경의 구성
: 실행환경 WEB SERVER + WAS
1-4 서버 응용 프로그램 Servlet
: Server Application let(조각). server application 내부에 있는 각각의 파편화된 코드를 지칭.
: 기존에 만들어둔 어플리케이션을 서블릿단위로 만든다 = 앞으로 할 학습 목표
: 서블릿을 만들기 위한 환경 구축 - 톰캣??
[3] 톰캣
3-1) 톰캣이란?
: 톰캣 = WAS + 웹서비스 기능 포함으로 웹서버로 볼 수도 있다 (웹문서 서비스 제공)
: 톰캣 설치후 start.bat 파일이 떠있지 않을땐 ① 환경변수에 java home-jkd등록하기 ② 기존 톰캣이 동작중이라 포트번호가 충돌나는 경우가 있음
: start.bat 파일 실행 후 브라우저에 http://localhost:8080/ 로 접속해서 톰캣 화면이 뜨면 작동확인 완료.
3-2) 톰캣 작동원리 파악하기
: apache-tomcat-9.0.74\webapps\ROOT - 톰캣의 홈디렉토리 (웹문서를 보관하는 곳)에 test.txt파일 저장 > 웹에서 http://localhost:8080/test.text > 해당 파일을 다른 서버를 통해 조회 가능
: 즉, 웹서버는 예약되어있는 특정 폴더가 있고, 해당 폴더에 문서를 저장후, 다른 원격에 있는 컴퓨터의 브라우저를 통해서 리소스 입력시 반환받을 수 있다.
3-3) context 사이트 추가
http: // IP : Port / context / 리소스들
: context란 파일이 저장된 디렉토리. 가상경로, 가상사이트 모두 동일한 지칭.
: 하지만 톰캣의 기본 root 안에 수많은 디렉토리를 다 담아서 작업할 수는없으므로, 디렉토리마다 떼어내서 별개로 만들어 연결. (물리적으론 별개의 사이트지만 기존의 root와 엮어서 서비스)
: 둘을 엮기 위해 apache-tomcat-9.0.74\conf- server.xml에서 설정을 해준다
<Context path="it" docBase="(중략)apache-tomcat-9.0.74\webapps\ITWebRoot(별개 사이트의 전체 경로복사)" priviledged="true"/>
👉 가상디렉토리 it와 실제 디렉토리 ITWebRoot와 연결 해서 서비스하라는뜻
👉 http://localhost:8080/it/news.txt 로 접속해도 ITWebRoot/news.txt로 조회한것 처럼 나온다
👉 실제로는 이렇게 추가한 뒤에 서버를 껐다 켤 수는 없으므로 다른 방법으로 연결하는데 그건 추후에. 일단은 context의 개념을 파악할 것!
[4] Servlet
4-1) WAS & servlet
: WAS는 HttpServlet 가 구현되어있고(정해져있는 서비스함수) 각 클래스코드 실행시 public class (클래스명) extends HttpServlet로, 상속받아 구현하게 된다.
public class Study extends HttpServlet{ // 이때 서블릿은 클래스명을 따라서 Study서블릿임
public void service (HttpServletRequest request, HttpServletResponse response){
// HttpServlet, service 모두 WAS와 연결된, 약속되어있는 서비스함수
System.out.println("hello");
}
}
4-2) 톰캣으로 서블릿 코드가 실행되도록 하는 코드배치
ROOT/WEB-INF > Classes > Study.class // 만약 패키지가 있었다면 패키지까지 폴더를 만들어서 class파일을 넣어야 한다
: 웹인포 폴더 안은 클라이언트에 의해 요청될 수 있는 디렉토리가 아님. 서버쪽(톰캣, WAS) 에서만 사용가능하다.
* ROOT안에 있는 파일은 클라이언트에서 조회가능하지만, WEB-INF로 들어간 파일은 조회 불가. 비공개의 영역!
따라서
: 클라이언트는 URL과 매핑된 코드(hello) 로 요청- http://localhost/hello - 서버는 해당 코드와 연결된 서블릿 코드 Study를 실행
// web.xml 내부 매핑
<servlet>
<servlet-name>na</servlet-name>
<servlet-class>Nana</servlet-class>
//<servlet-class>com.newlecturepre.web.Nana</servlet-class> 패키지명을 다 붙인경우
</servlet>
<servlet-mapping>
<servlet-name>na</servlet-name>
<url-pattern>/hello</url-pattern> // Nana라는 이름을 hello로 작동되도록 매핑해준다
</servlet-mapping>
👉 http://localhost/hello로 작동시 응답값 반환. 아직은 콘솔창 출력 println이므로 톰캣 화면에 결과값이 나타난다
4-3) Response로 클라이언트에게 응답값 보내기
✔ 기존 자바 프로그램과 서블릿 프로그램에서 달라지는 부분
: 원격으로 입출력이 오가게된다
자바 UI [콘솔/웹-클라이언트 등 외부요소 추가/윈도우 등 사용자 입출력] 프로그래밍
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Nana extends HttpServlet{
public void service(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException{
OutputStream os = response.getOutputStream();
PrintStream out = new PrintStream(os,true);
/*다국어문자를 띄울경우는 스트림계열이 아닌 writer계열사용.
PrintWriter out = response.getWriter();
out.println("hello today's servlet!!");
}
}
* 코드수정시 거쳐야 할 절차
① 코드수정
② 컴파일
③ 배포 (해당 폴더로 파일 옮김)
④ 톰캣 서버 재시작 - 수정된 내용 인식
⑤ 브라우저에서 요청
👉 프로젝트관리 + 코드편집도구 : 코드수정의 편리함
[5] 이클립스EE에서의 서블릿프로그래밍
5-1) 프로젝트 이름 노출 안되도록 하기 (컨텐트 변경)
: 주소에 프로젝트 이름이 그대로 노출이 되면 안되므로 프로젝트의 preference에서 이름 지정

5-2) 어노테이션을 이용한 URL 매핑
: 서블릿 2.X에서는 web.xml에서 매핑값을 설정해줘야했지만 3.0이상부터는 어노테이션으로 설정 가능해짐
: 단 web.xml에서 <web-app xmlns="" version ="3.X" metadata-complete="false"> 로 metadata가 true가 아닌 false값이어야 한다.

@WebServlet("/hi") // 매핑값
public class Nana extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println("hello today's servlet");
}
}
[6] 서블릿 출력 형식의 이해
: 브라우저에 컨텐츠 형식을 알려주지 않은 경우 브라우저마다 다르게 해석될 수 있다. (html로 해석 vs text로 해석)
6-1) 한글이 꺠지는 이유 두가지
(1) 서버에서 한글을 지원하지 않는 문자코드 (ISO-8859-1) 로 인코딩한 경우
(2) 서버에서는 utf-8로 인코딩해서 넘겼지만 브라우저가 다른 코드로 잘못 해석한 경우
@WebServlet("/hi") // 매핑값
public class Nana extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("UTF-8"); // 사용자에게 보내는 인코딩 방식. 이것만으론 컨텐츠에 제대로 반영이 안됨
resp.setContentType("text/html; charset=UTF-8");// 사용자가 어떻게 받아야 할지 컨텐츠 내에 인코딩을 심어주는 것
PrintWriter out = resp.getWriter();
for (int i = 0; i < 100; i++)
out.println((i + 1) + ":안녕 Servlet<br >");
}
}

