Post

Spring : Maven Project MVC 기본적인 틀 만들기

Spring : Maven Project MVC 기본적인 틀 만들기

Maven Project MVC 기본적인 틀 만들기

boostcourse 강의를 듣고 혼자 실습하다가.. 틀 만드는 것 부터 너무 복잡해서 정리를 해놔야겠단 생각에 포스팅합니다..!!

프로젝트 만들기

  1. File -> New -> Maven Project
  2. Use default Workspace location에 체크되어 있는 상태로 놔두고 Next

  3. Grup Idorg.apache.maven.archetypes이고 Artifact Idmaven-archetype-webapp인 Archetype을 선택하고 Next

  4. 원하는 Group IdArtifact Id를 설정후 Finish

pom.xml 설정하기

다양한 라이브러리를 가져와서 사용할 수 있지만 일단은 제가 사용했던 pom.xml을 가져오겠습니다.

설정을 추가하면 프로젝트 오른쪽 클릭 -> Maven -> Update Project 를 반드시 해주야합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>kr.or.connect</groupId>
  <artifactId>reservation</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>reservation Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!-- pom.xml 내에서 상수처럼 사용할 수 있습니다. -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <!-- Eclipse에서는 web.xml 파일을 작성하지 않고, Java Config를 사용할 때 failOnMissingWebXml를 false로 설정합니다. -->
    <failOnMissingWebXml>false</failOnMissingWebXml>
    <spring.version>5.2.3.RELEASE</spring.version>
    <jackson2.version>2.8.6</jackson2.version>
    <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>  
  </properties>

  
  <dependencies>
      <!-- junit  -->
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
      </dependency>
      
      
      <!-- Mock -->
      <dependency>
          <groupId>org.mockito</groupId>
          <artifactId>mockito-core</artifactId>
          <version>1.9.5</version>
          <scope>test</scope>
      </dependency>
      <!-- Mock에서 jsonpath를 이용할 수 있게 합니다. -->
      <dependency>
          <groupId>com.jayway.jsonpath</groupId>
          <artifactId>json-path</artifactId>
          <version>2.4.0</version>
      <dependency>
          
      <!-- spring -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- spring webmvc에 대한 의존성을 추가합니다.
      spring webmvc에 대한 의존성을 추가하게 되면 spring-web, spring-core등이 자동으로 의존성이 추가됩니다.-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- jUnit을 확장한 스프링의 테스트 라이브러리 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
      </dependency>
          
          
      <!-- Spring Security -->
      <!-- Spring Security Core -->
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-core</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- Spring Security Config -->
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-config</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- Spring Security Web -->
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-web</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- Spring Security JSP Custom Tags -->
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-taglibs</artifactId>
          <version>${spring.version}</version>
      </dependency>
      
          
      <!-- servlet -->
      <!-- servlet-api이다. tomcat에 배포될 경우엔 사용되지 않도록 하기 위해서 scope를 provided로 설정하였습니다. -->
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
      </dependency>
      <!-- jsp-api이다. tomcat에 배포될 경우엔 사용되지 않도록 하기 위해서 scope를 provided로 설정하였습니다. -->
      <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>javax.servlet.jsp-api</artifactId>
          <version>2.3.1</version>
          <scope>provided</scope>
      </dependency>
          
          
      <!-- jstl -->
      <!-- jstl은 tomcat이 기본 지원하지 않습니다. 그렇기 때문에 tomcat에도 배포가 되야 합니다.-->
      <dependency>
          <groupId>jstl</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>
          
          
      <!-- JDBC -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- 트랜잭션을 사용하기 위한 설정입니다. -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-tx</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- basic data source -->
      <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-dbcp2</artifactId>
          <version>2.1.1</version>
      </dependency>
      <!-- JDBC에서 mysql을 사용하기 위한 설정입니다. -->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.45</version>
      </dependency>
          
          
      <!-- jackson -->
      <!-- RestController의 json 변환을 위해 필요합니다 -->
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.9.8</version>
      </dependency>
      <!-- jackson-core 및 jackson-annotation 라이브러리의 의존성을 포함 -->
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>${jackson2.version}</version>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.datatype</groupId>
          <artifactId>jackson-datatype-jdk8</artifactId>
          <version>${jackson2.version}</version>
      </dependency>
          
          
      <!-- Lombok과 mapstruct를 같이 사용할 경우, Lombok이 먼저 와야 합니다. -->
      <!-- Lombok -->
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.20</version>
          <scope>provided</scope>
      </dependency>
          
          
      <!-- mapstruct -->
      <dependency>
          <groupId>org.mapstruct</groupId>
          <artifactId>mapstruct</artifactId>
          <version>${org.mapstruct.version}</version>
      </dependency>

          
      <!-- hibernate-validator -->
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-validator</artifactId>
          <version>6.1.0.Final</version>
      </dependency> 
          
          
      <!-- java 9 이상에서 추가해줘야 합니다. @PostConstruct 등을 사용하려면 필요합니다-->
      <dependency>
          <groupId>javax.annotation</groupId>
          <artifactId>javax.annotation-api</artifactId>
          <version>1.3.2</version>
      </dependency>
          
          
      <!-- swagger2 의존성 추가. Swagger 사용을 위해서는 구현체인 springfox-swagger2 가 필요 -->
      <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger2</artifactId>
          <version>2.6.1</version>
      </dependency>
      <!--  또 가장 중요한 (사용목적이라해도 과언이 아닌) UI 적으로 확인을 위해서는 springfox-swagger-ui 라이브러리가 필요합니다. -->
      <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger-ui</artifactId>
          <version>2.6.1</version>
      </dependency>
  </dependencies>

  <build>
    <finalName>reservation</finalName>
      <plugins>
      
      	<!-- maven 버전 설정을 위한 플러그인 입니다.-->
      	<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                
                <!-- mapstruct-processor을 설정해줍니다. -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                    <!-- other annotation processors -->
                </annotationProcessorPaths>
                
                <!-- Lombok 의존성을 설정해도 사용되지 않을 경우. 아래의 부분을 추가 -->
                <annotationProcessors>
                    <annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
                </annotationProcessors>
            </configuration>
          </plugin>
      	
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
  </build>
