스프링 부트는 톰캣 서버를 내장하고 있어서 톰캣 서버 설치 없이 편리하게 서블릿 코드를 실행할 수 있다
서블릿 컴포넌트 등록하기
package hello.servlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan //서블릿 자동 등록
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
스프링부트에서는 @ServletComponentScan
애노테이션을 제공한다.
자동으로 하위 패키지를 뒤져서 서블릿을 컴포넌트로 등록해준다.
HelloServlet
package hello.servlet.basic;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name="helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
//서블릿이 호출되면 서비스 메소드가 호출됨
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet.service");
System.out.println("request = " + request);
System.out.println("response = " + response);
String username = request.getParameter("username");
System.out.println("username = " + username);
//헤더
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
//바디
response.getWriter().write("hello "+username);
}
}
서블릿은 HttpServlet을 상속받아야 한다.
@WebServlet
애노테이션으로 이름과 urlPattern을 달아준다.
서블릿이 호출되면 service 메서드가 호출된다.
request.getParameter()
로 편리하게 파라미터를 조회할 수 있다
응답은 response
를 활용한다.
Http 스펙에 맞춰 일일히 응답하기에는 불편하다. 서블릿이 이렇게 자주 쓰는 기능들을 편리하게 제공한다.
HTTP request 메세지 보기
logging.level.org.apache.coyote.http11=debug
application.properties에 위와 같이 설정을 해주면 요청 정보를 확인해 볼 수 있다.
운영 서버에 이렇게 모든 요청 정보를 남기면 성능 저하가 발생할 수 있으니 개발 단계에서만 사용하는 것이 좋다.
index.html
위 경로에 index.html을 만들면 localhost:8080으로 접속했을 때 기본으로 열린다.
HttpServletRequest를 사용하면 Http 요청 메세지를 편리하게 조회할 수 있다.
HTTP 요청 메세지는 위와 같은 형태이다.
맨 위 라인이 start line으로 http 메서드, url, 쿼리 스트링, 스키마, 프로토콜 등의 정보가 있다
Host와 Content-Type이 헤더 정보이다.
한칸 띄우고 body가 있다.
body는 form 파라미터 형식으로 조회하거나(request.getParameter()
) message body를 직접 조회할 수 있다.
임시 저장소 기능
고객 요청이 시작되어서 끝날 때까지 request.setAttribute()
와 request.getAttribute()
로 임시 저장소를 사용할 수 있다.
세션 관리 기능
reqeust.getSession()
으로 로그인 관리 기능등에 세션을 사용할 수 있다.
Start Line
private static void printStartLine(HttpServletRequest request) {
System.out.println("--- REQUEST-LINE - start ---");
System.out.println("request.getMethod() = " + request.getMethod()); //GET
System.out.println("request.getProtocol() = " + request.getProtocol());
//HTTP/1.1
System.out.println("request.getScheme() = " + request.getScheme()); //http
// http://localhost:8080/request-header
System.out.println("request.getRequestURL() = " + request.getRequestURL());
// /request-header
System.out.println("request.getRequestURI() = " + request.getRequestURI());
//username=hi
System.out.println("request.getQueryString() = " +
request.getQueryString());
System.out.println("request.isSecure() = " + request.isSecure());
//https 사용 유무
System.out.println("--- REQUEST-LINE - end ---");
System.out.println();
}
Start Line에 대한 다양한 정보를 HttpServletRequest를 통해 확인할 수 있다.
모든 Header 정보 참조
//Header 모든 정보
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
/*
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ": " + request.getHeader(headerName));
}
*/
request.getHeaderNames().asIterator()
.forEachRemaining(headerName -> System.out.println(headerName + ": " + request.getHeader(headerName)));
System.out.println("--- Headers - end ---");
System.out.println();
}
request.getheaderNames()
로 모든 헤더 정보를 가져올 수 있다.
Header 편리한 조회
//Header 편리한 조회
private void printHeaderUtils(HttpServletRequest request) {
System.out.println("--- Header 편의 조회 start ---");
System.out.println("[Host 편의 조회]");
System.out.println("request.getServerName() = " +
request.getServerName()); //Host 헤더
System.out.println("request.getServerPort() = " +
request.getServerPort()); //Host 헤더
System.out.println();
System.out.println("[Accept-Language 편의 조회]");
request.getLocales().asIterator()
.forEachRemaining(locale -> System.out.println("locale = " +
locale));
System.out.println("request.getLocale() = " + request.getLocale());
System.out.println();
System.out.println("[cookie 편의 조회]");
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
System.out.println();
System.out.println("[Content 편의 조회]");
System.out.println("request.getContentType() = " +
request.getContentType());
System.out.println("request.getContentLength() = " +
request.getContentLength());
System.out.println("request.getCharacterEncoding() = " +
request.getCharacterEncoding());
System.out.println("--- Header 편의 조회 end ---");
System.out.println();
}
Header 값을 편리하게 조회하는 여러 방법들을 제공한다.
getCookies
로 쿠키들을 꺼낼 수 있다.
cookie.getName()
으로 cookie.getValue()
로 이름과 값을 꺼낼 수 있다.
하나의 헤더 정보만 꺼내고 싶으면 request.getHeader("host")
와 같이 사용한다
기타 정보
private void printEtc(HttpServletRequest request) {
System.out.println("--- 기타 조회 start ---");
System.out.println("[Remote 정보]");
System.out.println("request.getRemoteHost() = " +
request.getRemoteHost()); //
System.out.println("request.getRemoteAddr() = " +
request.getRemoteAddr()); //
System.out.println("request.getRemotePort() = " +
request.getRemotePort()); //
System.out.println();
System.out.println("[Local 정보]");
System.out.println("request.getLocalName() = " +
request.getLocalName()); //
System.out.println("request.getLocalAddr() = " +
request.getLocalAddr()); //
System.out.println("request.getLocalPort() = " +
request.getLocalPort()); //
System.out.println("--- 기타 조회 end ---");
System.out.println();
}
Remote 정보는 요청이 온 서버에 대한 정보고, Local 정보는 내 서버에 대한 정보이다. (network 연결이 맺어진 정보)
Http request를 통해 클라이언트가 서버에게 데이터를 전달하는 방법은 3가지다.
GET 쿼리 파라미터
메세지 바디 없이 URL의 쿼리 파라미터에 데이터를 포함해서 전달한다
검색, 필터, 페이징에 많이 사용하는 방식이다.
POST - HTML FORM
content-type : application/x-www-form-urlencoded
메세지 바디에 쿼리 파라미터 형식으로 데이터를 전달한다
회원 가입, 상품 주문, html form 등을 사용한다
HTTP message body에 데이터 직접 담아서 요청
HTTP API에서 주로 사용한다, JSON, XML, TEXT 등
주로 JSON을 사용한다.
POST, PUT, PATCH 등 전부 사용 가능하다
GET방식과 POST 방식 모두 생긴 모양은 쿼리파라미터 모양으로 동일하기 때문에 서버에서는 request.getParameter()
로 읽을 수 있다.