Home > Spring > ๐Ÿƒ[Spring] Spring Boot๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML, CSS, JS๋กœ ๋งŒ๋“  Frontend ํŽ˜์ด์ง€๋ฅผ ๋กœ์ปฌ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ์š”?

๐Ÿƒ[Spring] Spring Boot๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML, CSS, JS๋กœ ๋งŒ๋“  Frontend ํŽ˜์ด์ง€๋ฅผ ๋กœ์ปฌ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ์š”?
Spring Framework

๐Ÿƒ[Spring] Spring Boot๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML, CSS, JS๋กœ ๋งŒ๋“  Frontend ํŽ˜์ด์ง€๋ฅผ ๋กœ์ปฌ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ์š”?

  • Spring Boot๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML, CSS, JavaScript๋กœ ๋งŒ๋“  ํ”„๋ŸฐํŠธ์—”๋“œ ํŽ˜์ด์ง€๋ฅผ ๋กœ์ปฌ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ๊ณ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ณผ์ •์—์„œ๋Š” ์ •์  ๋ฆฌ์†Œ์Šค๋ฅผ Spring Boot ํ”„๋กœ์ ํŠธ์— ํฌํ•จํ•˜๊ณ , ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ •์ ํŽ˜์ด์ง€๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

1๏ธโƒฃ Spring Boot ํ”„๋กœ์ ํŠธ์— ์ •์  ํŒŒ์ผ ์ถ”๊ฐ€.

  • HTML, CSS, JavaScript ํŒŒ์ผ์€ Spring Boot ํ”„๋กœ์ ํŠธ์˜ ์ •์  ๋ฆฌ์†Œ์Šค ๋””๋ ‰ํ† ๋ฆฌ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ‘‰ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ.

src
 โ””โ”€โ”€ main
     โ”œโ”€โ”€ java
     โ”‚    โ””โ”€โ”€ com.example.demo (ํŒจํ‚ค์ง€ ๊ตฌ์กฐ)
     โ”‚         โ””โ”€โ”€ DemoApplication.java
     โ”œโ”€โ”€ resources
     โ”‚    โ”œโ”€โ”€ static
     โ”‚    โ”‚    โ”œโ”€โ”€ css
     โ”‚    โ”‚    โ”‚    โ””โ”€โ”€ styles.css
     โ”‚    โ”‚    โ”œโ”€โ”€ js
     โ”‚    โ”‚    โ”‚    โ”œโ”€โ”€ scripts.js
     โ”‚    โ”‚    โ”‚    โ””โ”€โ”€ login-scripts.js
     โ”‚    โ”‚    โ”œโ”€โ”€ signup.html
     โ”‚    โ”‚    โ””โ”€โ”€ login.html
     โ”‚    โ””โ”€โ”€ templates (ํ•„์š”ํ•œ ๊ฒฝ์šฐ Thymeleaf ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ)
     โ””โ”€โ”€ application.properties
  • static ๋””๋ ‰ํ† ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ •์  ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ, ์—ฌ๊ธฐ์„œ CSS, JavaScript, ์ด๋ฏธ์ง€ ๋ฐ HTML ํŒŒ์ผ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • HTML ํŒŒ์ผ(signup.html, login.html)์€ ์ง์ ‘ static ๋””๋ ‰ํ† ๋ฆฌ์— ๋ฐฐ์น˜ํ•˜์—ฌ ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ์ง์ ‘ ๋กœ๋“œ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ Spring Boot ์ปจํŠธ๋กค๋Ÿฌ ์„ค์ •.

  • Spring Boot ์—์„œ /login๊ณผ /signup ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ฐ„๋‹จํ•œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class AuthController {
    
    @GetMapping("/login")
    public String loginPage() {
        return "login.html"; // static/login.html ํŒŒ์ผ์„ ๋ฐ˜ํ™˜
    }
    
    @GetMapping("/signup")
    public String signupPage() {
        return "signup.html"; // static/signup.html ํŒŒ์ผ์„ ๋ฐ˜ํ™˜
    }
}

