Servlet과 PSA

2023. 5. 29. 17:20Spring

서블릿

서블릿(Servlet)은 자바를 기반으로 웹 애플리케이션을 개발하기 위한 서버 사이드 프로그래밍 기술입니다.

서블릿은 클라이언트의 요청에 대해 동적으로 처리하고,

웹 서버와 상호작용하여 웹 애플리케이션의 동작을 제어하는 역할을 수행합니다.

 

서블릿은 javax.servlet.Servlet 인터페이스를 구현하여 작성되며,

웹 애플리케이션 서버(예: Apache Tomcat)에서 실행됩니다.

서블릿은 클라이언트의 요청을 처리하고, 그에 따른 응답을 생성하여 클라이언트에게 반환합니다.

 

서블릿의 주요 특징

생명주기(Lifecycle): 서블릿은 초기화(Initialization), 요청 처리(Service), 종료(Destruction)의 생명주기를 가지고 있습니다. 이를 통해 서블릿은 초기 설정, 요청 처리, 리소스 해제 등의 작업을 수행할 수 있습니다.

요청-응답 모델: 서블릿은 클라이언트의 요청에 대해 응답을 생성합니다. HTTP 프로토콜을 기반으로 하여 클라이언트와 통신하며, 요청 메소드(GET, POST 등)와 매개변수, 헤더, 쿠키 등의 요청 정보를 처리합니다.

동적 콘텐츠 생성: 서블릿은 동적인 웹 페이지를 생성할 수 있습니다. 데이터베이스 조회, 비즈니스 로직 처리, 템플릿 엔진과의 연동 등을 통해 동적 콘텐츠를 생성하여 클라이언트에게 반환할 수 있습니다.

다중 스레드 처리: 서블릿은 다중 스레드 환경에서 동작합니다. 각 클라이언트 요청은 별도의 스레드로 처리되며, 서블릿 컨테이너는 스레드 풀을 관리하여 효율적인 처리를 지원합니다.

확장성: 서블릿은 자바 플랫폼의 기능과 라이브러리를 활용하여 웹 애플리케이션을 개발할 수 있습니다. 또한, 필요에 따라 서블릿을 상속하여 기능을 확장하거나, 서블릿 필터, 리스너 등을 통해 웹 애플리케이션의 기능을 추가할 수 있습니다.

 

일반적으로 서블릿을 사용하려면

web.xml을 작성하고 HttpServlet을 상속받아야 합니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<servlet>
<description>Basic Sevlet</description>
<display-name>BasicServlet</display-name>
<servlet-name>BasicServlet</servlet-name>
<servlet-class>BasicServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BasicServlet</servlet-name>
<url-pattern>/basic.do</url-pattern>
</servlet-mapping>
</web-app>

위와 같은 형태로 url과 서블릿을 맵핑하여 톰캣, 스프링 등 여러 미들웨어,소프트웨어 들과의 공유가 필요합니다.

public class BasicServlet extends HttpServlet {
 
	// GET
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		super.doGet(req, resp);
	}
	
	// POST
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		super.doPost(req, resp);
	}
}

이후 HttpServlet을 상속받고

각각 doGet, doPost를 오버라이딩 시켜 각각 링크와 연결된 GET, POST 메소드에 대한 처리를 수행하게 됩니다.

 

허나 이렇게 프로그래밍을 하게 된다면 WAS를 교체한다던지 다른 기술을 사용할때 매우 불편하게 작용하며

확장성이 매우 떨어지게 됩니다.

 

이를 위하여 Spring은 이러한 환경을 PSA화시켜 개선 시켰습니다.

 

PSA

PSA는 서비스의 추상화를 의미하며 Spring이 다른 기술을 추상화하여 개발자가 각 기술의 구현 세부 정보에 대해 

걱정하지 않아도 일관된 방식으로 사용할 수 있게 해주도록 하는 스프링의 핵심 요소 중 하나 입니다.

