[Spring]Spring & React 연동

김피자·2023년 3월 24일
0

Spring

목록 보기
23/28

Spring과 React를 연동하려고 한다!


시작 전

스프링 프로젝트 기본 세팅이 완료된 상태
작업 환경 : 인텔리제이


scr/main/frontend 생성


리엑트 작업공간 생성을 위해 scr/main에서 새로 터미널을 연다.

>> npx create-react-app frontend


생성 완료


리엑트 서버 실행

리엑트 서버 실행을 위해 먼저 터미널에서 frontend 폴더로 이동한다.

cd frontend 

실행

npm start


리엑트 기본서버 3000번이 실행되는 것을 볼 수 있다.

서버 종료는 터미널에서 ctrl + c


리엑트 Proxy 설정

CORS

서버와 클라이언트가 동일한 IP에서 실행되면 resource 제약 없이 서로 같은 자원을 공유할 수 있겠지만, 리엑트 서버는 localhost:3000 스프링 서버는 localhost:8080으로 동작하기 때문에 CORS 관련 이슈가 발생한다.

그래서 Proxy설정을 통해 서로 같은 도메인을 사용하도록 설정해야 한다.

src/main/frontend폴더에서 Proxy 모듈 설치하기

npm install http-proxy-middleware --save

프록시를 설정하는 방법은 package.json에 추가하는 방법과 src/main/frontend/src폴더에 setProxy.js파일을 생성하고 추가하는 방법이 있는데 나는 아주 간편한 첫 번째 방법으로 설정하겠다!!

package.json에 추가

"proxy" : "http://localhost:8080",

리엑트와 스프링 포트번호 변경

리엑트

내가 위에 올린package.json 사진을 보면 export PORT=4000 부분을 볼 수 있다.

"scripts": {
    "start": "export PORT=4000 && react-scripts start",
  },

리엑트 서버는 기본 3000번으로 세팅되어있다.
이번 프로젝트에서는 프론트 팀 요구사항에 맞게 4000번으로 지정해 주었다.

스프링

application.properties에 원하는 포트번호를 적어주면 된다.

server.port = 8080

App.js 수정

App.js 파일을 전체 지우고 붙여넣기 한다.

// src/main/frontend/src/App.js

import React, {useEffect, useState} from 'react';
import axios from 'axios';

function App() {
   const [hello, setHello] = useState('')

    useEffect(() => {
        axios.get('/hello')
        .then(response => setHello(response.data))
        .catch(error => console.log(error))
    }, []);

    return (
        <div>
            백엔드에서 가져온 데이터입니다 : {hello}
        </div>
    );
}

export default App;

서버에 요청이 들어왔을 때, 컨트롤러에서 해당 매핑을 찾아 실행시킨다.
정상 연결이 되었다면 {hello}부분에 Spring에서 return한 값이 들어올 것이다.


MainController 생성

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MainController {
    @GetMapping("/hello")
    public String test(){
        return "Hello, World!";
    }
}

실행

리엑트 실행 + 스프링 실행

먼저 8080/hello로 스프링 서버에 요청하면 Hello, World! 가 나오는 것을 볼 수 있을거다.

정상적으로 리엑트와 연동이 됐다면 3000번(내 경우엔 4000번) 포트에서도 저 Hello, World!가 보여야 할 것이다.

스프링에서 Hello, World!를 가져오기 성공!!


그럼 매번 npm start하고 Spring서버를 켜고 해야할까?

번거로운 작업 없이 Spring과 React 프로젝트가 하나의 패키지가 될 수 있도록 빌드를 진행해보자!

build.gradle 수정

Spring이 빌드될 때 React 프로젝트가 먼저 빌드되고, 그 결과를 Spring에 포함시킨다는 내용을 추가해주자

def frontendDir = "$projectDir/src/main/frontend"

sourceSets {
	main {
		resources { srcDirs = ["$projectDir/src/main/resources"]
		}
	}
}

processResources { dependsOn "copyReactBuildFiles" }

task installReact(type: Exec) {
	workingDir "$frontendDir"
	inputs.dir "$frontendDir"
	group = BasePlugin.BUILD_GROUP
	if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
		commandLine "npm.cmd", "audit", "fix"
		commandLine 'npm.cmd', 'install' }
	else {
		commandLine "npm", "audit", "fix" commandLine 'npm', 'install'
	}
}

task buildReact(type: Exec) {
	dependsOn "installReact"
	workingDir "$frontendDir"
	inputs.dir "$frontendDir"
	group = BasePlugin.BUILD_GROUP
	if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
		commandLine "npm.cmd", "run-script", "build"
	} else {
		commandLine "npm", "run-script", "build"
	}
}

task copyReactBuildFiles(type: Copy) {
	dependsOn "buildReact"
	from "$frontendDir/build"
	into "$projectDir/src/main/resources/static"
}

Spring 서버 실행


> Task :buildReact

> frontend@0.1.0 build
> react-scripts build

Creating an optimized production build...

리엑트 서버, 스프링 서버 따로 따로 실행했을 때랑 다르게 8080에서 리엑트를 빌드해 가져오는 것을 볼 수 있다!!

끝@@

profile
제로부터시작하는코딩생활

0개의 댓글