Spring으로 웹프로젝트 구현하기

천소진·2022년 12월 28일
0

Study

목록 보기
27/29

SpringFramework기반 웹 프로젝트 구현

※ build.gradle 에는 gradle프로젝트에서사용될 인터페이스를 공용Repository에서 가져와서 등록.
xml은 해당프로젝트와 연결될 web container에 대한 설정으로 build.gradle 에 등록이 되지 않은 것들은 설정할 수가 없다.

1. 기본 설정

1) 프로젝트 생성 후 스프링 사용 설정 등록.

─src
└ build.gradle의 dependencies내
implementation group: 'org.springframework', name: 'spring-core', version: '5.3.19'
implementation group: 'org.springframework', name: 'spring-context', version: '5.3.19'
implementation group: 'org.springframework', name: 'spring-test', version: '5.3.19'
implementation group: 'org.springframework', name: 'spring-webmvc', version: '5.3.19'
추가

2) 연동할 DB 추가

// mariaDB 
https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client

implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '3.0.4'

3) Lombok/Log4j2/JSTL/ ModelMapper/ HikariCP 추가

//lombok library *  : 어노테이션 기반으로 코드를 자동완성해주는 라이브러리
compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'

testCompileOnly 'org.projectlombok:lombok:1.18.24'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'

//HikariCP * : connection pooling을 제공하는 JDBC DataSource의 구현체
implementation group: 'com.zaxxer', name: 'HikariCP', version:'5.0.0'

//ModelMapper * : 서로 다른 Object 간의 필드값을 자동으로 mapping해주는 라이브러리
implementation group: 'org.modelmapper', name: 'modelmapper', version: '3.0.0'

//log4j2 * : Apache에서 만든 로깅용 자바기반의 오픈소스 라이브러리
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.2'
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.17.2'

implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.17.2'

//jstl * : 자바 서버페이지 표준태그라이브러리 (JSP페이지 내에서 자바 코드를 사용하지 않고 로직을 내장하도록해줌)
implementation group: 'jstl', name: 'jstl', version: '1.2'                                          

4) Spring Config 설정파일 (해당 웹프로젝트 환경설정) 작성

[root-context.xml]

  • webapp 오른쪽우클릭 → New → XML ConfigurationFile → Spring Config 생성
    : 일반적으로 Spring Framework이용시 사용하는 기본 설정 파일.
    : 주로 POJO에 대한 설정.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans 
          			  http://www.springframework.org/schema/beans/spring-beans.xsd"
          			  http://www.springframework.org/schema/context
                      http://www.springframework.org/schema/context/spring-context.xsd >

</beans>
  • web.xml 설정 추가(listener)
    : ContextLoaderListener는 RootApplicationContext를 생성하는 클래스
    : 톰캣이 실행되면서 스프링컨테이너가 생성이되는것을 감지하여 WebContext도 생성이 되도록 등록.
    → 스프링 컨테이너와 웹 컨테이너의 연동구조.
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/스프링환경설정파일 이름.xml</param-value>
 </context-param>
 
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

5) DB 연동에 필요한 DataSource 구성.

: build.gradle에 등록된 DB와 HIkariCP라이브러리를 사용하기 위한 커넥션 정보를 담고있는 클래스로 해당 웹프로젝트에 적용하기위해 xml에 추가.
: 스프링이 동작하면 자동으로 web프로젝트에 연동이 되도록 스프링 환경설정 xml파일에 등록.

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="org.mariadb.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mariadb://localhost:포트번호/webdb"></property>
<property name="username" value="사용자이름"></property>
<property name="password" value="사용자이름"></property>
<property name="dataSourceProperties">
<props>
<prop key="cachePrepStmts">true</prop>
<prop key="prepStmtCacheSize">250</prop>
<prop key="prepStmtCacheSqlLimit">2048</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>

6) MyBatis 프레임워크(SQL Mapping Framework)와 스프링 연동

: MyBatis는 단독으로 실행이 가능한 프레임워크지만 mybatis-spring 라이브러리를 통해 Spring과 쉽게 통합 가능.
: SQL 실행 결과를 객체개념으로 캡슐화 해줌.
: PreparedStatement 와 ResultSet의 역할을 모두 처리.
: close() 자동처리, SQL문 자동생성(Mapper인터페이스 활용)
→ MyBatis는 인터페이스를 사용하고 코드는 Mapper인터페이스와 XML을 통해 자동생성.