@Controller
class BoardController {
    @GetMapping("/{boardUuid}")
    @ApiOperation(value = "게시글 상세정보",
            notes = "게시글의 상세정보를 확인 할 수 있습니다.\n" +
                    "JWT가 있어야 차단 사용자 필터링이 가능합니다.")
    public ResponseEntity getBoard(@PathVariable String boardUuid) {
        Account account = AccountHolder.get();

        return service.getDetail(boardUuid,account);
	}
}

 

현재의 저희가 개발하는 방식은 Annotation을 통하여 url을 Mapping하고 바로 처리 할 수 있게 됩니다.

이를 통해 저희는 서블릿은 Low Level로 개발하지 않고도 간편하게 개발할 수 있는데 이는 바로 

스프링이 뒤에서 제공해주는 여러 기능들이 숨겨져 있기 때문입니다.

즉, HttpServlet을 상속받거나 doGet(), doPost()의 구현을 직접하지 않아도 스프링이 맡아 처리한다는 뜻입니다.

 

이러한 PSA, 즉 서비스 추상화를 통하여 개발의 편의성 뿐만아니라 확장성까지 향상 시킵니다.

만약 이전과 같은 방식으로 개발한다고 가정하였을때 톰캣이 아닌 다른 WAS로 개발하려면

또 수 많은 작업이 필요하게 됩니다 허나 이러한 PSA를 적용함으로써 코드를 그대로 두어도 문제 없이 동작합니다.

 

실제로 톰캣 내장인 스프링 부트에선 단순히 톰켓을 exclusions 시키고 다른 와스의 Dependency만 잡아도 WAS가 변경될 만큼

매우 편리한 환경을 제공하는 것을 알 수 있습니다.

 

이러한 PSA의 효과를 보는 곳은 하나 더 있습니다.

바로 스프링에서 DB와의 연결을 담당하는 Spring Transaction입니다.

 

try (Connection conn = DriverManager.getConnection(
             "jdbc:hoonco://127.0.0.1:5432/test", "hooco", "password");
             Statement stmt = conn.createStatement();
             ) {
             
             //start transaction 
             conn.setAutoCommit(false); 
             
             String SQL = "INSERT INTO Employees " +
             			  "VALUES (101, 20, 'Rita', 'Tez')";
             stmt.executeUpdate(SQL);
             
             String SQL = "INSERTED INT Employees " +
             			  "VALUES (107, 22, 'Kita', 'Tez')";
             stmt.executeUpdate(SQL);
             
             conn.commit();
             conn.setAutoCommit(true);
             
             } catch(SQLException e) {
             	
                System.out.println(e.getMessage());
                conn.rollback();
             }

 

위는 간단한 SQL을 DB에 보내는 트랜잭션 코드입니다.

DB와의 커넥션을 잡고 SQL을 작성하고 이를 적용하고 예외 처리까지

단순한 Insert 문 분인데도 불구하고 수많은 코드가 적재 되어 있습니다.

 

스프링은 이 트랜잭션 코드 또한 @Transactional 어노테이션 하나로 간단하게 처리할 수 있도록 진행하였으며

TransactionManager 들을 자유롭게 변경할 수 있도록 구성하였습니다.

 

 

이러한 PSA는 스프링하면 빼놓을 수 없는 핵심 요소 입니다.

덕분에 개발자들은 코드를 더 견고하고 간결하게 작성할 수 있고 기술이 변경되어도 유연하게 대처할 수 있도록 됩니다.

 

단순한 로직을 개발한다고 하더라도 추상화하여 확장성을 높일 수 있는 시야를 가질 수 있도록 더 노력해야겠습니다.

 

'Spring' 카테고리의 다른 글

Spring의 Event  (0) 2024.03.31
Annotaion  (0) 2023.06.18
스프링의 3대 핵심 요소  (0) 2023.05.21
Spring 그 시작과 핵심  (0) 2023.04.30
Hello Spring Batch!, SpringBatch 시작하기  (0) 2022.09.09