๐Ÿ“Œโ€œ๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ์€ UX์—์„œ ์‹œ์ž‘ํ•ด, REST๋กœ ์™„์„ฑ๋๋‹ค โ€“ ReviewAjaxController ๊ตฌํ˜„๊ธฐโ€

๐Ÿ“… 2025-07-02 โœ๏ธ ๋ฐ•์ฐฌํฌ

๐Ÿ”ง ๊ตฌํ˜„ ๋ชฉํ‘œ

๊ธฐ์กด ๊ฐ•์˜ ๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ์€ ์ „ํ†ต์ ์ธ JSP ํผ ์ œ์ถœ ๋ฐฉ์‹์ด์—ˆ๋‹ค.

๋ฆฌ๋ทฐ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ํ™”๋ฉด์ด ์ƒˆ๋กœ๊ณ ์นจ๋˜๊ณ , ๋ฆฌ๋ทฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ๋ณด๊ธฐ ์œ„ํ•ด์„  ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•ด์•ผ ํ–ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ์ด๊ฑด ๋„ˆ๋ฌด ๊ฑฐ์Šฌ๋ฆฐ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฐฑ์—”๋“œ ๊ด€์ ์—์„œ๋„ ๋„ˆ๋ฌด ๋น„ํšจ์œจ์ ์ด๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ์— ์„ค๊ณ„ํ•œ ๊ฑด ์™„์ „ํžˆ ์ƒˆ๋กญ๊ฒŒ ๋ถ„๋ฆฌ๋œ Ajax ๊ธฐ๋ฐ˜ ์ปจํŠธ๋กค๋Ÿฌ.

RESTful ๊ตฌ์กฐ๋กœ ๋ฆฌ๋ทฐ ๋“ฑ๋ก๊ณผ ๋ฆฌ๋ทฐ ์กฐํšŒ๋ฅผ ์™„์ „ํžˆ ๋ถ„๋ฆฌํ–ˆ๊ณ ,

ํ”„๋ก ํŠธ์™€์˜ JSON ์—ฐ๋™์„ ๊ณ ๋ คํ•ด UX๋ฅผ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๊ตฌ์กฐ์ ์œผ๋กœ ๋ช…ํ™•ํ•œ API๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค.


๐Ÿ“Œ ์ฃผ์š” ์‹œ๋„ ์š”์•ฝ

ํ•ญ๋ชฉ ํ•ต์‹ฌ ์„ค๊ณ„
๋ฆฌ๋ทฐ ์กฐํšŒ GET /review?lectureId=1 โ†’ JSON ๋ฐฐ์—ด ๋ฐ˜ํ™˜
๋ฆฌ๋ทฐ ๋“ฑ๋ก POST /review โ†’ JSON ์‘๋‹ต + ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URL ํฌํ•จ
์ธ์ฆ ์ฒดํฌ ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ ๋ฏธํ†ต๊ณผ ์‹œ 401 ๋ฐ˜ํ™˜
์˜ˆ์™ธ ํ๋ฆ„ 400 / 401 / 500 ๋“ฑ ์ƒํ™ฉ๋ณ„ ์ƒํƒœ ์ฝ”๋“œ + ๋ฉ”์‹œ์ง€ ๋ช…์‹œ
์‘๋‹ต ํฌ๋งท { success, message?, data? }๋กœ ํ†ต์ผ๋œ ๊ตฌ์กฐ

๐Ÿงฑ ์ „์ฒด ๊ตฌ์กฐ

[Client]
  โ†• AJAX
[ReviewAjaxController]
  โ†’ ReviewService
  โ†’ ReviewDAO
  โ†’ MySQL

โš™๏ธ ์ฃผ์š” ๊ธฐ๋Šฅ ํ๋ฆ„

โœ… 1. ๋ฆฌ๋ทฐ ์กฐํšŒ โ€“ GET /review?lectureId=1

int lectureId = Integer.parseInt(req.getParameter("lectureId"));
List<ReviewDTO> reviews = reviewService.getReviewsByLectureId(lectureId);
gson.toJson(reviews, res.getWriter());

๐Ÿ“Œ ํ”„๋ก ํŠธ๋Š” ๋‹จ์ˆœํžˆ ๋ฆฌ์ŠคํŠธ ๋ฐ›์•„ ๋ Œ๋”๋ง๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ์„œ๋ฒ„๊ฐ€ ๋ชจ๋“  ํ˜•์‹์„ ์ฑ…์ž„์ง„๋‹ค.


โœ… 2. ๋ฆฌ๋ทฐ ๋“ฑ๋ก โ€“ POST /review

UserDTO user = (UserDTO) session.getAttribute("user");
if (user == null) {
  resp.setStatus(401);
  ...
}

ReviewDTO dto = new ReviewDTO();
dto.setLectureId(lectureId);
dto.setUserId(user.getUserId());
...
reviewService.addReview(dto);

๐Ÿ“Œ POST ์š”์ฒญ์ธ๋ฐ๋„ ์ƒˆ๋กœ๊ณ ์นจ์€ ์—†๋‹ค. ์‚ฌ์šฉ์ž๋Š” โ€˜ํ๋ฆ„โ€™์ด ๋Š๊ธฐ์ง€ ์•Š๋Š”๋‹ค.


๐Ÿšง ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ์‚ฌ๋ก€

โŒ lectureId ์—†์„ ๋•Œ 500 ์—๋Ÿฌ โ†’ 400์œผ๋กœ ์ˆ˜์ •

try {
  ...
} catch (NumberFormatException e) {
  resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
  result.put("message", "๊ฐ•์˜ ID๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
}

๐Ÿ“Œ ํด๋ผ์ด์–ธํŠธ์™€์˜ ์‹ ๋ขฐ๋Š” ์ •ํ™•ํ•œ ์—๋Ÿฌ์ฝ”๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘๋œ๋‹ค.


๐Ÿง  ๋ฐฐ์šด ์ 


โœ๏ธ ํšŒ๊ณ 

์ด๋ฒˆ ReviewAjaxController๋Š” ๋‹จ์ˆœ ๋ฆฌ๋ทฐ API๊ฐ€ ์•„๋‹ˆ์—ˆ๋‹ค.

๊ทธ ์•ˆ์—๋Š” ์‚ฌ์šฉ์ž ํ๋ฆ„, ์„œ๋ฒ„ ํ™•์žฅ์„ฑ, ๋ณด์•ˆ, ์˜ˆ์™ธ ํ๋ฆ„ ๋“ฑ ์‹ค๋ฌด ๊ฐœ๋ฐœ์˜ ํ•ต์‹ฌ์ด ๋‹ค ๋“ค์–ด์žˆ์—ˆ๋‹ค.

โ€œAjax๋ฅผ ๋‹จ์ง€ ๊ธฐ์ˆ ๋กœ ์“ฐ์ง€ ๋ง์ž.

ํ๋ฆ„์„ ๋Š์ง€ ์•Š๋Š” ๊ตฌ์กฐ ์ž์ฒด๋กœ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์„ค๊ณ„ํ•˜์ž.โ€

ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก,

์ด ์ปจํŠธ๋กค๋Ÿฌ๋Š” JSON ์‘๋‹ต์„ ์ค‘์‹ฌ์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๊ณ„๋˜์—ˆ๋‹ค.