─ 스프링 관련 : spring-jdbc, spring-tx
─src
└build.gradle의 SpringFramework 설정목록에
implementation group: 'org.springframework', name: 'spring-jdbc', version: '5.3.19'
implementation group: ㄹ'org.springframework', name: 'spring-tx', version: '5.3.19'
추가

─ MyBatis관련: mybatis, mybatis-spring
─src
└ build.gradle의 dependencies내
implementation 'org.mybatis:mybatis:3.5.9'
implementation 'org.mybatis:mybatis-spring:2.0.7'
추가

==> spring 환경설정파일.xml에도 추가
① 상단에
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" 추가

② xsi:schemaLocation 목록에
http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring.xsd 추가

③ SQL문 자동생성을 위한 SqlSessionFactory 설정 추가
: MyBatis의 실제 SQL 처리는 SqlSessionFactory에서 생성하는 SqlSession을 통해서 수행됨.

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />        
<!--MyBatis와 DB 를 연결해주기위해 커넥션 정보가 담긴 DataSource를 참조-->
</bean>

7) Mapper(인터페이스) 설정.

: MyBatis의 기능중 DB에 접근할때 필요한 SQL문을 간결하게 생성해주는 역할을 대신함.
: 애너테이션이나 XML로 SQL을 생성.

  • SQL 분리

① 애너테이션 : 비교적 짧은 SQL 문을 담을 때 사용
==> Mapper 인터페이스에 직접 등록.

② XML : SQL문이 길고 복잡할 경우에 사용.
==> Mapper 인터페이스에 메소드만 선언.
==> resources 폴더에 .xml파일로 메서드이름과 네임스페이스, SQL문을 등록

<?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="Mapper 인터페이스의 위치값">
    <select id="메소드이름" resultType="반환타입">
           SQL문( ; 생략 )
    </select>
</mapper>
  • 스프링과 연동을 위해 스프링환경설정 파일에 등록
    ─ sqlSessionFactory 빈에 property로 추가
<property name="mapperLocations" value="classpath:/mappers/**/*.xml"></property>

─ 여러개의 mapper를 사용하는 경우 MyBatis가 찾을 수 있도록 스캐너 등록

	<mybatis:scan base-package="net.ict.springex.mapper"/>

8) test코드 파일에 스프링설정적용및 커넥션풀 객체 등록.

: DataSource 타입 멤버변수 설정.
: @ContextConfiguration 으로 스프링 설정 파일(xml)을 지정.
: 스프링빈을 테스트 코드에서 사용하기 위해 @ExtendWith(SpringExtension.class) 애너테이션적용.

2. 웹 프로젝트내 프레임워크 및 라이브러리 활용법

빈 생성 두가지 방법

1) xml 파일에 <bean> </bean> 태그를 이용해서 생성할 빈을 넣어주기.

ex) ``<bean class=“net.ict.sample.SampleDAO"></bean>``

2) <context:component-scan>태그 설정후 빈으로 생성할 클래스에 애너테이션 적용하기.

ex) ``<context:component-scan base-package=“ict.net.springex.sample"></context:component-scan>``
  • 애너테이션으로 스프링 빈으로 관리될 객체를 표시하면서 역할 지정.
    @Controller : 서블릿
    @Service : 서비스계층
    @Repository : DAO(데이터 저장소)
    @Component : 일반 객체나 유틸리티 객체
  • 의존 주입 방식
    : Lombok의 @RequiredArgsContructor를 통해 생성자 자동생성.
    : 주입 받아야 하는 객체의 변수를 final로 작성. → 해당 변수를 생성자의 파라미터로 지정.
    : 스프링3이후 생성자 주입 방식을 더 많이 활용.
  • 인터페이스를 이용한 느슨한 결합
    : 인터페이스를 구현한 클래스를 이용해서 필요에 따라 다른 클래스를 사용함으로써 객체간 결합도를 낮춤.
    : 인터페이스를 이용한경우 클래스간 충돌이 발생하는경우가 많음. (같은 인터페이스를 구현한 클래스가 여러개 생길수 있기 때문에)

