반응형

기본 설정

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.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.spring</groupId>
    <artifactId>spring-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-example</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <maven.test.skip>true</maven.test.skip>
        <!-- <tomcat.version>9.0.31</tomcat.version> --><!-- spring boot 내장 톰캣 버전 설정 -->
    </properties>

    <build>
        <finalName>${project.name}</finalName>
        <!-- <directory>${project.basedir}/deploy</directory> --><!-- output dir 설정, 디폴트는 target 디렉토리 -->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

application.yml

  • 경로 : ~/src/main/resource/application.yml
server:
  port: 8080

logging:
  config: classpath:${spring.profiles.active}/logback.xml

spring:
  profiles:
    active: local
  config:
    import:
      - classpath:${spring.profiles.active}/app.yml

app.yml

  • 경로 : ~/src/main/resource/local/app.yml
app:
  name: springboot-example-local
  desc: springboot-example-local
  • 경로 : ~/src/main/resource/dev/app.yml
app:
  name: springboot-example-dev
  desc: springboot-example-dev

logback.xml

  • 경로 : ~/src/main/resource/local/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <logger name="com.example" level="INFO"/>

    <root level="INFO">
        <appender-ref ref="consoleAppender"/>
    </root>
</configuration>
  • 경로 : ~/src/main/resource/dev/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/home/ubuntu/logs/springboot-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <logger name="com.example" level="INFO"/>

    <root level="INFO">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="fileAppender"/>
    </root>
</configuration>

Student

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {
    private String name;
    private String email;
}

StudentController

@RestController
public class StudentController {
    @GetMapping("/api/students")
    public List<Student> getStudents() {
        return List.of(
            new Student("john", "john@example.com"),
            new Student("tom", "tom@example.com")
        );
    }
}

maven 빌드

mvn clean package

실행

java -jar -Dspring.profiles.active=dev springboot-example.jar

요청 및 응답

curl http://localhost:8080/api/students
[{"name":"john","email":"john@example.com"},{"name":"tom","email":"tom@example.com"}]

Thymeleaf 사용하기

pom.xml

<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

이미지 추가

  • 경로 : ~/src/main/resources/static/images/home.png

home.html

  • 경로 : ~/src/main/resources/templates/home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>spring-example</title>
</head>
<body>
<h1>Welcome to...</h1>
<img th:src="@{/images/home.png}"/>
</body>
</html>

HomeController

@Controller
public class HomeController {
    @GetMapping("/")
    public String home() {
        return "home";
    }
}

HomeControllerTest

import com.example.spring.controller.HomeController;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(HomeController.class)
public class HomeControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @SneakyThrows
    @Test
    public void testHomePage() {
        mockMvc.perform(get("/"))
                .andExpect(status().isOk())
                .andExpect(view().name("home"))
                .andExpect(content().string(containsString("Welcome to...")));
    }
}

JSP 사용하기

pom.xml

<!-- war로 패키징하지 않으면 jsp 파일이 함께 패키징되지 않음 -->
<packaging>war</packaging>

<dependencies>
    <!-- jsp live reload -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    <!-- jsp, servlet, jstl -->
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>
</dependencies>

application.yml

spring:
  devtools:
    livereload:
      enabled: true # 서버 재시작 없이 jsp 수정 사항 실시간 반영
  mvc:
    view:
      prefix: /WEB-INF/jsp/
      suffix: .jsp

MainController

@Controller
public class MainController {
    @Value("${spring.profiles.active}")
    private String profile;

    @GetMapping("/main")
    public String main(HttpServletRequest request) {
        request.setAttribute("profile", profile);
        request.setAttribute("names", List.of("john", "tom", "jane"));
        request.setAttribute("date", "2020-01-01");
        return "main";
    }
}

style.css

  • ~/src/main/webapp/css/style.css
  • /webapp 하위 경로는 브라우저에서 바로 접근 가능
* {
    font-size: 15px;
}

main.jsp

  • ~/src/main/webapp/WEB-INF/jsp/main.jsp
  • /webapp/WEB-INF 하위 경로는 브라우저에서 바로 접근 불가
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>Main</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div>${profile}</div>
<div>
    <c:if test="${profile eq 'local'}">
        local
    </c:if>
    <c:if test="${profile ne 'local'}">
        not local
    </c:if>
</div>
<div>date :
    <fmt:parseDate value="${date}" var="parsedDate" pattern="yyyy-MM-dd"/>
    <fmt:formatDate value="${parsedDate}" pattern="yyyy.MM.dd"/>
</div>
<ul>
    <c:forEach items="${names}" var="name" varStatus="status">
        <li>${status.index} - ${name}</li>
    </c:forEach>
</ul>
</body>
</html>

maven 빌드

mvn clean package

실행

java -jar -Dspring.profiles.active=local springboot-example.war

서버 실행 후 접속

반응형

'Development > Spring' 카테고리의 다른 글

[Spring] BeanFactory & ApplicationContext  (0) 2020.12.27
[Spring] Paging  (0) 2020.12.27
[Spring] FileDownload  (0) 2020.12.27
[Spring] Spock Test  (0) 2020.12.27
[Spring] Controller  (0) 2020.12.27

+ Recent posts