김영한 님의 스프링 MVC 1편 강의를 듣고 정리한 내용을 정리하였습니다
서블릿
특징
서블릿 컨테이너
- 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고한다.
- 서블릿 컨테이너의 역할은 서블릿 객체를 생성, 초기화, 호출, 종료하는 호출주기 관리이다.
- 서블릿 객체는 싱글톤으로 관리한다.
- JSP도 서블릿으로 변환되어서 사용한다.
- 동시 요청을 위한 멀티쓰레드를 지원한다.
요청마다 쓰레드 생성하는 경우
장점
동시 요청을 처리할 수 있다.
리소스가 허용할 때까지 처리 가능하다
하나의 쓰레드가 지연이 있어도 나머지는 정상동작한다.
단점
쓰레드는 생성 비용은 매우 비싸다
쓰레드는 컨텍스트 스위칭 비용이 발생한다
쓰레드 생성에 제한이 없다.
쓰레드풀
요청마다 쓰레드 생성의 단점 보완
특징
필요한 쓰레드를 쓰레드 풀에 보관하고 사용한다.
쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 톰캣은 200개 기본 설정
사용
쓰레드가 필요하면 이미 생성되어있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.
사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
최대 쓰레드가 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면 - 대기, 거절 가능
쓰레드 풀 값을 낮게 설정하면 - 서버 리소스는 여유롭지만, 동시요청 많아지면 응답징녀
쓰레드 풀 값을 높게 설정하면 - 동시 요청이 많으면 cpu, memory 리소스 임계점 초과로 서버 다운
WAS의 멀티 쓰레드 지원
멀티 쓰레드에 대한 부분은 WAS가 관리
개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 된다.
개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 개발
SSR CSR 차이
ssr 서버 사이드 렌더링
- HTML 최종 결과를 서버에서 만들어 웹 브라우저에 전달
- 정적인 화면에 사용
- jsp, 타임리프
csr 클라이언트 사이드 렌더링
- HTML 결과를 자바스크립트를 활용해 웹 브라우저에서 동적으로 생성
- 주로 동적인 화면에서 사용
- 구글지도, 구글 캘린더
@ServletComponentScan //서블릿 자동등록
@SpringBootApplication
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
@WebServlet(name ="helloServelt" , urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("HelloServlet.service");
System.out.println("req = " + req);
System.out.println("res = " + res);
String username = req.getParameter("username");
System.out.println("username = " + username);
res.setCharacterEncoding("utf-8");
res.getWriter().write("hello" + username);
}
}
결과
HelloServlet.service
req = org.apache.catalina.connector.RequestFacade@14994fc5
res = org.apache.catalina.connector.ResponseFacade@a16ad29
username = kim
@WebServlet : 서블릿 어노테이션
name = 서블릿 이름
urlPatterns: URL 매핑
localhost:8080/hello에 접속 시
표준 스펙 구현체가 찍히는걸 확인할 수 있다.
application.properties 에 해당 속성을 추가한 뒤 재시작 하게 된다면
logging.level.org.apache.coyote.http11=debug
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Whale";v="3", "Not-A.Brand";v="8", "Chromium";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Whale/3.21.192.18 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: ko,en-US;q=0.9,en;q=0.8,ko-KR;q=0.7,ja;q=0.6,de;q=0.5
]
HelloServlet.service
req = org.apache.catalina.connector.RequestFacade@5f7258cc
res = org.apache.catalina.connector.ResponseFacade@34de247f
username = kim
http 요청 메세지를 콘솔창에서 확인할 수 있다.
HttpServletRequest, HttpServletResponse를 사용할 때 가장 중요한점은
객체들이 HTTP 요청메세지, Http응답메시지를 편리하게 사용하도록 도와주는 역할을 한다.
@WebServlet(name = "requestParamServlet", urlPatterns = "/request-param")
public class RequestParamServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("RequestParamServlet.service");
System.out.println("[전체 파라미터 조회] - start");
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> System.out.println(paramName + "=" + request.getParameter(paramName)));
System.out.println("[전체 파라미터 조회] - end");
System.out.println();
System.out.println("[단일 파라미터 조회]");
String username = request.getParameter("username");
String age = request.getParameter("age");
System.out.println("username = " + username);
System.out.println("age = " + age);
System.out.println();
System.out.println("[이름이 같은 복수 파라미터 조회]");
String[] usernames = request.getParameterValues("username" );
for(String name : usernames)
{
System.out.println("name = " + name);
}
response.getWriter().write("ok");
}
}
복수 파라미터에서 단일 파라미터 조회
username=hello&username=kim 과 같이 파라미터 이름은 하나인데 값이 중복일 경우
request.getParameterValues()를 사용하면 된다.
이렇게 중복일 경우 request.getParameter()을 사용하면 request.getParameterValues()의 첫번째 값을 반환한다.
POST HTML Form
contentType : application/x-www-form-urlencoded
JSON 결과를 파싱해서 사용할 수 있는 자바 객체로 변환하려면 Jackson, Gson 같은 JSON 변환 라이브러리를 추가해서 사용해야 한다. 스프링부트로 SpringMVC를 선택하면 기본적으로 Jackson 라이브러리(ObjectMapper) 를 함께 제공한다.
@WebServlet(name = "requestBodyJsonServlet" , urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
System.out.println("messageBody = " + messageBody);
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
System.out.println("helloData name = " + helloData.getUsername());
System.out.println("helloData age= " + helloData.getAge());
}
}
HttpServletResponse 기본 사용법
- HttpServletRespons 역할
- HTTP 응답 메세지 생성
- HTTP 응답코드 지정
편의 기능
Content-Type, 쿠키, Redirect
HttpServletResponse - 기본사용법
@WebServlet(name = "responseHeaderServlet" , urlPatterns = "/response-header")
public class ResponseHeaderServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.setHeader("Content-Type", "text/plain");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("my-header", "hello");
PrintWriter writer = response.getWriter();
writer.write("ok");
}
}
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
'스터디 > 2023_스프링부트' 카테고리의 다른 글
[study] 스프링MVC2 - 1. 타임리프 (0) | 2023.08.08 |
---|---|
[study] 스프링MVC 정리 2 (0) | 2023.08.01 |
[study] HTTP 웹 기본 지식 (1) | 2023.07.23 |
[study]자바의정석 11~14 chapter (0) | 2023.07.18 |
[study] 자바의 정석 - chapter 6~9 (0) | 2023.07.09 |