[Spring Framework] SpringMVC + Gradle 템플릿 + Tomcat 연동
ITWeb/개발일반 2018. 5. 2. 18:33매니저 역할을 오래 하다 보면 개발 감각이 떨어 지는건 어쩔수 없는 일인 것 같습니다.
SpringMVC 를 이용한 기본 웹 개발도 이제는 거북이 수준이 되어 가고 있는 것 같아 잊지 않기 위해 기록해 봅니다.
요즘 워낙 좋은 Tool, IDE 들이 많이 나와 있고. Git 검색만 해봐도 찾던 소스가 너무나도 많이 나옵니다.
아래는 Intellij community 버전을 이용해서 웹프로젝트 템플릿을 생성하는 예제 입니다.
각 단계별 코드별 설명은 작성 하지 않았습니다.
이유는 여긴 제가 그냥 혼자 기록하고 공부하는 공간이고, 누구를 가르치기에 너무 많은 무림고수 들이 계셔서 어쭙잖은 설명은 그냥 아래 레퍼런스로 대신 합니다.
References)
https://github.com/HowookJeong/springmvc-gradle-template
https://tomcat.apache.org/tomcat-9.0-doc/config/context.html
https://docs.spring.io/spring/docs/4.3.16.RELEASE/spring-framework-reference/htmlsingle/#spring-web
Step 1)
Intellij 를 실행 하고 매뉴에서 아래와 같이 선택을 합니다.
File -> New -> Project -> Gradle -> Java -> Next
GroupId -> org.project.web
ArtifactId -> springmvc-gradle-template
Next
Step 2)
SpringMVC Framework 틀을 만들기 위해 필요한 폴더와 파일들을 아래와 같이 생성을 합니다.
2-1) Community 버전으로는 gradle webapp 추가가 안되기 때문에 별도로 생성 합니다.
Make webapp directory
src/main/webapp
2-2) Make WEB-INF directory
src/main/webapps/WEB-INF
web.xml
dispatcher-servlet.xml
2-3) jsp template 사용을 위해서 WEB-INF 아래 jsp 폴더를 생성 합니다.
Make jsp directory
src/main/webapps/WEB-INF/jsp
2-4) Resource 구성을 합니다.
Make resources directory
src/main/resources/beans
bo-bean.xml
dao-bean.xml
src/main/resources/context
applicationContext.xml
applicationContext-mybatis.xml
src/main/resources/mybatis
config.xml
jdbc.properties
src/main/resources/sql
example.xml
log4j.xml
2-5) Package 구성을 합니다.
Make packages
org.project.web.bo
org.project.web.controllor
org.project.web.dao
org.project.web.model
여기까지 하셨으면 기본 empty project 생성은 끝났습니다.
이제 필요한 코드와 설정을 해보도록 하겠습니다.
Step 3)
이제 필요한 코드들을 생성해 보도록 하겠습니다.
3-1) web.xml 설정하기
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="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_3_0.xsd"
id="WebApp_ID">
<display-name>springmvc-gradle-template</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:context/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3-2) dispatcher-servlet.xml 설정하기
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
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
http://www.springframework.org/schema/util
http://www.springframework.org/schema/spring-util.xsd">
<mvc:resources mapping="/resources/**" location="/resources/"/>
<mvc:annotation-driven/>
<context:annotation-config/>
<context:component-scan base-package="org.project.web"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3-3) log4j.xml 설정하기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- console appender -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<!-- file appender -->
<appender name="file" class="org.apache.log4j.RollingFileAppender">
<param name="append" value="true"/>
<param name="maxFileSize" value="10MB"/>
<param name="maxBackupIndex" value="15"/>
<param name="file" value="logs/indexer.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<!-- Application Loggers -->
<logger name="org.spring.web">
<level value="debug"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="debug"/>
<appender-ref ref="console"/>
<!--<appender-ref ref="file"/>-->
</root>
</log4j:configuration>
3-4) mybatis/config.xml 설정하기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"HTTP://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="enhancementEnabled" value="false"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25000"/>
<setting name="defaultListResultHandlerType" value="java.util.ArrayList"/>
<setting name="defaultMapResultHandlerType" value="java.util.HashMap"/>
</settings>
</configuration>
3-5) mybatis/jdbc.properties 설정하기
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/
jdbc.username=root
jdbc.password=
3-6) build.gradle 설정하기
apply plugin: 'java'
apply plugin: 'war'
apply plugin: "com.bmuschko.tomcat"
group = 'org.project.web'
version = '1.0-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
repositories {
maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
def tomcatVersion = '7.0.59'
def springVersionn = '4.3.16.RELEASE'
def elasticsearchVersion = '6.2.4'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}"
compile group: 'org.springframework', name: 'spring-core', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-context', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-beans', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-web', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-webmvc', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-aop', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-context-support', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-aspects', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-tx', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-jdbc', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-orm', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-expression', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-jms', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-oxm', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-webmvc-portlet', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-messaging', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-websocket', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-instrument', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-instrument-tomcat', version: "${springVersionn}"
compile group: 'org.springframework', name: 'spring-test', version: "${springVersionn}"
compile group: 'org.mybatis', name: 'mybatis', version: '3.4.0'
compile group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.0'
compile group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.38'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.6.2'
compile group: 'javax.inject', name: 'javax.inject', version: '1'
compile group: 'javax.servlet', name: 'jstl', version: '1.2'
compile group: 'org.elasticsearch', name: 'elasticsearch', version: "${elasticsearchVersion}"
compile group: 'org.elasticsearch.client', name: 'transport', version: "${elasticsearchVersion}"
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.7.3'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.7.3'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.7.3'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
runtime group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.2'
runtime group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.6.2'
runtime(group: 'log4j', name: 'log4j', version: '1.2.17') {
exclude(module: 'mail')
exclude(module: 'jms')
exclude(module: 'jmxtools')
exclude(module: 'jmxri')
}
testCompile group: 'junit', name: 'junit', version: '4.8.2'
// providedCompile group: 'org.apache.tomcat.maven', name: 'tomcat7-maven-plugin', version:'2.2'
providedCompile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
providedCompile group: 'javax.servlet.jsp', name: 'jsp-api', version: '2.2'
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-tomcat-plugin:2.2.5'
}
}
tomcatRunWar.contextPath = '/'
tomcatRun.contextPath = '/'
이제 application 구현을 위한 코드 생성을 해보겠습니다.
3-7) controller/ExampleController
package org.project.web.controller;
import java.util.Locale;
import org.project.web.bo.ExampleBO;
import org.project.web.model.ExampleModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class ExampleController {
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
@Autowired
private ExampleBO exampleBO;
@RequestMapping(value = "/example", method = RequestMethod.GET)
public String exampleView(Locale locale, Model model) {
ExampleModel exampleModel = exampleBO.getExample();
model.addAttribute("user", exampleModel.getUser());
model.addAttribute("authenticationString", exampleModel.getAuthenticationString());
return "exampleView";
}
}
3-8) bo/ExampleBO
package org.project.web.bo;
import org.project.web.model.ExampleModel;
public interface ExampleBO {
ExampleModel getExample();
}
3-9) bo/ExampleBOImpl
package org.project.web.bo;
import javax.annotation.Resource;
import org.project.web.dao.ExampleDAO;
import org.project.web.model.ExampleModel;
import org.springframework.stereotype.Service;
@Service("exampleBO")
public class ExampleBOImpl implements ExampleBO {
@Resource(name="exampleDAO")
private ExampleDAO exampleDAO;
public ExampleModel getExample() {
return exampleDAO.getExample();
}
}
3-10) dao/ExampleDAO
package org.project.web.dao;
import org.project.web.model.ExampleModel;
public interface ExampleDAO {
ExampleModel getExample();
}
3-11) dao/ExampleDAOImpl
package org.project.web.dao;
import org.apache.ibatis.session.SqlSession;
import org.project.web.model.ExampleModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("exampleDAO")
public class ExampleDAOImpl implements ExampleDAO {
@Autowired
private SqlSession sqlSession;
public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
public ExampleModel getExample() {
ExampleModel exampleModel = sqlSession.selectOne("getExample");
return exampleModel;
}
}
3-12) model/ExampleModel
package org.project.web.model;
public class ExampleModel {
String user;
String authenticationString;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getAuthenticationString() {
return authenticationString;
}
public void setAuthenticationString(String authenticationString) {
this.authenticationString = authenticationString;
}
}
코드 구현을 했으니 이제 resources 설정을 하도록 하겠습니다.
3-13) beans/bo-bean.xml
<?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">
<bean id="exampleBO" class="org.project.web.bo.ExampleBOImpl"/>
</beans>
3-14) beans/dao-bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="exampleDAO" class="org.project.web.dao.ExampleDAOImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
3-15) context/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- import -->
<import resource="classpath:context/applicationContext-mybatis.xml"/>
<import resource="classpath:beans/bo-bean.xml"/>
<import resource="classpath:beans/dao-bean.xml"/>
</beans>
3-16) context/applicationContext-mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:mybatis/jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath*:sql/**/*.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.project.web.mapper"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
</beans>
3-17) sql/example.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="org.project.web">
<select id="getExample" resultType="org.project.web.model.ExampleModel">
SELECT user, authentication_string authenticationString
FROM mysql.user
WHERE host='localhost'
AND user='root'
</select>
</mapper>
화면 구성을 위한 데코레이션으로 jsp 코드를 작성해 보겠습니다.
3-18) WEB-INF/jsp/exampleView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<title>SpringMVC Gradle Template Example</title>
</head>
<body>
User : ${user} / Authentication String : ${authenticationString}
<br>
User : <c:out value="${user}" /> / Authentication String : <c:out value="${authenticationString}" />
</body>
</html>