일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Postman
- 롬복
- Git
- go
- JPA
- GitHub
- 스프링
- 코드업
- 클린코드
- 기초100제
- Spring Boot
- Spring
- 객사오
- java
- mariadb
- 티스토리챌린지
- springboot
- Gradle
- Codeup
- Python
- golang
- thymeleaf
- MySQL
- 오블완
- 알고리즘
- 클린 코드
- 파이썬
- Vue.js
- H2 설치
- spring security
- Today
- Total
nyximos.log
[Spring] 서블릿 본문
스프링 부트는 톰캣 서버를 내장하고 있어서,
톰캣 서버를 설치하지 않더라도 편리하게 서블릿 코드를 실행할 수 있다.
🤔 서블릿이란?
동적인 웹 페이지를 만들 때 사용되는 자바 기반 웹 애플리케이션 프로그래밍 기술
클라이언트의 요청을 처리 후 결과를 반환해준다.
javax.servlet 및 javax.servlet.http 패키지는 서블릿을 작성하기 위한 인터페이스 및 클래스를 제공합니다.
개발자는 javax.servlet.http 패키지의 HttpServlet 클래스를 상속받아 서블릿을 구현할 수 있다.
🌳 서블릿 생명 주기
서블릿의 생명 주기는 서블릿이 배포된 컨테이너에 의해 제어된다.
클라이언트가 Servlet에게 요청하면
1. servlet의 인스턴스가 존재하지 않는 경우, 웹 컨테이너는
1-1 Servlet 클래스를 로드한다.
1-2 Servlet 클래스의 인스턴스를 생성한다.
1-3 init() 메소드를 호출하여 Servlet 인스턴스를 초기화한다.
2. service() 메소드, request 객체와 response 객체를 호출한다.
만약 컨테이너가 서블릿을 제거해야 할 경우 servlet의 destroy() 메소드를 호출해서 끝낼 수 있다.
스프링 부트는 서블릿을 직접 등록해 사용할 수 있도록 @ServletComponentScan을 지원한다.
내장형 컨테이너를 사용할 때 @ServletComponentScan을 사용하여 @WebServlet, @WebFilter, @WebListener을 단 클래스를 서블릿 컨테이너에 자동 등록 할 수 있다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan //서블릿 자동 등록
@SpringBootApplication
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
@WebServlet : servlet과 url을 지정
속성
name : 서블릿 이름 지정
urlPatterns : 서블릿을 실행할 URL 매핑
value : urlPatterns과 같은 역할, name을 지정하지 않아도 된다.
import javax.servlet.ServletException;
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");
}
}
요청 매개 변수의 값을 문자열로 반환하거나 매개 변수가 없는 경우 null 을 반환한다.
요청 매개 변수는 요청과 함께 전송되는 추가 정보이다.
HTTP servlet의 경우 매개변수는 query string 또는 form data이다.
매개 변수에 값이 하나만 있을 경우에만 getParameter()를 사용하고,
값이 둘 이상일 경우 getParameterValues()를 사용한다.
만약 매개 변수가 여러개일 경우 getParameterValues() 에서 반환되는 배열의 첫번째 값과 같다.
컨텐츠 유형 및 문자 인코딩을 변경하기 위해 호출한다.
클라이언트로 보낼 응답의 문자 인코딩을 설정한다.
클라이언트에 문자 텍스트를 보낼 수 있는 PrintWriter 개체를 반환한다.
write(), print() 메소드를 통해 response body message 생성
실행한 후 http://localhost:8086/hello?username=nyximos주소로 이동하면
다음과 같은 실행결과가 나온다.
HelloServlet.service
request = org.apache.catalina.connector.RequestFacade@2a1cccbc
response = org.apache.catalina.connector.ResponseFacade@6ffe4032
username = nyximos
🎠 서블릿 컨테이너 동작 방식
내장 톰캣 서버 생성
HTTP 요청, HTTP 응답 메시지
웹 애플리케이션 서버의 요청 응답 구조
😮 HTTP 응답에서 Content-Length는 웹 애플리케이션 서버가 자동으로 생성해준다.
🤗 welcome 페이지 추가
main/webapp에 index.html을 만들어 놓으면 http://localhost:포트번호 호출시 index.html 페이지가 열린다.
HttpServletRequest - 개요
서블릿은 HTTP 요청 메시지를 개발자 대신 파싱한다.
그리고 결과를 HttpServletRequest 객체에 담아서 제공한다.
- Start Line - HTTP 메소드, URL, 쿼리 스트링, 스키마, 프로토콜
- header - header 조회
- 바디 - form 파라미터 형식 조회, message body 데이터 직접 조회
- 임시 저장소 기능 : getAttribute(), setAttribue()
- 세션관리 기능 : getSession()
HttpServletRequest - 기본 사용법
start-line 정보
- request.getMethod()
- request.getProtocol()
- request.getScheme()
- request.getRequestURL()
- request.getRequestURI()
- request.getQueryString()
- request.isSecure() : https 사용 유무
header 모든 정보
request.getHeaderNames()
.asIterator()
.forEachRemaining(headerName -> System.out.println(headerName + ":" + request.getHeader(headerName)));
쿠키 조회
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
content 조회
- request.getContentType()
- request.getContentLength()
- request.getCharacterEncoding()
HTTP 요청 데이터
HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법
주로 세가지 방법을 사용한다.
- GET - 쿼리 파라미터
- POST - HTML Form
- HTTP message body에 데이터를 직접 담아서 요청
GET - 쿼리 파라미터
- /url?name=nyximos&mbti=ENFJ
- 메시지 바디 🙅♀️
- URL의 쿼리 파라미터에 데이터 포함해서 전달
- ? 를 시작으로 보낸다.
- 추가 파라미터는 &로 구분
- ex) 검색, 필터, 페이징 등에서 많이 사용
쿼리 파라미터 조회 메서드
- request.getParameter() : 단일 파라미터 조회
- request.getParameterNames() : 파라미터 이름 모두 조회
- request.getParameterMap() : 파라미터 Map으로 조회
- request.getParameterValues() : 복수 파라미터 조회
POST - HTML Form
- content-type: application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파라미터 형식으로 전달
- ex) 회원 가입, 상품 주문, HTML Form 사용
- POST의 HTML Form을 전송하면 웹 브라우저는 HTTP메시지를 만든다.
- 클라이언트 입장에서는 쿼리 파라미터 방식과 차이가 있지만,
- 서버 입장에서는 형식이 동일하므로 아까와 같이 쿼리 파라미터 조회 메서드를 사용하자.
- 단 POST HTML Form 방식은 HTTP 메시지 바디에 데이터를 포함해서 보내므로
- content-type을 꼭 지정하자.
👨🔧 Postman을 사용하여 HTML Form을 만들지 않고 테스트 할 수 있다.
- Body에 x-www-form-urlencoded 체크했는지 확인
- Headers에서 Content-Type이 application/x-www-form-urlencoded로 지정했는지 확인하자.
HTTP message body에 데이터 직접 담아서 요청
- HTTP API에서 주로 사용
- JSON, XML, TEXT
- 주로 JSON 사용 (POST, PUT, PATCH)
1) 단순 텍스트
- content-type : text/plain
- InputStream을 사용해서 HTTP 메시지 바디의 데이터를 읽을 수 있는데 byte 코드를 반환하기 때문에
- 문자(String)으로 보려면 문자표(Charset)를 지정해야한다.
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
2) JSON
- content-type : application/json
- message body : {"name":"nyximos", "mbti":"ENFJ"}
- JSON 결과를 파싱해서 사용할 수 있는 자바 객체를 변환하려면 JSON 변환 라이브러리(Jackson, Gson)를 추가해서 사용해야 한다.
- 스프링 부트로 Spring MVC를 선택하면 기본으로 Jackson 라이브러리(ObjectMapper)를 함께 제공한다.
- Postman으로 실행할때 Body에서 raw를 선택후 JSON을 선택한다.
HttpServletResponse - 기본 사용법
- HTTP 응답 메시지 생성 - HTTP 응답코드 지정, 헤더 생성, 바디 생성
- 편의 기능 제공 - Content-Type, 쿠키, Redirect
- response.setStatus(HTTPServletResponse.SC_OK)
- response.setHeader(String name, String value) : Content-Type, Cache-Control, Pragma등을 정할 수 있다.
- response.setContentType()
- response.setCharacterEncoding()
- response.setContentLength() : 생략시 자동 생성
- response.addCookie()
- response.sendRedirect()
HTTP 응답 데이터 - 단순 텍스트
- 단순 텍스트 응답 writer.println("ok");
HTTP 응답 데이터 - HTML
- HTTP 응답으로 HTML을 반환할 때는 content-type을 text/html로 지정
HTTP 응답 데이터 - API JSON
- HTTP 응답으로 JSON을 반환할 때는 content-type을 application/json로 지정
- application/json은 스펙상 utf-8 형식을 사용하도록 정의되어 있다.
- 따라서 application/json; charset=utf-8이라고 전달하는 것은 의미없는 파라미터를 추가한 것이 된다.
- response.getWriter()를 사용하면 추가 파라미터를 자동으로 추가하는데,
- 이때 response.getOutputStream()을 출력하면 문제가 생기지 않는다.
참조
김영한, 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
https://docs.oracle.com/javaee/5/tutorial/doc/bnafe.html
'Programming > Spring' 카테고리의 다른 글
[Spring] MVC 프레임워크 만들기 (0) | 2022.02.15 |
---|---|
[Spring] 서블릿, JSP, MVC 패턴 (0) | 2022.02.10 |
[Spring Boot + Vue.js] 프로젝트 개발 환경 구성 (0) | 2022.02.07 |
[Spring] Web server failed to start. Port 8080 was already in use. 해결 방법 (0) | 2022.02.04 |
[Spring] 프로젝트 생성 (0) | 2022.02.04 |