Home 서블릿
Post
Cancel

서블릿

서블릿 시작

스프링 부트 환경에서 서블릿을 등록하고 사용해본다.

참고

서블릿은 톰캣 같은 웹 애플리케이션 서버를 직접 설치하고 그 위에 서블릿 코드를 클래스 파일로 빌드해서 올린 후 톰캣 서버를 실행하면 된다. 이러한 과정은 번거롭기 때문에 스프링부트를 사용해 톰캣 서버를 설치없이 편리하게 서블릿 코드를 실행한다.

스프링부트 서블릿 환경 구성

스프링부트는 서블릿을 직접 등록해 사용할 수 있도록 @ServletComponentScan 을 지원한다.

/hello/servlet/basic/HelloServlet

위와 같이 @ServletComponetScan을 추가해주고 아래의 HelloServlet을 작성 후localhost:8080/hello 로 들어가면 service 함수가 실행된다.

요청 및 응답

1
2
3
4
5
6
7
8
@Ovcrride
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
	String username = request.getParameter("username");

	response.setContentType("text/plain");  
	response.setCharacterEncoding("utf-8");  
	response.getWriter().write("hello " + username);
}

이렇게 작성하고 URL에 localhost:8080/hello?username=kim 이런식으로 하면 파라미터를 받을 수 있다. (String username = kim)

response 객체를 이용하면 브라우저에 내용을 띄울 수 있다.

참고

logging.level.org.apache.coyote.http11=debug 를 application.properties에 추가하면 서버가 받는 HTTP 요청 메시지를 콘솔에서 볼 수 있다.

운영 서버에서 사용하면 성능 저하가 발생할 수 있기에 개발 단계에서만 사용하자.

편리한 학습을 위한 html

main -> webapp 디렉토리 생성 -> index.html 추가

이러한 화면을 만들고 서블릿 basic을 클릭하고 링크로 들어가게 되면

작성해 둔 basic.html은 이러한 구성이다. 예를 들어 hello 서블릿 호출은 href=”/hello?username=servlet” 으로 되어있어 위에서 작성한 request로 쿼리를 받고 response를 이용해 출력하는 부분을 쉽게 확인할 수 있다.

HttpServletRequest

HTTP 요청 메시지를 개발자가 직접 파싱해 사용해도 되지만 매우 불편하다. 서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신 HTTP 요청 메시지를 파싱한다.

그리고 그 결과를 HttpServletRequest 객체에 담아 제공한다.

1
2
3
4
5
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

username=kim&age=20

위와 같은 HTTP 요청 메시지를 편리하게 조회할 수 있다.

  • Start Line
    • HTTP 메서드
    • URL
    • 쿼리스트링
    • 스키마, 프로토콜
  • 헤더
    • 헤더 조회
  • 바디
    • form 파라미터 형식 조회
    • message body 데이터 직접 조회 (JSON)

HttpServletRequest 객체의 부가 기능

  • 임시 저장소 기능
    • 해당 HTTP 요청이 시작부터 끝날 때 까지 유지되는 임시 저장소 기능
      • 저장 : request.setAttribute(name, value)
      • 조회 : request.getAttribute(name)
  • 세션 관리 기능
    • request.getSession(create:true);

** HttpServlet 객체들은 역할이 HTTP 요청 메시지, 응답 메시지를 편리하게 사용하도록 도와주는 객체이다. 따라서 이 기능들에 대해 깊이있는 이해를 하기 위해서는 HTTP 스펙이 제공하는 요청, 응답 메시지 자체를 잘 이해해야 한다.

HttpServletRequest 사용 (start-line, header 정보 조회)

StartLine 조회

basic/request/RequestHeaderServlet

service 함수에서 위 함수를 호출해 실행하고 localhost:8080/request-header로 가면 아래와 같은 결과를 얻을 수 있다.

request 객체를 이용해 가져올 수 있는 헤더 정보를 알 수 있다. ?username=kim 을 추가한다면 getQueryString()은 username=kim이 나올 것이다.

헤더 조회

물론 이 헤더부분은 위의 application.properties에서 추가한 기능으로 볼 수도 있다.

이런식으로 조회할 수도 있다.

기타 조회

Local 정보는 나의 서버 정보이고, Remote 정보는 요청이 온 것에 대한 정보이다.

HTTP 요청 데이터

HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법을 학습한다.

주로 아래의 3가지 방법을 사용한다.

  • GET - 쿼리 파라미터
    • /url?username=hello&age=20
    • 메시지 바디 없이, URL의 쿼리파라미터에 데이터를 포함해 전달
    • ex) 검색 필터, 페이징 등에서 많이 사용하는 방식
  • POST - HTML Form
    • content-type: application/x-www-form-urlencoded
    • Form 내용을 메시지 바디에 쿼리 파라미터 형식으로 전달 username=hello&age=20
    • ex) 회원 가입, 상품 주문, HTML Form 사용
  • HTTP message body에 데이터를 직접 담아 요청
    • HTTP API에서 주로 사용. JSON, XML, TEXT
    • 데이터 형식은 주로 JSON 사용
    • POST, PUT, PATCH

GET 쿼리 파라미터

아래의 데이터를 클라이언트에서 서버로 전송해본다.

  • username = hello
  • age = 20

메시지 바디 없이 URL의 쿼리 파라미터를 사용해 데이터를 전달한다.