→ 이런 경우 같은 타입의 빈이 여러개가 생성이되므로 @Primary 또는 @Qualifier등을 이용해서 객체를 구분하거나 특정 클래스를 지정가능.

→ Lombok과 Qualifier를 같이 쓰려면 config 설정 파일을 추가해주어야함.
─ main ─ java 마우스 우클릭 ─ new ─ File 에 lombok.config 생성후
lombok.copyableannotations+=org.springframework.beans.factory.annotation.Qualifier 추가


Spring + Web + MVC

: Spring에서 제공하는 웹 모듈로 MVC의 구성요소를 사용해 사용자의 다양한 요청을 처리하는 Framework
: 기존의 MVC 구조에 추가적으로 Front-Controller패턴(퍼시드 패턴) 적용
: 애너테이션의 적극적인 활용. → 코드 단축
: 파라미터나 리턴 타입에 대한 자유로운 형식
: 추상화된 API들의 제공.
==> 웹어플리케이션을 유연하고 확장 가능하게 만들어줌.

1. 구조

  • DispatcherServlet (Front-Controller)
    : 모든 요청이 하나의 컨트롤러를 거치는 제일 앞단의 Controller
    : 사용자의 HTTP Request에 맞는 세분화된 Controller에게 요청을 연결해줌.
  • Handler(Controller)
    : 배정받은 HTTP Request를 처리해 Model을 만들고 View이름 지정 및 직접 반환.
    : View안에 Model의 데이터를 세팅하지는 않음.

  • Model and View
    : Controller에 의해 반환된 Model과 View가 Warpping된 객체.
    : Map<String, Value> 형태로 데이터를 저장.
    : View와 View Name만 지정.

  • ViewResolver
    : Model and View 객체를 이용하여 View그리기.
    : 사용자에게 보여줄 완성된 View를 그리며, 특정 url로 들어갔을때 보여지는 View를 의미함.

2. Spring MVC를 사용하기 위한 환경 설정.

1) servlet-context.xml

: mvc패턴에 관련된 설정등록.
: 웹과 관련된 처리를 분리하기 위해서 작성.
: 일반적으로 계층별로 분리.

<!-- 1. 스프링 MVC 설정을 애너테이션 기반으로 처리-->
<!-- 2. 스프링 MVC의 여러 객체들을 자동으로 스프링 빈으로 등록-->    
<mvc:annotation-driven></mvc:annotation-driven>

<!-- 이미지나 HTML과 같은 정적 파일의 경로 지정.-->
<mvc:resources mapping="/resources/**" location="/resources/"></mvc:resources>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"></property>       // WEB-INF/views 디렉토리에 위치한
    <property name="suffix" value=".jsp"></property>                // .jsp 확장자 타입의 파일을 사용자에게 전달할 View로 등록.
</bean>    
<context:component-scan base-package="net.ict.springex.controller"/>

2) web.xml

: web application(웹서비스)에 대한 설정.
: DispatcherServlet = FrontController에 대한 환경설정 등록.

<!--FrontController의 이름지정 및 기본설정내용이 담긴 파일의 위치등록.-->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/servlet-context.xml</param-value>
    </init-param>

    <!--tomcat 로딩시에 클래스를 미리 로딩한다는 뜻. -->
    <load-on-startup>1</load-on-startup>

</servlet>
<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>      // 모든 경로에서 오는 요청을 다 받음.
</servlet-mapping>

3. Spring MVC 에서의 애너테이션 활용

1) 컨트롤러선언부에 사용하는 애너테이션

  • @Controller : 빈으로 사용되는 클래스임을 명시.
  • @RestController : REST 방식의 처리를 위한 컨트롤러. 객체를 Json 형태로 ResponseEntity로 감싸서 반환.
  • @RequestMapping : 특정 URL 패턴에 작동하는 컨트롤러를 명시. 웹 request와 연결. 여러경로를 한번에 처리.
  • @ControllerAdvice : 예외처리 클래스임을 명시. 클래스 선언부에 사용.

