리액트 백앤드 연동
리액트 백앤드 연동(개발)
개발서버를 연동한다.
- 백앤드 서버
- 백앤드서버 라이브러리 설정
- 백앤드서버 코드 작성
- 프론트 서버
- 프론트서버 프록시 설정
- 프론트서버 코드 작성
1. 백앤드서버 라이브러리 설정
(pom.xml)
<!-- 리액트에서 ajax 요청시 Map객체 리턴하는 컨트롤러에서 json 관련에러를 잡아줌. -23.07.16 CTH -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
위와 같은 라이브러리를 추가한 이유
연동을 완료 하고나서 프론트에 접속하면 프록시를 통해 backend 서버로 요청이 간다. (json으로 RequestBody 응답의 map객체를 리턴한다.)
그런데 자꾸 HashMap에 관련한 아래와 같은 에러를 백앤드에서 응답했다.
# 이 경우는 스프링에서 HttpMessageConverter로 사용할 객체를 자동으로 찾지 못해서 발생한다.
# jackson의 ObjectMapper 객체나 Gson의 Gson 객체가 있으면 스프링 4 이상에서는 자동으로 Jackson2MessageConverter 또는 GsonMessageConverter를 설정한다.
Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.HashMap
찾아보니 버전을 4버전 이상으로 올리면 대부분 해결된다고 하며, 문제시에는 List, Map 형태에서 발생 가능하다고 한다. 이러한 이유로 gson 라이브러리를 추가 한다.
2. 백앤드서버 코드 작성
(HomeController.java)
@ResponseBody
@RequestMapping(value="/app/test",method = RequestMethod.GET)
public Map<String, Object> test() throws Exception{
logger.info("HomeController test start >>");
//1. 객체생성
Map<String, Object> resultJSON = new HashMap<>();
try {
resultJSON.put("message", "Hello from the backend!");
} catch (Exception e) {
//jsp쪽으로 보내는 오류정보
logger.debug("ExceptionMsg : {}", e.getMessage());
e.printStackTrace();
throw e;
} finally {
logger.debug("test finally : {}", "Ok");
}
return resultJSON;
}
3. 프론트서버 프록시 설정
(package.json)
{
...
"proxy": "https://blang.co.kr/",
...
}
요청시 백앤드와 통신하기 위해 프록시를 위처럼 설정했다. (나의 경우 집에 물리적인 웹서버 2대, WAS서버 2대가 연동되어 있으므로 기본 도메인을 넣었다.)
4. 프론트서버 코드 작성
(App.js)
function App() {
const [data, setData] = useState(null);
/*
위의 코드에서는 fetch 함수를 사용하여 /dbd/app/test 경로로 GET 요청을 보내고,
응답을 JSON 형식으로 파싱하여 상태 변수 data에 저장합니다. useEffect 훅을 사용하여
컴포넌트가 마운트될 때 한 번만 요청을 보내도록 합니다.
응답이 성공적으로 받아지면, data 상태 변수를 사용하여 데이터를 렌더링합니다.
응답이 아직 도착하지 않은 경우에는 "Loading..." 메시지를 표시합니다.
위의 코드에서 /api/test 는 백엔드 API의 실제 엔드포인트로 대체되어야 합니다.
또한, 응답 형식 및 데이터 구조는 백엔드 API의 설계에 따라 달라질 수 있습니다.
따라서 실제 백엔드 API와의 통신을 위해서는 해당 API의 엔드포인트와
응답 처리 방식에 맞게 코드를 수정해야 합니다.
*/
useEffect(() => {
const fetchData = async() => {
try {
const response = await fetch('/dbd/app/test');
const jsonData = await response.json();
setData(jsonData);
} catch (error) {
console.error('Error:', error);
}
};
fetchData();
}, []);
return (
{/* 기본구조 */}
<div id="wrap" className="wrap">
{/* 백앤드 데이터 */}
{data ? (
<div>
<h1>현재 백앤드: 백앤드가 연결되었습니다.</h1>
<p>{data.message}</p>
</div>
) : (
<p>현재 백앤드: Loading...</p>
)}
<div>
);
}
export default App;
테스트
- 백앤드(web/was) 실행 && 프론트(react) 실행
- 클라이언트(크롬)로 프론트서버 요청
- 프록시를 통한 백앤드 측으로 요청됨 > 컨트롤러 실행 > Map 리턴
- 프론트서버에서 응답결과 UseState 값을 셋팅. > 결과에 따라 화면 핸들링
Leave a comment