[ 최종 수정일 : 2023년 09월 20일 ]

 

 

 

 

요청 포워딩을 구현하는 방법은 두 가지가 있습니다.

  • RequestDispatcher 클래스를 활용한 forwarding
  • RequestDispatcher 클래스를 활용한 include
  • HttpServletResponse 클래스를 활용한 redirect

 


 

Request Forwarding - (RequestDispatcher)


클라이언트가 서블릿에 요청을 전송하면 request 객체가 자동으로 생성됩니다.

이때 request 객체를 활용해서 응답을 처리하는 웹 컴포넌트에게 요청을 위임하는 것이 요청 포워딩입니다.

 

RequestDispatcher Request Forwaridng의 기본적인 Syntax입니다.
RequestDistatcher dis = request.getRequestDispatcher(target);
dis.forward( request, response );

 

요청 포워딩을 수행한 웹 컴포넌트의 모든 응답은 모두 자동 취소됩니다.

만약 워딩 수행 전, 버퍼가 플러싱되면 요청 포워딩은 수행되지 않습니다.

 

 

 

 

Request Include - (RequestDispatcher)


웹 페이지 내에서 다른 리소스를 현재 페이지에 포함시키는 방법입니다.

일반적으로 스크립팅 언어(JSP, PHP 등)을 활용하여 웹 페이지의 일부분을 동적으로 구현할 때 사용합니다.

 

RequestDispatcher Request Include의 기본적인 Syntax입니다.
RequestDistatcher dis = request.getRequestDispatcher(target);
dis.include( request, response );

 

쉽게 말해, A 서블릿의 로직 수행 결과를 B 서블릿으로 요청을 넘길 때, 로직 수행 결과를 포함해서 넘겨주게 됩니다.

 

 

 

Request Redirection - (HttpServletResponse)


요청 포워딩과 비슷하게 다른 컴포넌트에게 요청을 위임하는 방식입니다.

요청 포워딩과 차이점은 응답을 먼저 하고 요청을 위임하기 때문에, 동일한 request가 아니라 새로운 request 객체가 생성됩니다.따라서 웹 브라우저의 URL 값이 변경되고 속성에 설정된 값을 가져오지 못합니다.

그래서 삭제 단위가 브라우저인 Session Scope에 저장해야 합니다.

 

Request Redirect의 기본적인 Syntax입니다.
HttpSession session = req.getSession();
session.sendRedirect("/target");

 

즉, 클라이언트는 서블릿에게 요청을 전송하고 응답을 받으면 JSP에 재요청을 하고 응답을 받는 원리로 수행됩니다.

 

 

 

 

 

 

 

 

 

'웹 표준 > Servlet' 카테고리의 다른 글

Session Tracking  (0) 2023.09.14
FrontController, Command Patterns  (0) 2023.09.13
DTO, DAO, VO  (0) 2023.09.12
Connection Pool  (0) 2023.09.08
톰캣 사양 별 DTD  (0) 2023.09.05

 

 

 

DTO (Data Transfer Object), DAO (Data Access Object), VO (Value Object)는 3계층 아키텍처에서 사용됩니다.

 

 


 

 

1. 3-Tire Architecture

 웹 애플리케이션을 설계하고 개발할 때, 구조적 명료성과 유지보수를 위해 일반적으로 3계층 아키텍처(3-Tire Architecture)를 사용합니다. 3계층 아키텍처에서 두 가지 패턴은 데이터의 전송 및 캡슐화를 담당하게 됩니다.

 

 다음은 3계층 아키텍처의 구성요소입니다.

 

  • 프레젠테이션 계층(Presentation Layer)
    이 계층에서는 사용자의 입력을 받아 처리하고 사용자에게 결과를 표시합니다.

  • 비즈니스 계층(Business Logic Layer)
    애플리케이션의 다양한 비즈니스 로직이 구현되어 있는 계층입니다.

  • 영속성 계층(Persistence Layer)
    데이터베이스에 접근하여 데이터의 CRUD 연산을 처리하는 계층입니다.

 

위 3계층 아키텍처를 기반으로 DTO와 DAO를 알아보겠습니다.

 

 


2. DTO (Data Transfer Object)

 DTO는 일반적으로 Presentation, Business Layer에서 활용됩니다.

클라이언트의 요청을 DTO에 저장하고 DAO에게 DTO를 인자값으로 주면서 데이터 조작을 요청합니다.

이 때, DTO는 서블릿 공유 컨테이너의 Rquest Scope에 위치하므로 요청에 대한 응답을 전송하는 즉시 DTO는 파괴됩니다.

 

 

 

3. DAO (Data Access Object)

 DAO는 DTO를 기반으로 데이터베이스에 접근하여 데이터를 CRUD하고, 그 조작 결과를 VO(Value Object)로 반환합니다.

 

 

 

4. VO (Value Object)

VO는 Business Layer에서 DAO에게 요청한 값을 받아올 때 사용하며,  DAO는 데이터 조작을 통해 얻은 데이터를 반환할 때 VO를 통해 반환합니다.  즉, VO의 필드들은 DQL문장들의 결과셋으로 이루어진다고 할 수 있습니다.

 

 

 

 

'웹 표준 > Servlet' 카테고리의 다른 글

Session Tracking  (0) 2023.09.14
FrontController, Command Patterns  (0) 2023.09.13
Request  (0) 2023.09.13
Connection Pool  (0) 2023.09.08
톰캣 사양 별 DTD  (0) 2023.09.05

 

 

 

[2023_08_09] 해당 발행글은 Oracle을 기준으로 작성되었습니다.

 

 

 

 

Connection Pool은 연결 객체를 생성하고 영구소멸하는 것이 아니라 대여와 반납의 개념으로 이루어집니다.

 

 

 


 

 

