Spring Boot를 백엔드로 사용하면서 React를 프론트엔드로 통합하는 방법을 정리합니다.

JSP 기반의 기존 프로젝트에서 React를 일부 도입하고 싶을 때 적용할 수 있는 방식입니다.


1. 프로젝트 구조

/backend
  ├── src/main/java/com/cardfolio/springboot
  │       ├── CardFolioApplication.java
  │       ├── controller
  │       │     ├── WebController.java
  │       └── ...
  ├── src/main/resources/static (React 빌드 파일 배포 위치)
  ├── src/main/resources/templates (JSP 파일 위치)
  ├── src/main/resources/application.properties
  
/frontend
  ├── public
  ├── src
  ├── package.json
  ├── index.html
  └── ...

2. Spring Boot 설정

React 정적 리소스를 서빙할 수 있도록 application.properties를 다음과 같이 수정합니다.

# JSP 뷰 설정
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

# React 정적 리소스 제공 설정
spring.resources.static-locations=classpath:/static/
spring.web.resources.add-mappings=true

 

기존 JSP를 유지하면서 React의 정적 리소스를 서빙할 수 있도록 spring.resources.static-locations 설정을 추가합니다.


3. React 프로젝트 빌드 및 배포

React 프로젝트를 빌드한 후, Spring Boot의 static 폴더에 배포합니다.

  1. React 프로젝트 빌드 실행
cd frontend
npm run build

 

   2. 빌드된 파일을 백엔드 프로젝트로 복사

cp -r build/* ../backend/src/main/resources/static/

4. React 라우팅 문제 해결(Spring Boot 설정)

React의 SPA(Single Page Application) 특성상, 직접 URL로 접근하면 404 오류가 발생할 수 있습니다.

이를 방지하기 위해 Spring Boot에서 모든 경로를 index.html로 포워딩하도록 컨트롤러를 추가합니다.

 

WebController.java

package com.cardfolio.springboot;

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

@Controller
public class WebController {
    @GetMapping({"/", "/chart", "/card", "/company"})
    public String forwardReact() {
        return "forward:/index.html";
    }
}

 

사용자가 /chart, /card, /company 등의 경로로 접근할 때 React의 index.html이 제공되도록 설정합니다.


5. React 라우터 설정 (프론트엔드 설정)

React의 BrowserRouter는 기본적으로 HTML5의 history API를 사용하므로, Spring Boot 서버에서 경로를 처리할 수 있도록 조정해야 합니다.

 

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter as Router } from 'react-router-dom'; 

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>
);

 

App.js

import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Layout from './Component/Layout';
import HomePage from './Pages/HomePage';
import ChartPage from './Pages/ChartPage/ChartPage';
import CardPage from './Pages/CardPage/CardPage';
import CompanyPage from './Pages/CompanyPage/CompanyPage';

function App() {
  return (
    <Routes>
      <Route path="/" element={<Layout><HomePage /></Layout>} />
      <Route path="/chart" element={<Layout><ChartPage /></Layout>} />
      <Route path="/card" element={<Layout><CardPage /></Layout>} />
      <Route path="/company" element={<Layout><CompanyPage /></Layout>} />
    </Routes>
  );
}

export default App;

+ Recent posts