Search

DefaultHandlerExceptionResolver: Resolved ~ : Required request body is missing …

νƒœκ·Έ
JPA

μ˜€λŠ˜λ„ 마주친 μ—λŸ¬

κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κ³  ν”„λ‘ νŠΈμ— μ—°κ²°ν•˜μ—¬ ν•˜λ‚˜μ”© ν•΄κ²°ν•˜λ˜ 쀑, μ•„λž˜μ™€ 같은 μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.
2023-12-01T02:42:01.109+09:00 WARN 90341 --- [io-8081-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<?> wanted.assignment.pmsystem.domain.planner.board. BoardController.deleteBoard(wanted.assignment.pmsystem.domain.planner.board.dto.requests.DeleteBoardRequest)]
Plain Text
볡사
μ²˜μŒλ³΄λŠ” μ—λŸ¬μ— λ‹Ήν™©μŠ€λŸ¬μ› μ§€λ§Œ, 늘 ν•˜λ˜λŒ€λ‘œ μš”μ²­μ΄ μ œλŒ€λ‘œ κ°”λŠ”μ§€ λΆ€ν„° ν™•μΈν•˜μ˜€μŠ΅λ‹ˆλ‹€.
μ›λž˜ λͺ…μ„ΈλŠ” DELETE http://localhost:8081/api/boards 에 request body 둜 board 의 인덱슀λ₯Ό λ‹΄μ•„ λ„˜κΈ°λŠ” κ²ƒμ΄μ˜€μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μœ„μ™€ 같은 였λ₯˜κ°€ λ°œμƒν–ˆκ³ , 원인을 μ°Ύμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

DELETE μ—μ„œλŠ” payload body λ₯Ό λͺ»μ“°λŠ”κ±ΈκΉŒ?

DEELTE λͺ…μ„Έμ—λŠ” 이상이 μ—†κ³ , request body 에도 λ¬Έμ œκ°€ μžˆλŠ”λ° μ™œ 처리λ₯Ό λͺ»ν•˜λŠ”건지 μ²˜μŒμ—” μ•„λž˜μ™€ 같은 였λ₯˜λ₯Ό 보고 μ°Έ λ‹Ήν™©ν–ˆμŠ΅λ‹ˆλ‹€.
2023-12-01T02:49:12.598+09:00 WARN 90341 --- [nio-8081-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'DELETE' is not supported]
Plain Text
볡사
ν”„λ‘ νŠΈμ—μ„œ λ­”κ°€ λ†“μΉœκ²Œ μžˆλ‚˜ μ‹Άμ–΄ 찬찬히 μ‚΄νŽ΄λ³΄λ‹ˆ ν‹€λ¦°κ²Œ μ „ν˜€ μ—†μ–΄λ³΄μ˜€μŠ΅λ‹ˆλ‹€. 500 μ—λŸ¬λ„ μ•„λ‹ˆκ³  401 μ—λŸ¬λ‹ˆ λ­”κ°€ μΈμ¦λ¬Έμ œμΈκ°€ μ‹Άμ–΄ μ‚΄νŽ΄λ΄€λŠ”λ° κ·Έ λ˜ν•œ μ•„λ‹ˆμ˜€μŠ΅λ‹ˆλ‹€. μ΄λ ‡κ²Œ λ˜ν•œλ²ˆ λ§žμ™œν‹€μ— 빠진 κΉ€μ‹œμ€β€¦ 🫠 
κ³΅λΆ€ν•˜κ³  λ³΄λ‹ˆ μ΄λŠ” ν”„λ‘ νŠΈμ—μ„œ DELETE 맀핑 μ‹œ request body 에 값을 넣어보낼 λ•Œ μ’…μ’… λ‚˜νƒ€λ‚˜λŠ” 였λ₯˜λΌκ³  ν•©λ‹ˆλ‹€. λ˜ν•œ μΌλ°˜μ μœΌλ‘œλŠ” DELETE 맀핑 μ‹œ request body λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  ν•˜λŠ”λ°μš”β€¦ Β μ™œ κ·ΈλŸ°μ§€ μ•„λž˜μ—μ„œ μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

HTTP μŠ€νŽ™μ—μ„œλŠ” λͺ…ν™•ν•˜κ²Œ DELETE 에 μš”μ²­ 본문의 μ‚¬μš©μ„ κΈˆν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