3๏ธโƒฃ ์ •์  ํŒŒ์ผ ๋ฐ ์ž์› ์ ‘๊ทผ

  • HTML ํŒŒ์ผ์—์„œ CSS ๋ฐ JavaScript ํŒŒ์ผ์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ Spring Boot์—์„œ ์ œ๊ณตํ•˜๋Š” ์ •์  ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๋Œ€๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ‘‰ login.html(์˜ˆ์‹œ)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
    <link rel="stylesheet" href="/css/styles.css"> <!-- ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋กœ ์ˆ˜์ • -->
</head>
<body>
    <div class="login-container">
        <form id="loginForm" class="login-form">
            <h2>Login</h2>
            <div class="input-group">
                <label for="login-email">Email</label>
                <input type="email" id="login-email" name="login-email" required>
            </div>
            <div class="input-group">
                <label for="login-password">Password</label>
                <input type="password" id="login-password" name="login-password" required>
            </div>
            <button type="submit">Login</button>
            <p class="signup-link">Don't have an account? <a href="/signup">Sign up here</a></p> <!-- Spring Boot ๊ฒฝ๋กœ ์‚ฌ์šฉ -->
        </form>
    </div>
    <script src="/js/login-scripts.js"></script> <!-- ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋กœ ์ˆ˜์ • -->
</body>
</html>

4๏ธโƒฃ Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰

  • ์ด์ œ Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋ฉด ๋กœ์ปฌ ์„œ๋ฒ„์—์„œ /login ๋ฐ /signup ๊ฒฝ๋กœ๋กœ ์ ‘๊ทผํ•˜์—ฌ ํ”„๋ŸฐํŠธ์—”๋“œ ํŽ˜์ด์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘‰ ์• ํ”Œ๋ฆฌ๊ฒŒ์ด์…˜ ์‹คํ–‰ ๋ช…๋ น์–ด

./gradlwe bootRun #Gradle ์‚ฌ์šฉ์‹œ
mvn spring-boot:run # Maven ์‚ฌ์šฉ์‹œ

5๏ธโƒฃ ์ถ”๊ฐ€ ์„ค์ •(ํ•„์š”ํ•œ ๊ฒฝ์šฐ)

1๏ธโƒฃ CORS ์„ค์ •

  • ํ”„๋ŸฐํŠธ์—”๋“œ ํŽ˜์ด์ง€์—์„œ ๋‹ค๋ฅธ ์„œ๋ฒ„์˜ API์— ์ ‘๊ทผํ•˜๋ ค๋ฉด CORS ์„ค์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • WebMvcConfigurer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:8080")
                        .allowedMethods("GET", "POST", "PUT", "DELETE");
            }
        };
    }
}

๐Ÿ“ CORS(Cross-Origin Resource Sharing)

์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ํ˜ธ์ŠคํŒ… ๋˜๋Š” ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ณด์•ˆ์ƒ์˜ ์ด์œ ๋กœ, ํ•œ ๋„๋ฉ”์ธ์—์„œ ๋กœ๋“œ๋œ ์›น ํŽ˜์ด์ง€๊ฐ€ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ โ€œ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same-Origin-Policy)โ€๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ API์™€ ์—ฐ๊ฒฐ.

  • ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž… ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฑ์—”๋“œ API๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, /login API๋ฅผ ๋งŒ๋“ค์–ด JavaScript์—์„œ ํ•ด๋‹น API๋กœ AJAX ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“ AJAX(Asynchronous JavaScript and XML)

์›น ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๊ณ  ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ์„œ๋ฒ„์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ์ˆ ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.
์›น ํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ๋” ๋น ๋ฅด๊ณ  ์ง๊ด€์ ์ธ ๊ฒฝํ—˜์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

6๏ธโƒฃ ์š”์•ฝ.

  • Spring Boot ํ”„๋กœ์ ํŠธ์˜ static ๋””๋ ‰ํ† ๋ฆฌ์— HTML, CSS, JavaScript ํŒŒ์ผ์„ ๋„ฃ์–ด ์ •์  ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด /login ๋ฐ /signup ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•˜๊ณ  HTML ํŒŒ์ผ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
  • JavaScript ์ฝ”๋“œ๋Š” ํ”„๋ŸฐํŠธ์—”๋“œ์—์„œ ํ•„์š”ํ•œ ๋™์ž‘์„ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์ถ”๊ฐ€๋กœ API๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.