javascript fetch() → java/Spring 반환
프런트 엔드에서 백엔드로 비동기 데이터 전송
기존에는 javascript의 비동기 기능으로 XMLHttpRequest를 이용해 비동기를 구현했는데 이 기능은 사용하기에는 다소 불편한 점이 있어 좀 더 편하게 사용하기 위해 Jquery 라이브러리를 따로 받고 이에 포함되어 있는 ajax을 이용해 비동기를 구현했는데, ES6부터는 javascript 자체적으로 fetch(비동기 기능)을 지원한다. 이 fetch() 비동기 기능을 활용하여 Spring(java)로 데이터를 전송하는 테스트를 하려 한다
프런트엔드에서는 fetch()를 통해 데이터를 보내고 백엔드에서는 JSONObject를 통해 데이터를 받아 가공 및 사용한다.
메서드 타입은 REST API에 맞춰서 GET, POST, PUT, DELETE를 사용하여 좀 더 사용하고자 하는 목표와 맞는 의미가 표현되게 사용하는 것이 좋다
데이터의 전송, 반환에는 JSON을 주로 사용한다
fetch() 기본 구성 fetch( Url, Option ) .then(response ⇒ { }) .catch(error ⇒ { })
Url : mapping할 주소
Option : Method, Header, body
then( ) : 비동기 데이터 전송 및 반환에 성공 시 실행
catch( ) : fetch 실행 중 에러 발생 시 catch 의미 그대로 에러를 잡아낸다
<Method에 사용 가능한 타입>
GET : 데이터를 반환을 요청
POST : 데이터 추가를 요청
PUT : 데이터 수정을 요청
DELETE : 데이터 삭제를 요청
<기본적으로 알아야 할 사항>
JSONObject : 스트링을 json 객체로 만들어준다
JSONArray : JSONObject를 JSONArray에 추가할 경우 추가적으로 배열 형태로 저장이 가능하다
JSONParser : JSON 형태의 String 문자열이 들어올 경우 JSON 형태로 변환해주어 JSONOBject, JSONArray에 추가할 수 있다.
JSON.stringify : JSONParser의 반대 형태로 JSON을 String 형태로 바꿔 전송한다.
예)
document.getElementById('myForm').addEventListener('submit', function(event) {
// 기본 폼 제출 동작을 막습니다.
event.preventDefault();
// FormData 객체를 생성하여 폼의 데이터를 캡처합니다.
let formData = new FormData(event.target);
// fetch를 사용하여 데이터를 서버에 POST 요청합니다.
fetch('https://your-api-endpoint.com', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
});
@PostMapping(value="/pay_fetch") // http://localhost:9091/ajax/pay_fetch
@ResponseBody
public String pay_fetch(Model model, String id, String passwd) {
// System.out.println("-> pay_fetch");
System.out.println("-> id: " + id);
System.out.println("-> passwd: " + passwd);
try {
Thread.sleep(10000); // 5s
} catch (Exception e) {
}
DecimalFormat df = new DecimalFormat("#,###,### 원");
JSONObject json = new JSONObject(); // json 변환
if (id.equals("user1") && passwd.equals("1234")) {
json.put("code", "success");
json.put("mname", "아로미");
json.put("id", id);
json.put("bonbong", df.format(2500000));
json.put("sudang", df.format(500000));
json.put("total", df.format(3000000));
} else {
json.put("code", "fail");
}
return json.toString(); //
}
@GetMapping(value="/review_list_all", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String review_list_all(@RequestParam(required = false, defaultValue = "recent") String sort, Model model) {
System.out.println("sort-> " + sort);
// 리뷰 목록 정렬
JSONArray array = new JSONArray();
switch (sort) {
case "star_high":
ArrayList<ReviewVO> highStarList = reviewProc.list_star_high();
for (ReviewVO review : highStarList) {
JSONObject reviewJson = new JSONObject();
reviewJson.put("id", review.getId());
reviewJson.put("star", review.getStar());
reviewJson.put("rdate", review.getRdate());
reviewJson.put("contents", review.getContents());
array.put(reviewJson);
}
break;
case "star_low":
ArrayList<ReviewVO> lowStarList = reviewProc.list_star_low();
for (ReviewVO review : lowStarList) {
JSONObject reviewJson = new JSONObject();
reviewJson.put("id", review.getId());
reviewJson.put("star", review.getStar());
reviewJson.put("rdate", review.getRdate());
reviewJson.put("contents", review.getContents());
array.put(reviewJson);
}
break;
case "recent":
ArrayList<ReviewVO> oldList = reviewProc.recent_review();
for (ReviewVO review : oldList) {
JSONObject reviewJson = new JSONObject();
reviewJson.put("id", review.getId());
reviewJson.put("star", review.getStar());
reviewJson.put("rdate", review.getRdate());
reviewJson.put("contents", review.getContents());
array.put(reviewJson);
}
break;
case "old":
default:
ArrayList<ReviewVO> allList = reviewProc.review_list_all();
for (ReviewVO review : allList) {
JSONObject reviewJson = new JSONObject();
reviewJson.put("id", review.getId());
reviewJson.put("star", review.getStar());
reviewJson.put("rdate", review.getRdate());
reviewJson.put("contents", review.getContents());
array.put(reviewJson);
}
break;
}
function loadReviews(sort) {
let url = 'http://localhost:9093/review/review_list_all?sort=' + sort;
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json' // 요청의 콘텐츠 타입을 JSON으로 설정
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json(); // 응답 본문을 JSON으로 변환하여 반환
})
.then(data => {
const reviewList = document.getElementById('review-list');
reviewList.innerHTML = ''; // 기존 리뷰 목록을 초기화
data.forEach(reviewVO => {
const id = reviewVO.id; // 리뷰 ID
const star = reviewVO.star; // 별점
const rdate = reviewVO.rdate; // 작성일자
const contents = reviewVO.contents; // 리뷰 내용
// 각 리뷰 항목을 HTML로 생성
const reviewItem = `
<div class="review-item">
<div class="review-header">
<span class="review-id">${id}</span>
</div>
<div>
<div class="star-rating">
${generateStars(star)}
</div>
<span class="review-date">${rdate}</span>
<div class="update_delete">
<span class="update_review">수정</span>
<span class="delete_review">삭제</span>
</div>
</div>
<div class="contents">
<div class="review-content">${contents}</div>
</div>
</div>
`;
reviewList.innerHTML += reviewItem;
});
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
}