</project>

MapStruct와 Lombok을 같이 사용하게 되면, 의존성 설정할 때 순서를 신경써주어야 합니다.

또, pluginManagement와 plugins의 차이와 주의할 점에 대해서도 알아야합니다.

MapStruct 의존성 설정 포스트 링크(MapStruct 사용법 및 ModelMapper와의 비교 내용도 포함)

Lombok의 사용법 및 주의점 포스트 링크

pluginManagement와 plugins의 차이와 주의할 점 포스트 링크

Servlet 버전 설정하기

자바 어노테이션을 사용하기위해 Servlet 버전을 3.0이상으로 바꿔줍니다.

  1. web.xml 위쪽에 버전이 있는 부분을 삭제합니다.
1
2
3
4
<!--<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" > 이 부분을 삭제--> 
<?xml version="1.0" encoding="UTF-8"?> <!-- 이부분을 추가해줍니다. -->
  1. Navigator -> .settings -> org.eclipse.wst.common.project.facet.core.xml에서 jst.web 부분의 버전을 원하는 버전으로 바꿔줍니다.
  2. Eclipse를 재시작합니다.

DataBase 만들기

DataBase 명령어를 참고해 DB 계정을 만듭니다.

src/main/resources/application.properties 파일에 다음과 같이 설정합니다.

1
2
3
4
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://domain:port/dbName?useUnicode=true&characterEncoding=utf8
spring.datasource.username=dbUserName
spring.datasource.password=dbPasswd

application.properties는 스프링 사용시 필요한 옵션들을 작성하여 추가할 수 있습니다. 예를 들면 메일 서버를 구축한다던가 혹은 db의 종류를 설정, 로그사용여부 등을 설정이 가능합니다. 이 후, 아래와 같이 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
@PropertySource("classpath:application.properties")
public class DBConfig implements TransactionManagementConfigurer {
	
	@Autowired
	Environment env;
	
	private String driverClassName = env.getProperty("spring.datasource.driver-class-name");
	private String url = env.getProperty("spring.datasource.url");
	private String username = env.getProperty("spring.datasource.username");
	private String password = env.getProperty("spring.datasource.password");
    
    ...
}

Environment시스템 환경변수 , JVM 시스템 프로퍼티 , 프로퍼티 파일 등의 프로퍼티PropertySource라는 것으로 통합관리합니다.

Environment란?

DispatcherServlet을 FrontController로 설정하기

설명이 필요하기 때문에 링크로 대체하겠습니다.

WebApplicationInitializer / AbstractAnnotationConfigDispatcherServletInitializer

Controller 작성하기

간단한 컨트롤러를 만들어서 테스트 해봅니다.

Controller작성하기

JDBC 연결하기

JDBC 연결하기

Layered Architecture를 보면 DispatcherServlet과 나머지 부분을 분리하여 사용하는게 좋다고 했습니다.

DispatcherServlet을 경우에 따라서 2개 이상 설정할 수 있는데 이 경우에는 각각의 DispathcerServletApplicationContext가 각각 독립적이기 때문에 각각의 설정 파일에서 생성한 빈을 서로 사용할 수 없습니다.

위의 경우와 같이 동시에 필요한 빈은 ContextLoaderListener를 사용함으로써 공통으로 사용하게 할 수 있습니다.

ContextLoaderListener의 설정은 DispatcherServlet을 FrontController로 설정하기에 포함되어 있습니다.

그 외에 프로젝트 진행 시 유용한 자료들

Mapping 및 객체

Entity, VO, DTO의 차이

생성자 주입을 사용해야 하는 이유

Lombok의 사용법 및 주의점

MapStruct의 사용법 및 ModelMapper와의 비교

ResponseEntity를 사용해야 하는 이유

직렬화, 역직렬화

Jackson Annotation 사용법

직렬화 : 자바 객체를 전송가능한 Json형태로 만들어주는 것을 의미

역직렬화 : 직렬화한 Json 데이터들을 자바 객체로 변환하는 것을 의미

유효성 검사

유효성 검사(Validation) 방법 및 Custom Annotation

예외처리

Exception 전략

Security

Spring Security란? (설정 포함)

Spring Security를 이용한 로그인 및 로그아웃

Spring Security에서 DB를 이용한 로그인 및 회원가입

테스트

MockMvc를 이용한 단위 테스트

Given-When-Then 패턴

Web API 문서화를 위한 Swagger

Spring MVC에서 Swagger 사용하기

기타

Cookie / Session


여기까지 했으면 안에 내용을 구현해서 멋진 프로젝트를 만듭니다! 추후에 알게되는 것이 있으면 계속 추가하겠습니다!

This post is licensed under CC BY 4.0 by the author.