2) 메소드 선언부에 사용하는 애너테이션

  • @GetMapping : get 방식 요청을 처리.
  • @PostMapping : post 방식 요청을 처리.
  • @DeleteMapping : 기존의 정보를 삭제하는 delete를 위한 요청을 처리.
  • @PutMapping/@PatchMapping : 기존의 정보를 수정하는 update를 위한 요청을 처리.
  • @RequestMapping : 특정 URL 패턴에 작동하는 컨트롤러를 명시. 웹 request와 연결.
  • @ResponseBody : view 페이지가 아닌 반환값 그대로 클라이언트한테 return 하고 싶은 경우에 사용.
  • @ExceptionHandler : 어떤 예외상황일때 처리될지 연결하고 등록. 예외처리 메소드 선언부에 사용.

3) 메소드의 파라미터에 사용하는 애너테이션 (파라미터 자동 수집 및 변환)

  • @RequestParam :파라미터의 이름을 지정하거나 기본값을 지정할 수 있음. HttpServletRequest와 같은 역할.
  • @PathVariable : url 경로에 변수를 바로 넣어주는 역할. 메소드 선언부에 정의된 변수와 똑같이 사용.
  • @ModelAttribute : 파라미터로 넘겨준 타입(getter/setter가 있는 Bean객체)의 객체를 자동으로 생성→ 자동 바인딩 → 자동으로 model객체가되어 view까지 전달.

4. 특별한 파라미터 Model

: request.setAttribute() 와 같은 기능
: 메소드의 파라미터에 Model을 선언하면 자동으로 객체 생성
: addAttribute()를 이용해서 view까지 전달할 객체 저장.

5. RedirectAttributes

: redirect시에 필요한 쿼리 스트링을 구성해주는 객체.(스프링MVC에서 제공)
: 스프링 MVC 경우 반환 타입이 문자열이며, "redirect :" 로 시작하는 경우 명시한 페이지로 바로 이동하도록 처리.
: POST 방식으로 처리하고 Redirect를 통해 Get방식으로 특정페이지로의 이동을 처리하는 패턴. ==> " PRG(Post - Redirect - Get) 패턴 "
: POST 방식으로 전달된 데이터를 Redirect를 통해 남기지 않기 위함.
: 다양한 리턴타입 사용 가능 = void, String, ResponseEntity,배열, 컬렉션 등.

=> addAttribure(키, 값) : redirect시에 쿼리스트링으로 전달될 값.
=> addFlashAttribute(키, 값) : 일회성으로 전달되는 값으로 보여지지 않음.

6. 스프링MVC 예외처리

1) @ControllerAdvice

: 모든 @Controller 에서 부가적인 기능(예외처리, 바인딩설정, 모델객체 설정 등)을 적용하고 싶을때 사용
: Controller에서 전역에서 발생할 수 있는 예외를 한 곳에서 관리하고 처리할수 있게 도와줌.

2) @ExceptionHandler

: @Contoller, @RestController(Json형태로 객체를 반환)가 적용된 빈 내에서 발생하는 예외를 하나의 메소드에서 처리해주는 기능.
: 메소드 선언부에 적용하며, 지정한 예외가 발생하는지 감시하고 발생하면 예외처리를 해줌.
: 두개이상 등록도 가능하며, Controller 또는 RestController에만 적용가능함.
: 리턴타입은 자유롭게 사용가능하며, 파라미터로 받아오는 Exception또한 자유롭게 받기가 가능.

servlet-context.xml, root-context.xml, web.xml 차이점
XML : 객체(bean)를 정의하는 설정 파일.

  • servlet-contex.xml
    : servlet에서 보듯이 요청(Request)과 관련된 객체를 정의
    : url과 관련된 controller나, @(어노테이션), ViewResolver, Interceptor, MultipartResolver 등의 설정을 등록.

  • root-contex.xml
    : servlet-context.xml 과는 반대로 view와 관련되지 않은 객체를 정의
    : Service, Repository(DAO), DB등 비즈니스 로직과 관련된 설정을 등록

  • web.xml
    : 설정을 위한 설정파일
    : WAS가 최초로 구동될 때, 각종 설정을 정의해줌.
    : 여러 xml파일을 인식하도록 각 파일을 가리켜 주는 역할.

0개의 댓글