본문 바로가기
강의/웹 프로그래밍(풀스택)

부스트코스 웹 프로그래밍(풀스택) - 1. 웹 프로그래밍 기초 - 5-2-2 강의 정리

by 리드민 2022. 4. 13.
반응형

[1] 강의

웹 프로그래밍(풀스택)

5. Servlet - BE

2) Servlet 작성 방법-2

 

[2] 개념 정리

HttpServlet : HttpServlet 클래스에서 사용자 요청을 처리하는 doGet/doPost 메서드는 모두 HttpServletRequest와 HttpServletResponse 객체를 매개변수로 가지고 있다. HttpServletRequest와 HttpServletResponse 객체는 서블릿과 클라이언트 사이를 연결해주는 중요한 객체들이다.

web.xml : web application의 설정을 위한 deployment descriptor(배포 설명자) 로서 XML 형식의 파일 모든 Web application은 반드시 하나의 web.xml 파일을 가져야되고 위치는 WEB-INF 폴더 아래에 있다.

 

[3] 강의 정리

  Servlet 3.0 이상에서 사용하는 방법부터 실습을 통해서 알아보도록 하겠다. 이번 실습을 진행할 거냐면 일단은 Servlet 3.1 spec으로 exam 31이라는 프로젝트를 하나 생상할 거다. 해당 프로젝트에 1부터 10까지 출력하는 TenServlet을 작성할 거다. 그리고 실제 요청할 때는 이런 주소를 가지고 동작하도록 설정을 하려고 한다. 이클립스를 실행시키고 exam31이라는 프로젝트 먼저 생성을 해야한다. File에 New, Dynamic Web Project 선택하고. 프로젝트 이름은 exam31 이렇게 지정하면 된다. 이때 눈여겨볼 부분은 Dynamic web module version이라는 부분이다. 이렇게 선택해보면 2.X 하고 되어 있는 부분이 있다. 3.X 버전이 존재하고 있는 거 보이나? 그중에 우리는 기본으로 되어있는 3.1을 선택해서 진행을 해보자. Next 하시고. 다음에 또 살짝 눈여겨보면 소스 폴더는 src다. 라고 되어있는 걸 볼 수 있다. output folder가 build라는 디렉토리 밑에 classes라는 디렉토리로 지정이 되어있는 걸 볼 수 있다.

  지난 시간에 웹 애플리케이션을 만들고 Servlet 3.0 이상에서 사용하는 방법부터 실습을 통해서 알아보도록 하겠다. 이번 실습을 진행할 거냐면 일단은 Servlet 3.1 spec으로 exam 31이라는 프로젝트를 하나 생상할 거다. 해당 프로젝트에 1부터 10까지 출력하는 TenServlet을 작성할 거다. 그리고 실제 요청할 때는 이런 주소를 가지고 동작하도록 설정을 하려고 한다. 이클립스를 실행시키고 exam31이라는 프로젝트 먼저 생성을 해야한다. File에 New, Dynamic Web Project 선택하고. 프로젝트 이름은 exam31 이렇게 지정하면 된다. 이때 눈여겨볼 부분은 Dynamic web module version이라는 부분이다. 이렇게 선택해보면 2.X 하고 되어 있는 부분이 있다. 3.X 버전이 존재하고 있는 거 보이나? 그중에 우리는 기본으로 되어있는 3.1을 선택해서 진행을 해보자. Next 하시고. 다음에 또 살짝 눈여겨보면 소스 폴더는 src다라고 되어있는 걸 볼 수 있다.

  output folder가 build라는 디렉토리 밑에 classes라는 디렉토리로 지정이 되어있는 걸 볼 수 있다. 지난 시간에 웹 애플리케이션을 만들고 cmd 창에서 tree /f라는 명령어로 디렉토리 구조들 살펴봤을 때. build라는 디렉토리에 classes라는 디렉토리가 만들어져 있었던 거 기억할 거다. 이클립스에서는 해당 디렉토리가 보이지는 않지만, 서블릿이 컴파일되면 이 컴파일된 클래스 파일은 이 디렉토리 안에 들어온다. 이렇게 지정이 되어 있었던 부분이다. 다음 Next하면 Context root라는 부분이 exam31이라고 되어 있는 거 확인할 수 있는 거다. 이 부분이 이렇게 설정이 되어 있기 때문에 여러분들이 나중에 URL이 요청할 때 이 exam31이라는 URL이 들어가게 되어 있다. 이 부분들도 나중에 이런 부분들이 이렇게 된다고 알 수 있는 부분이다. 그 다음에 하나 보면 web.xml 파일을 자동으로 만들까 이런 부분이 선택이 되어있다.

  2점대 버전과 3점대 버전의 가장 큰 차이점은 서블릿을 web.xml 파일에다가 직접 등록을 하느냐 아니면 어노테이션 방법을 이용해서 하느나 이 차이다. 3점대는 어노테이션 방법을 이용한다고 했었다. 그래서 web.xml이 필수는 아니다. 그런데 나중에 스프링이라던가 이런 것들을 사용하게 될 때는 서블릿을 3점대로 만들었다 하더라도 다른 설정 부분을 web.xml에 추가해야 할 필요가 있기 때문에 그대는 반드시 web.xml을 생성하게 체크를 해줘야지 진행하는데 크게 무리가 없다. 여기까지 보고 Finish, 한번 해보자. 그러면 웹 exam31이라는 프로젝트가 하나 만들어져 있는 것을 볼 수가 있을 것이다. 여기에 서블릿을 하나 만들면 된다. 자, Servlet Java package는 그냥 exam 하고 준다. Class 이름은 TenServlet 작성하면 된다. Next 하고. URL mappings라고 되어 있는 부분. 기억나나? 이부분이 실제 요청되는 URL 상에 가장 마지막 실제 이 TenServlet이라는 서블릿 파일을 요청할 때 나는 이 이름으로 요청할게라는 걸 지정한 부분이다.근데 우리 아까 실습에서는 이 부분을 ten이라고 요청하기로 했다. 그래서 이 부분을 Edit 하셔가지고 ten 하고 수정해보자. 이렇게 바뀌었다, 그런 다음에 Next. 이때도 메서드, doGet() 메서드만 있으면 된다.

  Finish, 그럼 이런 파일이 하나 생겼다. 그럼 이번에는 이 doGet() 메서드 안에다가 1부터 10까지 출력할 수 있는 코드를 넣어주면 된다. HelloServlet을 출력했었던 코드를 잠깐 되짚어서 생각하면 좋을 거 같다. 이 서블릿은 동적으로 응답 결과를 만들어내는 것이라고 했었던거 기억나는가? 동적으로 만들어낸다는 것은 이미 응답할 페이지를 만들어서 가지고 있는 게 아니라 요청이 들어 왔을 때 이 프로그램이 실행되면서 다시 이야기 하면 ten이라고 요청을 하면 이 서블릿이 실행이 되면서 응답할 코드를 만들어 내고 그때 그 코드로 응답을 하게 된다. 이런 부분들이 계속 수행을 하다 보면 이해가 될 거 같다. 일단은 이 코드 내에서는 내가 응답하고 싶은 내용이 나오게 만들어 주면 된다. HTTP 프로토콜 설명하면서 요청, 응답 이런 단어들 계속 들었을 텐데.

  클라이언트가 요청하면 서버는 응답해요라고 이야기했었다. 이때 클라이언트가 요청할 때 서버는 요청을 받아내는 객체와 응답을 하기 위한 객체 두 개를 자동으로 만들어냈다. 요청에 대한 정보들은 모두 이 객체 안에 추상화시켜 가지고 있다. 응답에 대한 부분들은 이 객체 안에 가지고 있는 거다. 그러니까 응답으로 뭔가 돌려줘야 했을 때는 반드시 이 객체에다가 내용들을 넣어줘야 되는 거다. 그러면 응답으로 1부터 10까지 출력해보고 싶다고 했기 때문에. 일단은 이 response라는 객체에다가 나 응답을 할 거에요 해줘야 한다. 그런데 클라이언트(브라우저)가 응답을 받았을 때 누군지 알아야 한다. 얘가 이미지인지 동영상인지 이것을 알아내야 되기 때문에 알려줘야 한다. 이것을 알려주는 메서드가 setContentType()이다. 그래야 브라우저가 응답을 받았을 때 이거 뭐구나. 그러니 이거에 맞게 해석해서 알맞게 보여줘야지 이런 판단을 할 수 있다. 그러니까 응답 결과에다가 나는 이런 타입으로 보내줄게 라는 약속을 여기다가 넣어주는거다. text로 보낼거다.

  이 text는 html이라는 부분을 작성해 준거다. 이리고 하나 더 추가하면 좋을 게 charset이라는 거 추가해주면 좋다고 얘기 했던거 기억하는가? 이때 charset이 클라이언트와 서버에서 보내주는 정보와 서로 맞지 않으면 한국 사람과 스페인 사람이 만났는데 이야기를 하려고 했더니 안 맞는다. 이런거랑 비슷하다고 생각하면 된다. 해석하는거, 나는 이 charater를 utf-8이라는 방식으로 보낼 거야. 이런 부분이라고 생각하면 좋을 거 같다. 그러면 나는 응답을 이걸로 보낼 거야라고 약속했고. 그 다음에 진짜 보낼 내용을 넣어줘야겠지. 그런데 아무데나 막넣는게 아니라 일단은 그 보낼 내용을 넣어줄 통로를 하나 얻어내야 한다. 그래서 이 response라는 객체에 어떤 메서드가 있나면 getWriter()라고 하는 메서드가 존재한다. 이 getWriter()라는 메서드를 수행하면 어떤 객체를 return 받을 수 있냐면 여기 PrintWriter라는 객체가 return 되는 것을 볼 수 있을 거다. 이 객체 PriterWriter를 return 받을 수 있으니까 이 response가 가진 getWriter()를 수행해서 PrintWriter 객체를 하나 얻어오는 거다. 변수명은 아무거나 지정해도 상관없다. 필자는 out이라고 지정했다. 이제는 통로가 마련됐으니 이제부터는 out이라는 통로에다가 출력해주면 된다. 출력하는 메서드는 print() 쓰면 된다. println()을 쓸지 고민하지 않아도 된다. HTML을 해본 사람은 알겠지만 HTML 파일에다가 아무리 Enter를 쳐봐야 줄이 안 바뀐다. 반드시 br이라는 태그를 써야지만 줄을 바꾼다. 그렇기 때문에 제가 여기에다 쓸 때 Enter를 쓰든 안쓰든 어쨌든 똑같은 거니까 아무거나 사용해도 괜찮다.

  여기에 출력하고 싶은 내용을 써주면 되는데 나는 일단 타이틀을 1-10까지 출력!! 이렇게 하나 해주고 싶다. 그런데 글자가 너무 조그맣게 보이면 재미없을 거 같아서 조금 글자를 크게 보이게 할 수 있도록 h1이라는 태그를 넣어주었다. 그럼 진짜로 1부터 10까지 출력해야겠다. 서블릿은 자바랑 똑같다. 1부터 10까지 출력하는 코드 만들어낼 수 있죠? out.print() 해서 1, 2, 3, 4 이렇게 출력할 건 아니죠? 반복문이라는 걸 우리는 알고 있으니까 반복문을 이용해서 출력을 해보자. 여기에다가 i는 1부터 10까지 하나씩 증가한다. 이걸 어디서 출력할 거냐면 아까 응답 결과 out에다가 print() 하시는데 뭐를, I를 print() 하면 좋을 거 같다. 근데 또 아까 무슨 얘기했었냐하면 나는 1 출력하고 바꾸고 2 출력하고 이렇게 하고 싶다. 근데 여기에서는 내가 println() 이렇게 해봐야 어쨌든 줄은 안 바뀌니까 반드시 br이라는 태그를 넣어줘야지만 줄이 바뀐다. 그래서 이렇게 줄이 바뀔 수 있도록 완성을 해준다. out 객체는 다 사용했으니까 close() 해보자. 저장을 하고, 반드시 저장해야지 들어가겠죠? 실행해보자. 여기 Java Resources에 src에 exam이라는 폴더가 만들어졌을 거고. 이 패키지 안에 생성된 TenServlet을 Run As, Run on Server해서 실행을 시켜볼 거다. Next, Finish 하고 실행을 시켜본다. 서버가 시작이 됐다. 이렇게 브라우저에 1-10까지 출력!! 이러면서 1, 2, 3, 4, 5, 6, 7, 8, 9, 10이 출력이 되고 있는 걸 볼 수 있다. 이렇게 여러분들이 서블릿 버전, 지금 3.1를 이용해서 출력을 하고 있다.

  다시 이클립스 화면으로 돌아가서 잠깐 눈여겨보는데, 뭘 보냐면 이분이다. 어노테이션으로 @WebServlet 이라는 것이 만들어져있다. 이때 ten이라고 들어있는 것을 확인할 수 있다. 나는 ten이라는 URL이 마음에 안 든다. 그러면 난 이렇게 ttt라고 바꾸고 싶다. 만약에 그렇다면 수정하고 다시 한번 실행시켜 보자. 이렇게 실행됐을 때 이 URL 부분을 눈여겨서 보면 아까 ten이라고 되어 있었던 부분이 ttt하고 바뀌어 있는 것을 보실 수 있으실 거다. 나온 내용은 똑같다. 똑같이 TenServlet이 실행되는데 이 URL mapping이 뭐냐에 따라서 요청하는 주솟값이 달라지는 거다. 여기에 아까 지정했었던 ten 이렇게 요청해보자. 그랬더니 뭐라고 나오나? 나 그런 페이지 모르는데 하고 나오는 걸 볼 수 있을거다. 여기까지 웹 버전 3.0 이상에서 서블릿을 작성하는 방법을 살펴봤다.

 

 

[4] 코드 정리

package examples;

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 TenServlet
 */
@WebServlet("/ten")
public class TenServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TenServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<h1>1부터 10까지 출력합니다.<h1>");
		for(int i = 1; i<=10; i++) {
			out.print(i+"<br>");
		}
		out.close();
	}

}
반응형