1. 웹서버? was? 무슨차이?
웹서버
웹서버는 정적 리소스 파일을 처리한다. apache, ngix등이 포함된다. 이들은 웹 서버의 기능을 제공하긴 하지만 실질적으로 비즈니스 로직을 처리하진 않는다. 그냥 http 응답에 따라서 반응한다.
WAS ( Web Application Server )
WAS는 어플리케이션 로직을 가지고 있는 웹 서버라고 보면된다. 어플리케이션 코드를 실행하고 정적 리소스, 동적 리소스 모두 제공이 가능하다.
- was + DB만으로 웹서버 구성이 가능하다.
2. 웹 서버의 구성
- WAS + DB
어플리케이션 로직 처리와 리소스 제공이 전부 WAS에 달려있다
장점
- 구성이 간단하다.
- 웹 서버를 따로 둘 필요가 없다.
단점
- WAS가 다운되면 웹서버 자체가 아무것도 동작하지 않는다.
- WAS가 처리해야 할 일이 많다.
- 웹서버 + WAS + DB
웹서버가 최앞단에 있고 뒤에 WAS, 마지막에 DB가 있다. 해당 경우에는 웹서버에서 정적 데이터를 처리하고, WAS가 동적 데이터를 처리한다.
장점
- WAS의 부담이 줄어든다.
- WAS가 다운되었을 때 에러 메세지 등을 표시할 수 있다.
단점
- 신경써야 할 프로그램이 한개 더 늘어난다.
3. 서블릿
서블릿이란
서블릿은 웹어플리케이션에서 수행해야 하는 정말 많은 것들을 도와준다 예를 들어
- 소켓 연결
서블릿은 HTTP 요청을 처리하기 위해 소켓 연결을 수행합니다. 웹 브라우저에서 서블릿에 요청을 보내면, 서블릿 컨테이너는 해당 요청에 대한 소켓 연결을 생성하고, 해당 요청을 처리하는 서블릿 클래스의 service() 메서드를 호출합니다.
public class MyServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) { // 소켓 연결 수행 Socket socket = new Socket("localhost", 8080); } }
- 헤더 정보 파싱
서블릿은 HTTP 요청의 헤더 정보를 파싱할 수 있습니다. HttpServletRequest 객체를 사용하여 HTTP 요청의 모든 헤더를 읽고, 필요한 정보를 추출할 수 있습니다.
public class MyServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) { // HTTP 요청의 헤더 정보 파싱 String userAgent = request.getHeader("User-Agent"); } }
- 서블릿이 없다면 http 패킷을 전부 다 한줄 한줄 파싱해야 한다.
- 서블릿은 해당 작업을 매우 쉽게 만들어준다.
- 바디 정보 파싱
서블릿은 HTTP 요청의 바디 정보를 파싱할 수 있습니다. HttpServletRequest 객체를 사용하여 HTTP 요청의 바디를 읽고, 필요한 정보를 추출할 수 있습니다.
public class MyServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) { // HTTP 요청의 바디 정보 파싱 BufferedReader reader = request.getReader(); String line; while ((line = reader.readLine()) != null) { // 바디 정보 처리 } } }
- http 응답
서블릿은 HTTP 응답을 생성할 수 있습니다. HttpServletResponse 객체를 사용하여 HTTP 응답의 헤더와 바디를 설정하고, 웹 브라우저에 전송할 수 있습니다.
public class MyServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) { // HTTP 응답 생성 response.setStatus(HttpServletResponse.SC_OK); //404 403 500 200 201 response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head><title>My Servlet</title></head>"); out.println("<body><h1>Hello World!</h1></body>"); out.println("</html>"); } }
설정
서블릿은 웹 어플리케이션에서 수행해야 하는 다양한 작업들을 도와줍니다. 예를 들어, 소켓 연결, 헤더 정보 파싱, 바디 정보 파싱, HTTP 응답 등을 처리할 수 있습니다.
디렉터리 매핑은 web.xml 파일에서 설정할 수 있습니다. 이를 통해 서블릿 클래스와 URL을 연결할 수 있습니다. 예를 들어, <servlet-mapping> 태그를 사용하여 서블릿 클래스와 URL을 매핑할 수 있습니다.
- web.xml
Spring에서는 web.xml 대신에 Java Config 파일을 사용하여 서블릿 매핑을 설정할 수 있습니다. 예를 들어, @WebServlet 어노테이션을 사용하여 서블릿 클래스와 URL을 매핑할 수 있습니다.
@WebServlet(name = "MyServlet", urlPatterns = { "/myservlet/*" }) public class MyServlet extends HttpServlet { // 서블릿 코드 }
위의 예제에서 "/myservlet/*" URL은 MyServlet 클래스와 매핑됩니다. 이제 브라우저에서 "/myservlet/" 경로로 요청을 보내면, 서블릿 컨테이너는 MyServlet 클래스의 service() 메서드를 호출합니다.
또한, Spring MVC에서는 @Controller 어노테이션과 @RequestMapping 어노테이션을 사용하여 서블릿 매핑을 설정할 수 있습니다. 예를 들어, 아래와 같이 HomeController 클래스를 작성하여 "/" URL과 HomeController 클래스를 매핑할 수 있습니다.
@Controller public class HomeController { @RequestMapping("/") public String home() { return "index"; //jsp, thymeleaf, body <- restapi http api } }
위의 예제에서 "/", 즉 루트 URL은 home() 메서드와 HomeController 클래스와 매핑됩니다. 이제 브라우저에서 애플리케이션의 루트 URL로 요청을 보내면, home() 메서드가 호출되어 index 뷰를 반환합니다.
위의 예제에서 "/myservlet/*" URL은 MyServlet 클래스와 매핑됩니다. 이제 브라우저에서 "/myservlet/" 경로로 요청을 보내면, 서블릿 컨테이너는 MyServlet 클래스의 service() 메서드를 호출합니다.
- build.gradle
implementation 'javax.servlet:javax.servlet-api:4.0.1'