Connection Pool은 DataSource Interface의 규격대로 DataSource를 제공합니다.

이러한 DataSource는 Tomcat같은 WAS 내부에서 생성하게 됩니다.

 

WAS가 DataSource를 생성하는 방법은 두 가지가 있습니다.

 

  • Global DataSource
  • 애플리케이션 별 Local DataSource

 

Global DataSource는 표준에 따라 생성 후 제공하지만, 각 벤더의 WAS마다 설정방법이 모두 다르기 때문에

WAS가 바뀌어도 소스를 변경할 필요가 없는 Local DataSource를 사용하는 것을 권장합니다.

 

 

다음 경로에 프로젝트 내에 META-INF 폴더를 만들고 context.xml을 생성합니다.

 

 


 

 

기초적인 context.xml Syntax입니다.

 

<?xml version="1.0" encoding="UTF-8"?>

<Context>

    <!-- <Resource 
        name="jdbc/OracleLocalDB" 
        auth="Container"
        type="javax.sql.DataSource"
        username="이름작성"
        password="비밀번호작성"
        driverClassName="oracle.jdbc.OracleDriver"
        url="jdbc:oracle:thin:@db이름?TNS_ADMIN=db설치주소"
        maxTotal="8"
        maxIdle="2"
    /> -->

    <Resource 
        name="jdbc/OracleCloudATP" 
        auth="Container"
        type="javax.sql.DataSource"
        username="이름작성"
        password="비밀번호작성"
        driverClassName="oracle.jdbc.OracleDriver"
        url="jdbc:oracle:thin:@tns_name?TNS_ADMIN=클라우드지갑주소"
        maxTotal="8"
        maxIdle="2"
    />

<!--     <Resource 
        name="jdbc/OracleLocalDBWithDriverSpy" 
        auth="Container"
        type="javax.sql.DataSource"
        username="이름작성"
        password="비밀번호작성"
        driverClassName="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"
        url="jdbc:log4jdbc:oracle:thin:@db이름?TNS_ADMIN=db설치주소"
        maxTotal="8"
        maxIdle="2"
    /> -->

    <Resource 
        name="jdbc/OracleCloudATPWithDriverSpy" 
        auth="Container"
        type="javax.sql.DataSource"
        username="이름작성"
        password="비밀번호작성"
        driverClassName="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"
        url="jdbc:log4jdbc:oracle:thin:@tns_name?TNS_ADMIN=클라우드지갑주소"
        maxTotal="8"
        maxIdle="2"
    />

</Context>

 

주석된 부분은 LocalDB이므로 필요하신 분은 주석 해제 후 개발환경에 맞게 작성하시면 됩니다.

 

 


 

 

위의 코드를 참고해서 Connection Pool을 두개를 사용하겠습니다.이제 Eclipse에서 Tomcat Server를 실행하고 Servlet을 작성합니다.

 

Servlet을 작성할 때, LifeCycleMethods를 모두 생성합니다.

 

 

다음 코드를 작성합니다.

 

@Log4j2
@NoArgsConstructor

@WebServlet("/UsingDataSource")
public class UsingDataSourceServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    // 의존성 주입
    @Resource(name="jdbc/OracleCloudATP")
    private DataSource dataSource;


    public void init(ServletConfig config) throws ServletException {
        log.trace("init({}) invoked.", config);
		
        Objects.requireNonNull(dataSource);
        log.info("\t + dataSource: " + dataSource);
    } // init()


    public void destroy() {
        log.trace("destroy() invoked.");
    } // destroy()


    protected void service(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {
        log.trace("service(req, res) invoked.");
		
        try {
            Connection conn = this.dataSource.getConnection();
			
            try(conn){
                Objects.requireNonNull(conn);
                log.info("\t + conn: {}", conn);
            } // try
			
        } catch (SQLException e) {
            throw new IOException(e);
        } // try-catch
		
    } // service()

} // end class

 

@Resource 어노테이션은 지정된 자원의 레퍼런스를 획득 후 DataSource의 필드에 의존성 주입을 하게 됩니다.

이제 서버에 작성된 Servlet을 올릴 때마다, Connection Pool에 Data Resource를 계속해서 추가하게 됩니다.

 

 

 

'웹 표준 > Servlet' 카테고리의 다른 글

Session Tracking  (0) 2023.09.14
FrontController, Command Patterns  (0) 2023.09.13
Request  (0) 2023.09.13
DTO, DAO, VO  (0) 2023.09.12
톰캣 사양 별 DTD  (0) 2023.09.05

 

 

 

web.xml을 웹 애플리케이션의 설정파일이라고 할 수 있습니다.

즉, 웹 애플리케이션에 포함된 모든 종류의 구성요소(Servlet, JSP와 같은 Component)를 설정합니다.

 

 


 

 

사양에 따라 web.xml을 설정해야 합니다.

 

 

# Tomcat 9.0

<?xml version="1.0" encoding="UTF-8"?>

    <web-app 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    version="4.0">

 

 

# Tomcat 8.0

<?xml version="1.0" encoding="UTF-8"?>

    <web-app 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

 

 

# Tomcat 7.0

<?xml version="1.0" encoding="UTF-8"?>

    <web-app 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

 

 

 

web.xml에서 설정 이후, 지역 설정 Project Facets에서 잘 적용됐는지 확인할 수 있습니다.

 

 

 

 

 

 

'웹 표준 > Servlet' 카테고리의 다른 글

Session Tracking  (0) 2023.09.14
FrontController, Command Patterns  (0) 2023.09.13
Request  (0) 2023.09.13
DTO, DAO, VO  (0) 2023.09.12
Connection Pool  (0) 2023.09.08

+ Recent posts