⚠️ Spring Boot 는 사실 서블릿과 관련이 없다. 그러나 Spring Boot 는 톰캣 서버를 내장하고 있기 때문에 별도의 서버 설치 없이 편리하게 서블릿 코드를 실행할 수 있다.
→ 따라서 실습은 Spring Boot 에서 실행하고자 한다.
💡 @ServletComponentScan
= 스프링에서 서블릿 서버를 쓰기 위함
서블릿을 사용하기 위해선
HttpServlet
을 상속받아야 한다.
💡 @WebServlet()
을 지정한다.
name = ""
: 서블릿 이름 (서블릿 이름은 겹치면 안된다.)urlPatterns = "url"
: url이 실행된다.@WebServlet()
public class HelloServlet extends HttpServlet {}
🎲 @Override
메소드 보기 : ctrl + o
→ protected
타입의 서비스 메소드를 호출한다.
💡 HttpServletRequest, HttpServletResponse 는
interface
로 정의되어 있다.
톰캣이나 Jetty 와 같은 WAS 서버들이 서블릿 표준 서버를 구현한다.
→ 이 구현체를 찍으면 다음과 같다.
쿼리파라미터 넘기기 = http://localhost:8080/hello?username=kim
💡 HTTP 에서 요청을 하면, 서버에 응답 메세지가 찍힌다.
request
, response
가 생성된다. request
, response
가 실행되고,HttpServletRequest
객체에 담아서 제공한다.💡 HttpServletRequest 객체는 추가로 여러가지 부가 기능도 함께 제공한다.
request.setAttribute(name, value)
request.getAttribute(name)
※ MVC Pattern 에서 많이 사용된다.
request.getSession(create: true)
🎲 변수 생성: ctrl + alt + v
→ QueryString 이 없기 때문에 null 값으로 출력된다.
💡 만약 쿼리를 지정했다면 다음과 같이 출력된다.
request.getHeaderNames()
: 헤더의 모든 정보를 출력할 수 있다.request.getLocales()
: 헤더의 Locales 의 모든 정보를 꺼내올 수 있다.request.getCookies()
: 쿠키 정보는 http header에 담긴다. request.getHeader()
: Header 딱 하나 만의 정보를 꺼낼 수 있다. 클라이언트에서 서버로 데이터를 전달하는 방법은 주로 다음과 같은 3가지 방법이 사용된다.
""
에 쿼리 파라미터를 작성하여 넘겨준다.username=hello&age=20
메시지 바디 없이, URL의 쿼리 파라미터를 사용해서 데이터를 전달하는 방식
💡 쿼리 파라미터는 URL에 다음과 같이 ?
를 시작으로 보낼 수 있다.
&
로 구분하면 된다.http://localhost:8080/request-param?username=hello&age=20
//paramName = 키(key) -> username, age
//request.getParameter = 값(value) -> hello, 20
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> System.out.println(paramName + " = " + request.getParameter(paramName)));
🤔 파라미터 이름은 하나인데, 값이 중복되면 어떻게 될까 ?
🅰️ request.getParameter()
는 하나의 파라미터에 대해서 단 하나의 값만 있을 때 사용해야 한다. 만약 중복일 때에는 request.getParameterValues()
를 사용해야 한다.
HTML 의 Form 을 사용해서 클라이언트에서 서버로 데이터를 전송하는 방식
💡 POST 의 HTML Form 을 전송하면 웹 브라우저는 다음 형식으로 HTTP 메시지를 만든다.
http://localhost:8080/request-param
application/x-www-form-urlencoded
username=hello&age=20
💡 application/x-www-form-urlencoded
형식은 앞서 GET 에서 살펴본 쿼리 파라미터 형식과 같다. → 따라서 쿼리 파라미터 조회 메서드를 그대로 사용하면 된다.
request.getParameter()
로 편리하게 구분없이 조회할 수 있다.✅ 정리하면
request.getParameter()
는 GET URL 쿼리 파라미터 형식도 지원하고 + POST HTML Form 형식도 지원하다.
💡 POST 는 content-type 을 필수로 지정해 줘야 한다.
🤔 그렇다면 테스트 할 때마다 Form 을 만들어야 하나 ? → No ! 우리에겐 Postman 이 있다.
x-www-form-urlencoded
선택application/x-www-form-urlencoded
로 지정된 부분 꼭 확인하기 !이제부터는 HTTP API 나 REST API 를 사용해서 HTTP 메시지 바디에 데이터를 직접 담아서 요청하는 형태로 진행해보자 !
inpustStream()
: 메시지 바디의 내용을 byte 코드로 반환한다.StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)
JSON 결과를 파싱해서 사용할 수 있는 자바 객체로 변환하려면 Jackson, Gson 과 같은 JSON 변환 라이브러리 를 추가해서 사용해야 한다.
스프링 부트로 Spring MVC 를 선택하면 기본으로 Jackson 라이브러리 (ObjcetMapper
) 를 제공한다.
⭐
response.setHeader();
로 직접 헤더를 설정하는 것보다 Servlet 에서 제공하는 편의 기능을 사용하여 설정하는 것이 더 좋다 !
response.setHeader();
로 직접 헤더를 설정하는 것보다
response.setContType()
,response.setCharacterEncoding
로 설정하자.
private void content(HttpServletResponse response) {
//Content-type: text/plain;charset=utf-8
//Good 👍
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
//Bad 👎
response.setHeader("Content-Type", "text/plain;charset=utf-8");
}
response.setHeader();
로 직접 헤더를 설정하는 것보다
서블릿에서 제공하는 Cookie 클래스를 사용하는 것이 보다 편리하고 가독성이 좋다.
private void cookie(HttpServletResponse response) {
//Set-Cookie: myCookie=good;
//Good 👍
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600); //600초
response.addCookie(cookie);
//Bad 👎
response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");
}
response.setHeader();
로 직접 헤더를 설정하는 것보다
response.setContType()
,response.setCharacterEncoding
로 설정하자.
private void redirect(HttpServletResponse response) throws IOException {
//Status Code 302
//Location: /basic/hello-form.html
//Good 👍
response.sendRedirect("/basic/hello-form.html");
//Bad 👎
response.setStatus(HttpServletResponse.SC_FOUND); //302
response.setHeader("Location", "/basic/hello-form.html");
}
HTML 내용을 Java 에서 구현할 때, PrintWriter 를 사용해서 보여줄 수 있다.
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Content-type: text/html;charset=utf-8
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println(" <div>Hello!</div>");
writer.println("</body>");
writer.println("</html>");
}
localhost:8080/response-html
로 들어가면 Hello! 가 찍힌 걸 볼 수 있다.
실제 소스 코드는 다음과 같다.
→ 가장 많이 사용하는 방식 !
※ 스프링MVC 쓰면 사실 완전 단축되는 데 일단은 차근차근 알아가 보자 :)
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Content-type: application/json
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
HelloData helloData = new HelloData();
helloData.setUsername("Lee");
helloData.setAge(24);
//{"username":"Lee", "age":24}
String result = objectMapper.writeValueAsString(helloData); //객체를 받아서 String 으로 변환
response.getWriter().write(result);
}
⚠️
application/json
스펙 상utf-8
을 기본으로 사용하도록 정의되어 있다. 따라서 사실 위 코드와 같이 인코딩 타입을 정의하는 것은 의미 없기 때문에 굳이 안 써도 된다.