본문 바로가기
Back End/Spring

[Spring] 서블릿(servlet) aka. MVC 구버전

by SolaKim 2023. 8. 3.

서블릿은 자바 언어를 기바능로 웹 애플리케이션을 개발하는데 사용되는 기술이다.

웹 서버에서 동작하는 자바 클래스로, 클라이언트의 요청을 받아 처리하고 그 결과를 다시 클라이언트에게 전송하는 역할을 수행한다.

 

@WebServlet : 서블릿 애노테이션

  • name : 서블릿 이름
  • urlPatterns : URL 매핑
  • 예 ) @WebServlet(name = "helloServlet", urlPatterns = "/hello")
  • HTTP요청을 통해 매핑된 URL이 호출되면 서블릿 컨테이너는 다음 메서드를 실행한다.
    • protected void service(HttpServletRequest request, HttpServletResponse response)

 

HttpServletRequest 역할

  • HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱한다. 그리고 그 결과를 HttpServletRequest 객체에 담아서 제공한다.
  • 해당 HTTP 요청이 시작부터 끝날때까지 유지되는 임시 저장소 기능이 있다.
    • 저장 : request.setAttribute(name, value)
    • 조회 : request.getAttribute(name)
중요 ⭐️
HttpServletRequest, HttpServletResponse를 사용할 때 가장 중요한 점은 이 객체들이 HTTP 요청메시지, HTTP 응답 메시지를 편리하게 사용하도록 도와주는 객체라는 점이다. 

 

 

 

HTTP 요청 데이터

 

GET - 쿼리 파라미터

 

쿼리 파라미터는 URL에 다음과 같이 ? 를 시작으로 보낼 수 있다. 추가 파라미터는 & 로 구분하면 된다.

http://localhost:8080/request-param?username=hello&age=20

서버에서는 HttpServletRequest 가 제공하는 다음 메서드를 통해 쿼리 파라미터를 편리하게 조회할 수 있다.

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

 

복수 파라미터에서 단일 파라미터 조회

username=hello&username=kim 과 같이 파라미터 이름은 하나인데, 값이 중복이면 어떻게 될까?

request.getParameter() 는 하나의 파라미터 이름에 대해서 단 하나의 값만 있을 때 사용해야 한다.

지금처럼 중복일 때는 request.getParameterValues() 를 사용해야 한다.

참고로 이렇게 중복일 때 request.getParameter() 를 사용하면 request.getParameterValues() 첫 번째 값을 반환한다.

 


POST - HTML Form

 

이번에는 HTML의 Form을 사용해서 클라이언트에서 서버로 데이터를 전송해보자.

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

  • 특징
  •  content-type: application/x-www-form-urlencoded 
  • 메시지 바디에 쿼리 파리미터 형식으로 데이터를 전달한다. username=hello&age=20
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
    <form action="/request-param" method="post">
    username: <input type="text" name="username" />
    age: <input type="text" name="age" />
    <button type="submit">전송</button>
    </form>
</body>
</html>
application/x-www-form-urlencoded 형식은 앞서 GET에서 살펴본 쿼리 파라미터 형식과 같다. 따라서 쿼리 파라미터 조회 메서드를 그대로 사용하면 된다. 
클라이언트(웹 브라우저) 입장에서는 두 방식에 차이가 있지만, 서버 입장에서는 둘의 형식이 동일하므로, request.getParameter() 로 편리하게 구분없이 조회할 수 있다. 

정리하면 request.getParameter() 는 GET URL 쿼리 파라미터 형식도 지원하고, POST HTML Form 형식도 둘 다 지원한다.

 

HTTP message body - API 메시지 바디

  • HTTP message body에 데이터를 직접 담아서 요청
    • HTTP API에서 주로 사용, JSON, XML, TEXT
    • 데이터 형식은 주로 JSON 사용
    • POST, PUT, PATCH
  • HTTP 메시지 바디의 데이터를 InputStream을 사용해서 직접 읽을 수 있다.
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
참고 !! 
inputStream은 byte 코드를 반환한다. byte 코드를 우리가 읽을 수 있는 문자(String)로 보려면 문자표 (Charset)를 지정해주어야 한다. 여기서는 UTF_8 Charset을 지정해주었다.

 

json 같은 경우는 따로 파싱을 해줘야하는데,

public class HelloData {
    private String username;
    private int age;
}
private ObjectMapper objectMapper = new ObjectMapper();
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);

위와 같은 코드를 추가해서 파싱할 수 있다.