검색 필터나 페이징 등에서 많이 사용하는 방식이다.

파라미터는 ?를 시작으로 하고, 추가 파라미터는 &으로 구분지어진다.

쿼리 파라미터 조회 메서드

1
2
3
4
String username = request.getParameter("username") // 단일 파라미터 조회
Enumeration<String> parameterNames = request.getParameterNames(); // 파라미터 이름들 모두 조회
Map<String, String[]> parameterMap = request.getParameterMap(); //파라미터를 Map으로 조회
String[] usernames = request.getParameterValues("username"); //복수 파라미터 조회

파라미터가 ?username=kim&age=20&username=hong 같이 중복으로 보내지는 경우는 사실 거의 없다.

POST HTML Form

HTML의 Form을 사용해 클라이언트에서 서버로 데이터를 전송한다.

회원가입, 상품 주문 등에서 사용하는 방식이다.

  • content-type : application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달한다.
    • username=hello&age=20

위와 같은 HTML Form이 있고 전송 버튼을 누르면 Submit 되는 상황이다.

form action = “/request-param” method = “post” 이다.

submit이 되면 /request-param 으로 redirect 되고 해당 URL에 해당하는 함수를 호출하게 된다.

함수에 쿼리 파라미터 조회를 넣으면 정상적으로 조회가 되는 것을 볼 수 있다.

클라이언트 입장에서는 데이터를 전달하는 방식이 GET의 URL과 POST의 FORM으로 다르지만, 서버 입장에서는 둘의 형식이 동일하므로 request.getParameter() 메서드로 편리하게 구분없이 조회 가능하다.

API 메시지 바디

HTTP message body에 데이터를 직접 담아서 요청한다.

  • HTTP API에서 주로 사용한다. JSON, XML, TEXT
  • 데이터 형식은 주로 JSON.
  • POST, PUT, PATCH

단순 텍스트

먼저 가장 단순한 텍스트 메시지를 HTTP 메시지에 담아 전송하고 읽어본다. HTTP 메시지 바디의 데이터를 InputStream을 사용해 직접 읽을 수 있다.

messageBody에 일반 TEXT로 hello를 보내면 hello가 전송된다.

request.getInputStream() 으로 데이터를 읽을 수 있고 이 데이터를 String으로 바꾸기 위해 StreamUtils.copyToString() 을 사용한다.

JSON 형식

  • POST http://localhost:8080/request-body-json
  • content-type: application/json
  • message body: [“username: “hello”, “age” : 20]

우선 JSON 형식ㅇ로 파싱할 수 있도록 객체를 하나 생성한다.

위 처럼 그냥 가져오게 되면 JSON 형식 그대로 가져오게 된다.

위와 같이 ObjectMapper를 사용해 HelloData 객체를 통하여 각각의 Value를 가져올 수 있다.

** JSON 결과를 파싱해서 사용할 수 있는 자바 객체로 변환하려면 Jackson, Gson 같은 JSON 변환 라이브러리를 추가해 사용해야 한다. 스프링 부트로 Spring MVC를 선택하면 기본으로 Jackson 라이브러리 ‘ObjectMapper’를 함께 제공한다.

** HTML Form 데이터도 메시지 바디를 통해 전송되므로 직접 읽을 수 있다. 하지만 편리한 파라미터 조회 기능 (request.getParameter) 을 제공하기 때문에 파라미터 조회 기능을 사용하면 된다.

HttpServletResponse

HTTP 응답 메시지를 생성하는 역할을 한다.

  • HTTP 응답 메시지 생성
    • HTTP 응답 코드 지정
    • 헤더 생성
    • 바디 생성
  • 편의 기능 제공
    • Content-type
    • 쿠키
    • Redirect

HttpServeletResponse 기본 사용

setStatus를 이용해 HTTP 응답 코드를 지정하며 setHeader를 통해 응답 헤더 정보들을 설정할 수 있다.

메시지 바디는 writer를 이용해 작성하게 된다.

Content 편의 메서드

writer.println(“ok”) 라 자동생성되면 length는 2여야 하는데 3으로 나온다. 이유는 println이라 Enter가 들어갔기 때문.

쿠키 편의 메서드

주석처럼 setHeader로 할 수도 있지만 쿠키 객체를 이용한 아래가 더 깔끔하다.

redirect 편의 메서드

주석처럼 status 코드를 따로 setStatus 해주지 않아도 sendRedirect()를 이용하면 302로 설정된다.

HTTP 응답 데이터

HTTP 응답 메시지는 주로 아래의 내용을 담아 전달한다.

  • 단순 텍스트 응답
    • writer.println(“ok”);
  • HTML 응답
  • HTTP API - MessageBody JSON 응답

HTML 응답

writer로 직접 쓴 html을 보내게 된다. 브라우저에서 보면 안녕? 만 뜨게 된다.

자바코드이기 때문에 HTML 구조이지만 if문 등을 써서 보낼 수도 있다.

API JSON 응답

위에서 사용했던 HelloData 객체를 이용해 JSON 형태의 메시지를 응답할 수 있다. objectMapper는 객체를 JSON 문자로 변경하기 위한 것이다.

위의 코드를 실행하면 JSON 형태로 브라우저에 보여지게 된다.

This post is licensed under CC BY 4.0 by the author.