본문 바로가기

웹 개발/Spring

[Web_Spring] 05

● Front-Controller 패턴

 

1. 사용자의 Request는 Front-Controller인 DispatcherServlet을 통해 처리한다.

 

2. HandlerMapping은 Request의 처리를 담당하는 컨트롤러를 찾기 위해서 존재한다.

- HandlerMapping 인터페이스를 구현한 여러 객체중 @Controller 어노테이션이 적용된 것을 기준으로 판단하며,

   적절한 컨트롤러가 찾아졌다면 HandlerAdapter를 이용해서 해당 컨트롤러를 동작시킨다.

 

3. Controller는 Request를 처리하는 비지니스 로직을 작성, View에 전달해야 하는 데이터는 주로 Model 객체에 담아 전달

- 이에 대한 처리는 ViewResolver를 이용하게 된다.

 

4. ViewResolver는 Controller가 리턴한 결과 앞에 절대 경로, 뒤에 .html확장자를 붙여준다.

 

5. 응답 페이지의 전체경로가 완성되면 View객체를 통해 해당 페이지의 응답준비를 한다.

 

6. 준비된 응답은 DispatcherServlet을 통해서 전송된다.

 

 

 

● Front-Controller 패턴 특징

- HttpServletRequest, HttpServletResponse를 거의 사용할 필요 없이 기능 구현

- 다양한 타입의 파라미터 처리, 다양한 타입의 리턴 타입 사용 가능

- GET방식, POST방식 등 전송 방식에 대한 처리를 어노테이션으로 처리 가능(@GetMapping, @PostMapping)

 

 

 

 

실습

 

1. src/main/resource/application.properties

#server port
server.port=10002

#JDBC spy datasource
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
spring.datasource.hikari.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.hikari.jdbc-url=jdbc:log4jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.hikari.username=hr
spring.datasource.hikari.password=hr

#log level
logging.level.root=info

 

 

 

2. src/main/java/com.example.ex02/mapper/TimeMapper.java

package com.example.ex02.mapper;

import org.apache.ibatis.annotations.Mapper;

@Mapper //스프링 마이바티스에서 xml파일과 연결될 Mapper 인터페이스임을 알려준다.
public interface TimeMapper {
//    SQL이 복잡하거나 길어지는 경우에는 어노테이션보다 XML방식을 더 선호하게 된다.
//    @Select("SELECT SYSDATE FROM DUAL")
    public String getTime();
}

 

 

 

3. src/main/resource/mapper/TimeMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.ex02.mapper.TimeMapper">
    <select id="getTime" resultType="string">
        SELECT SYSDATE FROM DUAL
    </select>
</mapper>

 

 

 

4. src/main/java/com.example.ex02/myBatis/MyBatisConfig.java

package com.example.ex02.myBatis;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration //설정 관련 클래스에 작성한다.
@MapperScan("com.example.ex02.mapper") //작성한 경로부터 하위 경로까지 모두 @Mapper를 스캔한다.
@RequiredArgsConstructor
public class MyBatisConfig {
    //    커넥션 풀 및 MyBatis에 필요한 요소를 메모리에 할당 및 관리, xml과 java연동에 필요한 경로 관리
    private final ApplicationContext applicationContext;

    //    @Bean : 메소드의 리턴 객체를 스프링 컨테이너에 등록, 객체명은 메소드의 이름으로 자동 설정되며,
//            직접 설정하고자 할 때에는 @Bean(name="객체명")으로 사용
    @Bean //@Configuration 또는 @Component가 작성된 클래스의 메소드에만 사용이 가능하다.
    @ConfigurationProperties(prefix = "spring.datasource.hikari") //properties 파일에서 prefix인 설정 모두 가져오기
    public HikariConfig hikariConfig() {
        return new HikariConfig(); //properties파일에서 가져온 설정들과 필드가 매핑되어 자동으로 주입된다.
    }