근데 μ™œ λ§Žμ€ μ‚¬λžŒλ“€μ΄ 쓰지 μ•ŠλŠ”κ±ΈκΉŒμš”? DELETE λŠ” λ¦¬μ†ŒμŠ€λ₯Ό μ œκ±°ν•˜λŠ” 데 μ‚¬μš©λ˜λ©° μ΄λŠ” 일반적으둜 λ¦¬μ†ŒμŠ€ μ‹λ³„μž(예 URL) λ₯Ό 톡해 μˆ˜ν–‰λ©λ‹ˆλ‹€. 즉, μΆ”κ°€ 데이터가 ν•„μš”ν•˜μ§€ μ•Šμ€ κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μš”μ²­ 본문을 ν¬ν•¨μ‹œν‚€λ©΄ 이 κ°„κ²°ν•˜κ³  λͺ…ν™•ν•œ 톡신이 λ³΅μž‘ν•΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. λ§Žμ€ HTTP ν΄λΌμ΄μ–ΈνŠΈ, μ„œλ²„ 및 μ€‘κ°„μž 듀은 DELETE μš”μ²­μ˜ 본문을 μ˜ˆμƒν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 이λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μ²˜λ¦¬ν•˜μ§€ λͺ»ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ ν‘œμ€€ν™”λœ μ ‘κ·Ό 방식을 λ”°λ₯΄λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μš”μ²­ 본문이 ν•„μš”ν•œ κ²½μš°λ„ μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λ³΅μž‘ν•œ μ‚­μ œ μ‘°κ±΄μ΄λ‚˜ μΆ”κ°€ 메타 데이터λ₯Ό 전솑해야 ν•˜λŠ” κ²½μš°μ— ν•΄λ‹Ήν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ΄λŠ” 일반적인 관행이 μ•„λ‹ˆλ©° νŠΉμ • μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μš”κ΅¬μ— 따라 λ‹¬λΌμ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ•„λ‹ˆ 그럼 이전 ν”„λ‘œμ νŠΈμ—μ„œ λ‚˜ DELETE μ–΄λ–»κ²Œ ν–ˆλ”λΌ

μ°Ύμ•„λ³΄λ‹ˆ @RequestParam 으둜 처리λ₯Ό ν–ˆμ—ˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ boardId=1 μ΄λ ‡κ²Œ url 에 λ°•νžˆλŠ”κ²Œ λ³΄κΈ°μ‹«μ—ˆλ˜ μ €λŠ” @PathVariable 둜 λ³€κ²½ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

μ΄λ²ˆμ—” @PathVariable 이 문제

ν•˜μ§€λ§Œ λ˜λ‹€μ‹œ λ‚˜νƒ€λ‚œ μ—λŸ¬β€¦ λ‹€μ‹œ λ„€νŠΈμ›Œν¬λ₯Ό 찬찬히 μ‚΄νŽ΄λ³΄κ³  ν”„λ‘ νŠΈμ—λŠ” 이상이 μ—†μŒμ„ ν™•μΈν•˜μ˜€μŠ΅λ‹ˆλ‹€.
그리고 spring boot 의 service λ₯Ό ν™•μΈν•΄λ³΄μ•˜λŠ”λ°μš”, μ•„λž˜μ™€ 같은 였λ₯˜κ°€ μ°ν˜€μžˆλŠ”κ²ƒμ„ 확인할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 였λ₯˜λ₯Ό 찬찬히 읽어보면 νŒŒλΌλ―Έν„° 이름 μ œλŒ€λ‘œ 지정 ν•˜λΌλŠ” κ±΄λ°μš”,
java.lang.IllegalArgumentException: Name for argument of type [java.lang.Long] not specified, and parameter name information not found in class file either. at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.updateNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:183) ~[spring-web-6.1.1.jar:6.1.1]at
Plain Text
볡사
μ•„λž˜μ™€ 같이 νŒŒλΌλ―Έν„°λͺ…을 λͺ…ν™•ν•˜κ²Œ 지정해주면 였λ₯˜λŠ” ν•΄κ²°λ©λ‹ˆλ‹€. μ™œ κ·ΈλŸ΄κΉŒμš”?
@GetMapping(value = "/{boardId}")public ResponseEntity<?> displayBoardDetail (@PathVariable Long boardId) @GetMapping(value = "/{boardId}")public ResponseEntity<?> displayBoardDetail (@PathVariable("boardId") Long boardId)
Java
볡사

μ™œ @PathVariable 에 이름을 λͺ…μ‹œμ μœΌλ‘œ 지정해야 ν•˜λ‚˜μš”?

@PathVariable 을 μ‚¬μš©ν•  λ•Œ "boardId"와 같이 λ³€μˆ˜μ˜ 이름을 λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜λ©΄, Spring FrameworkλŠ” HTTP μš”μ²­μ˜ URL κ²½λ‘œμ—μ„œ ν•΄λ‹Ή λ³€μˆ˜ 이름과 μΌμΉ˜ν•˜λŠ” 뢀뢄을 μ°Ύμ•„ λ©”μ†Œλ“œ νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬ν•œλ‹€κ³  ν•©λ‹ˆλ‹€. λ§Œμ•½ μ΄λ ‡κ²Œ μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ Spring 은 λŸ°νƒ€μž„ μ—μ„œ νŒŒλΌλ―Έν„°μ˜ 이름을 μ•Œ 수 μ—†μŠ΅λ‹ˆλ‹€. 즉, @PathVariable 에 λͺ…μ‹œμ μœΌλ‘œ 이름을 μ œκ³΅ν•˜μ§€ μ•ŠμœΌλ©΄ μ–΄λ–€ URL 경둜 λ³€μˆ˜λ₯Ό μ–΄λ–€ νŒŒλΌλ―Έν„°λ‘œ 맀핑해야 ν•˜λŠ”μ§€ κ²°μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€. νŒŒλΌλ―Έν„° 이름을 λͺ…μ‹œμ μœΌλ‘œ μž‘μ„±ν•˜λ©΄ 컴파일 μ˜΅μ…˜μ— 관계없이 λŸ°νƒ€μž„μ— μ˜¬λ°”λ₯Έ 맀핑이 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.