[Spring/스프링] @RequestParam과 @PathVariable 그리고 Name for argument of type not specified, and parameter name ...

sbj·2023년 12월 18일
0

ERROR.zip

목록 보기
14/19
post-thumbnail

2023년 12월 17일


Problem (문제)

ava.lang.IllegalArgumentException: Name for argument of type [java.lang.Integer] not specified, and parameter name information not found in class file either.

Causes (원인)

Name for argument of type [java.lang.Integer] not specified, and parameter name information not found in class file either.

해당 에러는 파라미터 이름을 명시하지 않아서 발생한다.


상황

나는 컴퓨터다라고 멘탈을 다잡고 생각해보자

  1. 왜 Multipart file 메소드를 추가한 이후, 갑자기 게시글 상세페이지로 넘어가면 404 에러가 발생하는 것인가
  2. boardlist.html
<tr th:each="board : ${list}">
            <td th:text="${board.id}">1</td>
            <td>
                <a th:text="${board.title}" th:href="@{/board/view(id=${board.id})}"></a>
            </td>
        </tr>

제목을 클릭하면 "@{/board/view(id=${board.id})}" 로 연결되도록 해주었다.

  1. boardView 컨트롤러
@GetMapping("/board/view") //localhost:8080/board/view?id=1 --1이 id에 입력되어, 1번 게시글을 불러오게 됨
    public String boardView(Model model, Integer id) {
        model.addAttribute("board", boardService.boardView(id));
        return "boardview";
    }

그럼 boardView 컨트롤러가 URL을 Mapping 하겠지. 그리고 이에 해당하는 id가 파라미터로 넘겨지겠지. 그리고 boardService.boardView(id) 메소드를 사용해서 해당 Id가 있는 보드를 검색하고 model에 추가하겠지.

이후 boardview를 반환하겠다.

  1. 해당 에러의 원인은 파라미터의 이름에 대한 정보를 기본적으로 제공하지 않기 때문에 발생한다 했다. 그러면 요청 파라미터의 이름을 지정해줄까.

@RequestParam

@RequestParam은 Spring MVC에서 클라이언트의 HTTP 요청 파라미터를 컨트롤러 메소드의 파라미터로 바인딩하려고 할 때 사용되는 어노테이션이다.

@RequestParam("id") id라는 이름의 파라미터를 찾아, Integer id에 바인딩 한다.


  1. 나의 경우 파라미터 이름 정보가 클래스 파일에 포함되지 않아서 발생했고, 명시적으로 요청 파라미터의 이름을 지정해주었다.
@GetMapping("/board/view") //localhost:8080/board/view?id=1 --1이 id에 입력되어, 1번 게시글을 불러오게 됨
    public String boardView(Model model, @RequestParam("id") Integer id) {
        model.addAttribute("board", boardService.boardView(id));
        return "boardview";
    }

@RequestParam(”id”) 어노테이션을 추가해서, id라는 이름의 요청 파라미터를 찾아 Integer에 바인딩 하도록 지정했다. 그리고 해결했다.


결과

@RequestParam 고맙다.


추가 공부

나 앞으로 이런 에러를 참 많이 마주할 것 같아서 관련 어노테이션을 더 찾아봤다.


@PathVariable

URL 경로에 있는 변수를 메소드의 파라미터로 바인딩하는데 사용된다.

@GetMapping("/board/{id}")와 같이 사용하면, URL의 ID 부분이 메소드의 id 파라미터로 전달된다. RESTful API를 만드는데에 유용하다고 한다.

RESTful API

웹서비스의 기본 아이디어인 자원의 표현에 초점을 맞추고 있다. URL이 자원을 표현하고, HTTP 메소드가 해당 자원에 대한 행위를 표현하는 방식을 사용한다.

여기서, @PathVariable을 사용하면 URL 경로에 있는 변수(자원의 식별자)를 메소드의 파라미터로 바인딩하여, 각 자원에 대한 특정 작업을 수행할 수 있다. 이렇게 함으로써 API의 엔드포인트가 명확해진다.

그럼 @PathVariable도 받아주시나요

@GetMapping("/board/view") //localhost:8080/board/view?id=1 --1이 id에 입력되어, 1번 게시글을 불러오게 됨
    public String boardView(Model model, @PathVariable("id") Integer id) {
        model.addAttribute("board", boardService.boardView(id));
        return "boardview";
    }

어노테이션으로 @PathVariable로 수정했으나 다시 또 500에러가 발생한다.

500 에러는

서버에서 요청을 처리하는 과정에서 내부 오류가 발생했음을 나타낸다. 서버 로그를 파악해서 원인을 파악해야 한다.

에러 메시지

Required URI template variable 'id' for method parameter type Integer is not present]

500 에러는 서버에서 요청을 처리하는 과정에서 내부 오류가 발생했다는 것을 나타낸다. 이는 서버에서 문제가 발생했음을 나타내며, 클라이언트 측에서는 이 오류를 해결할 수 없다. 서버의 로그를 확인하여 문제의 원인을 파악해야한다.

다시 또 에러 해결해보기

  1. ‘id’ 변수가 URL 패턴에 없다는 것을 나타낸다.
  2. 그렇다면 URL 패턴에 포함시켜주자.

기존 코드를:

@GetMapping("/board/view")

다음과 같이 변경했고,

@GetMapping("/board/view/{id}")

이렇게 하면, 'id'가 URL 패턴에 포함되고, @PathVariable 어노테이션은 이 'id' 변수를 메소드의 파라미터로 바인딩할 수 있다.

profile
Strong men believe in cause and effect.

0개의 댓글