    @Bean
    public HikariDataSource hikariDataSource(){
//        DataSource 객체에 DBMS 정보 설정
        return new HikariDataSource(hikariConfig());
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws IOException {
//        세션 팩토리 설정 객체
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//        DBMS 정보를 담고 있는 DataSource를 세션 팩토리 설정 객체에 전달
        sqlSessionFactoryBean.setDataSource(hikariDataSource());
//        SQL 쿼리를 작성할 mapper.xml 경로 설정
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath*:/mapper/*.xml"));
        try {
//            위에서 설정한 세션 팩토리 빈을 통해 세션 팩토리 생성
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
//            팟홀(언더바) 표기법을 카멜 표기법으로 자동 변경 설정
            sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
            return sqlSessionFactory;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

 

 

5. src/test/java/com.example.ex02/myBatis/MyBatisConfigTests.java

package com.example.ex02.myBatis;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection; 

@SpringBootTest
@Slf4j
public class MyBatisConfigTests {
    @Autowired
    private DataSource dataSource;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

//    @Test
//    public void dataSourceTest(){
////        try statement 문법
////        try(외부 드라이버 요청 문법 작성){}
////        try문에 있는 소괄호에 연결객체를 요청하면, 사용종료 후 자동으로 close()된다.
//        try
//                (
//                        Connection conn = dataSource.getConnection();
//                )
//        {
//            log.info("---------------------------------");
//            log.info("datasource connection : " + conn);
//            log.info("---------------------------------");
//
//        } catch (Exception e){
//            e.printStackTrace();
//        }
//    }

    @Test
    public void sqlSessionTest(){
        log.info("-------------------------------");
        log.info("sql session factory : " + sqlSessionFactory);
        log.info("-------------------------------");

        try
                (
                        SqlSession sqlSession = sqlSessionFactory.openSession(true);
                        Connection conn = sqlSession.getConnection();
                )
        {
            log.info("sql session : " + sqlSession);
            log.info("-------------------------------");
            log.info("sql session connection " + conn);
            log.info("-------------------------------");

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

 

 

6. src/test/java/com.example.ex02/mapper/TimeMapperTests.java

package com.example.ex02.mapper;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
public class TimeMapperTests {
    @Autowired 
    private TimeMapper timeMapper;

    @Test
    public void getTimeTest(){
        log.info("-------------------------------");
        log.info(timeMapper.getTime());
        log.info("-------------------------------");
    }
}

 

 

 

7. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId> 
    <artifactId>ex02</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ex02</name>
    <description>MyBatis Practice</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.bgee.log4jdbc-log4j2</groupId>
            <artifactId>log4jdbc-log4j2-jdbc4</artifactId>
            <version>1.16</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                    <include>**/*.setting</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 

 

 

8. ex03.html

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>EX03</title>
</head> 
<body>
<h1>EX04</h1>

<table border="1">
    <tr>
        <th>이름</th>
        <th>나이</th>
        <th>성별</th>
    </tr>
    <tr>
        <td th:text="${exampleVO.name}"></td>
        <td th:text="${exampleVO.age}"></td>
        <td th:text="${exampleVO.gender}"></td>
    </tr>
</table>

</body>
</html>

 

 

 

9. ex04.html

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>EX04</title>
</head>
<body>
<h1>EX04</h1> 

<table border="1">
    <tr>
        <th>이름</th>
        <th>국어</th>
        <th>영어</th>
        <th>수학</th>
        <th>총점</th>
        <th>평균</th>
    </tr>
    <tr th:object="${testVO}">
        <td th:text="*{name}"></td>
        <td th:text="*{kor}"></td>
        <td th:text="*{eng}"></td>
        <td th:text="*{math}"></td>
        <td th:text="*{kor + eng + math} + '점'"></td>
        <td th:text="|*{(kor + eng + math) / 3}점|"></td>
    </tr>
</table>
</body>
</html>

 

 

 

10. src/main/java/com.example.ex02/domain.vo/ExampleVO.java

package com.example.ex02.domain.vo;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class ExampleVO {
    private String name;
    private Integer age;

    public String getGender(){
        return "선택안함";
    }
}

 

 

 

11. src/main/java/com.example.ex02/domain.vo/TestVO.java

package com.example.ex02.domain.vo;

import lombok.Data;
import org.springframework.stereotype.Component;

@Component
@Data
public class TestVO {
    //이름
    private String name;
    //국어
    private Integer kor;
    //영어
    private Integer eng;
    //수학
    private Integer math;
}

 

 

 

12. src/main/java/com.example.ex02/controller/ExampleController.java

package com.example.ex02.controller;

import com.example.ex02.domain.vo.ExampleVO;
import com.example.ex02.domain.vo.TestVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller 
@RequestMapping("/ex/*")
@Slf4j
public class ExampleController {

    @RequestMapping(value = "example", method = {RequestMethod.POST, RequestMethod.GET})
    public void ex01(){
        log.info("ex01...................");
    }

    @GetMapping("ex02")
    public void ex02(){
        log.info("ex02.................");
    }

    @GetMapping("ex03")
    public void ex03(ExampleVO exampleVO){
        log.info("---------------------------------");
        log.info(exampleVO.toString());
        log.info("---------------------------------");
    }

    //    이름, 국어, 영어, 수학 점수를 전달받은 뒤 각 요소를 화면에 출력한다.
    @GetMapping("ex04")
    public void ex04(TestVO testVO){
        log.info("--------------------------------------");
        log.info(testVO.toString());
        log.info("--------------------------------------");
    }

}

 

 

'웹 개발 > Spring' 카테고리의 다른 글

[Web_Spring] 07  (0) 2022.06.19
[Web_Spring] 06  (0) 2022.06.18
[Web_Spring] 03  (0) 2022.06.15
[Web_Spring] 02  (0) 2022.06.14
[Web_Spring] 01  (0) 2022.06.13