[Spring] 18. @RequestParam이란?
이전 글에서는 @GetMapping과 @PostMapping에 대해 살펴봤습니다. @GetMapping은 주로 화면 조회나 데이터 조회에 사용하고, @PostMapping은 주로 폼 전송이나 데이터 처리에 사용합니다.
이번 글에서는 사용자가 보낸 요청 값을 Controller에서 받는 방법인 @RequestParam에 대해 정리하겠습니다. 게시글 상세 번호, 검색어, 페이지 번호처럼 URL이나 폼을 통해 전달되는 값을 받을 때 자주 사용합니다.
핵심은 간단합니다. @RequestParam은 요청 파라미터 값을 Controller 메서드의 파라미터로 받아올 때 사용하는 어노테이션입니다.
1. 요청 파라미터란?
요청 파라미터는 사용자가 서버에 함께 보내는 값입니다. 예를 들어 게시글 상세 화면에 들어갈 때 게시글 번호를 함께 보낼 수 있습니다.
/board/detail?boardNo=10
위 주소에서 boardNo=10이 요청 파라미터입니다.
| 요청 URL | /board/detail?boardNo=10 |
| 파라미터 이름 | boardNo |
| 파라미터 값 | 10 |
검색 기능에서도 요청 파라미터를 사용할 수 있습니다.
/board/search?keyword=spring
/board/list?page=2
/board/list?keyword=spring&page=3
이런 값들을 Controller 메서드에서 받기 위해 @RequestParam을 사용할 수 있습니다.
2. @RequestParam 기본 사용법
@RequestParam은 요청 파라미터를 Controller 메서드의 파라미터로 연결합니다.
@Controller
@RequestMapping("/board")
public class BoardController {
@GetMapping("/detail")
public String detail(@RequestParam("boardNo") Long boardNo) {
System.out.println("게시글 번호: " + boardNo);
return "board/detail";
}
}
사용자가 다음 주소로 요청하면,
GET /board/detail?boardNo=10
Spring은 boardNo 파라미터 값을 찾아 Controller 메서드의 boardNo 변수에 넣어줍니다.
요청 파라미터 boardNo=10
→ @RequestParam("boardNo")
→ Long boardNo에 10 전달
3. 파라미터 이름이 같으면 생략 가능
요청 파라미터 이름과 메서드 파라미터 이름이 같다면 @RequestParam의 이름을 생략할 수 있습니다.
@GetMapping("/detail")
public String detail(@RequestParam Long boardNo) {
System.out.println("게시글 번호: " + boardNo);
return "board/detail";
}
위 코드는 요청 파라미터 이름이 boardNo이고, 메서드 파라미터 이름도 boardNo일 때 사용할 수 있습니다.
/board/detail?boardNo=10
→ Long boardNo
더 단순하게는 @RequestParam 자체를 생략해도 동작하는 경우가 있습니다.
@GetMapping("/detail")
public String detail(Long boardNo) {
return "board/detail";
}
하지만 처음 공부할 때는 값이 어디서 들어오는지 명확하게 보이도록 @RequestParam을 붙여서 이해하는 것이 좋습니다.
4. 검색어 받기
검색 기능에서는 사용자가 입력한 검색어를 요청 파라미터로 받을 수 있습니다.
GET /board/search?keyword=spring
Controller에서는 다음처럼 받을 수 있습니다.
@GetMapping("/search")
public String search(@RequestParam("keyword") String keyword) {
System.out.println("검색어: " + keyword);
return "board/search";
}
요청 흐름은 다음과 같습니다.
/board/search?keyword=spring
→ keyword 파라미터 값 확인
→ String keyword에 "spring" 전달
→ 검색 처리
검색어는 화면에서 입력받아 GET 방식으로 보내는 경우가 많습니다. 사용자가 검색 결과 주소를 복사하거나 다시 접근할 수 있기 때문입니다.
5. 여러 파라미터 받기
요청 파라미터는 여러 개를 함께 보낼 수 있습니다.
/board/list?keyword=spring&page=2&size=10
Controller에서는 각각의 값을 따로 받을 수 있습니다.
@GetMapping("/list")
public String list(
@RequestParam("keyword") String keyword,
@RequestParam("page") int page,
@RequestParam("size") int size
) {
System.out.println("검색어: " + keyword);
System.out.println("페이지: " + page);
System.out.println("개수: " + size);
return "board/list";
}
이 경우 요청 파라미터와 메서드 파라미터가 다음처럼 연결됩니다.
| 요청 파라미터 | Controller 파라미터 | 값 |
keyword |
String keyword |
spring |
page |
int page |
2 |
size |
int size |
10 |
6. required 속성
@RequestParam은 기본적으로 해당 파라미터가 반드시 있어야 한다고 봅니다. 만약 요청에 파라미터가 없으면 오류가 발생할 수 있습니다.
@GetMapping("/search")
public String search(@RequestParam("keyword") String keyword) {
return "board/search";
}
위 코드에서 keyword는 기본적으로 필수값입니다. 그런데 사용자가 다음처럼 요청하면 문제가 생길 수 있습니다.
GET /board/search
검색어가 없어도 허용하고 싶다면 required = false를 사용할 수 있습니다.
@GetMapping("/search")
public String search(
@RequestParam(value = "keyword", required = false) String keyword
) {
System.out.println("검색어: " + keyword);
return "board/search";
}
이제 keyword 파라미터가 없어도 요청을 처리할 수 있습니다. 파라미터가 없으면 keyword에는 null이 들어갈 수 있습니다.
7. defaultValue 속성
파라미터가 없을 때 기본값을 넣고 싶다면 defaultValue를 사용할 수 있습니다.
@GetMapping("/list")
public String list(
@RequestParam(value = "page", defaultValue = "1") int page
) {
System.out.println("현재 페이지: " + page);
return "board/list";
}
사용자가 페이지 값을 보내지 않으면 기본값으로 1이 들어갑니다.
GET /board/list
→ page 값 없음
→ 기본값 1 사용
GET /board/list?page=3
→ page 값 있음
→ 3 사용
페이징 기능에서는 defaultValue를 자주 사용합니다. 첫 페이지를 기본값으로 두면 사용자가 별도 페이지 번호 없이 목록에 접근해도 자연스럽게 1페이지를 보여줄 수 있습니다.
8. 검색과 페이징 예시
게시판 목록에서는 검색어와 페이지 번호를 함께 받을 수 있습니다.
/board/list?keyword=spring&page=2
Controller 예시는 다음과 같습니다.
@Controller
@RequestMapping("/board")
public class BoardController {
private final BoardService boardService;
public BoardController(BoardService boardService) {
this.boardService = boardService;
}
@GetMapping("/list")
public String list(
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", defaultValue = "1") int page,
Model model
) {
List<BoardDto> boardList = boardService.findBoardList(keyword, page);
model.addAttribute("boardList", boardList);
model.addAttribute("keyword", keyword);
model.addAttribute("page", page);
return "board/list";
}
}
이 구조에서는 검색어가 없어도 목록을 볼 수 있고, 페이지 값이 없으면 기본값 1을 사용합니다.
keyword
→ 없을 수도 있음
page
→ 없으면 1 사용
목록, 검색, 페이징 기능에서는 이런 식으로 @RequestParam을 활용하는 경우가 많습니다.
9. int와 Integer 사용 차이
요청 파라미터를 숫자로 받을 때 int와 Integer의 차이도 조심해야 합니다.
@GetMapping("/list")
public String list(@RequestParam(required = false) int page) {
return "board/list";
}
위 코드는 문제가 될 수 있습니다. required = false로 설정했는데, 요청에 page 값이 없으면 int에는 null을 넣을 수 없기 때문입니다.
이럴 때는 기본값을 주거나, Integer를 사용할 수 있습니다.
@GetMapping("/list")
public String list(
@RequestParam(value = "page", defaultValue = "1") int page
) {
return "board/list";
}
또는 다음처럼 받을 수 있습니다.
@GetMapping("/list")
public String list(
@RequestParam(value = "page", required = false) Integer page
) {
if (page == null) {
page = 1;
}
return "board/list";
}
페이징에서는 보통 defaultValue를 사용해 기본 페이지 번호를 정하는 방식이 깔끔합니다.
10. @RequestParam Map 사용
요청 파라미터가 많거나 동적으로 받아야 할 때는 Map으로 받을 수도 있습니다.
@GetMapping("/search")
public String search(@RequestParam Map<String, String> params) {
System.out.println(params.get("keyword"));
System.out.println(params.get("category"));
return "board/search";
}
요청이 다음과 같다면,
/board/search?keyword=spring&category=title
Map에는 다음과 같은 값이 들어갈 수 있습니다.
keyword → spring
category → title
다만 명확한 파라미터가 정해져 있다면 각각의 파라미터를 명시적으로 받는 방식이 더 읽기 좋습니다. Map은 파라미터 구조가 유동적일 때만 신중하게 사용하는 것이 좋습니다.
11. POST 폼 데이터도 받을 수 있을까?
@RequestParam은 GET 요청의 쿼리 문자열뿐만 아니라, POST 요청으로 전송된 폼 데이터도 받을 수 있습니다.
<form action="/member/login" method="post">
<input type="text" name="memberId">
<input type="password" name="memberPw">
<button type="submit">로그인</button>
</form>
@PostMapping("/member/login")
public String login(
@RequestParam("memberId") String memberId,
@RequestParam("memberPw") String memberPw
) {
return "redirect:/";
}
폼의 name 값과 @RequestParam 이름이 연결됩니다.
input name="memberId"
→ @RequestParam("memberId")
input name="memberPw"
→ @RequestParam("memberPw")
다만 입력값이 많아지면 @RequestParam으로 하나씩 받기보다 DTO로 받는 것이 더 깔끔합니다.
@PostMapping("/member/login")
public String login(MemberLoginDto memberLoginDto) {
return "redirect:/";
}
즉, 단순한 값 한두 개는 @RequestParam으로 받아도 되고, 여러 입력값은 DTO로 묶는 것이 좋습니다.
12. @RequestParam과 DTO 구분
요청 값을 받을 때 @RequestParam을 쓸지 DTO를 쓸지 헷갈릴 수 있습니다. 기준은 간단합니다.
| 상황 | 추천 방식 | 예시 |
| 값이 1~2개 | @RequestParam |
boardNo, page, keyword |
| 폼 입력값이 많음 | DTO | 회원가입, 게시글 작성 |
| 검색 조건이 많음 | SearchDto | 검색어, 카테고리, 기간, 정렬 |
예를 들어 게시글 번호 하나만 필요하다면 @RequestParam이 간단합니다.
@GetMapping("/detail")
public String detail(@RequestParam Long boardNo) {
return "board/detail";
}
반대로 게시글 작성처럼 제목, 내용, 카테고리, 첨부파일 정보 등 여러 값이 있다면 DTO로 받는 것이 좋습니다.
@PostMapping("/write")
public String write(BoardDto boardDto) {
return "redirect:/board/list";
}
13. @RequestParam과 @PathVariable 차이
요청 값을 받는 방법에는 @RequestParam 외에도 @PathVariable이 있습니다. 둘은 URL에서 값을 받는다는 점은 비슷하지만, 값이 들어있는 위치가 다릅니다.
| 구분 | @RequestParam | @PathVariable |
| 값 위치 | 쿼리 문자열 | URL 경로 일부 |
| 예시 URL | /board/detail?boardNo=10 |
/board/10 |
| 사용 예시 | @RequestParam Long boardNo |
@PathVariable Long boardNo |
이번 글에서는 @RequestParam만 먼저 이해하면 됩니다. @PathVariable은 다음 글에서 자세히 정리하겠습니다.
14. 자주 하는 실수
1) 파라미터 이름이 맞지 않는 경우
요청 파라미터 이름과 @RequestParam 이름이 다르면 값이 들어오지 않을 수 있습니다.
/board/detail?boardNo=10
@GetMapping("/detail")
public String detail(@RequestParam("no") Long boardNo) {
return "board/detail";
}
요청에서는 boardNo로 보냈는데, Controller에서는 no를 찾고 있습니다. 이런 경우 이름을 맞춰야 합니다.
@GetMapping("/detail")
public String detail(@RequestParam("boardNo") Long boardNo) {
return "board/detail";
}
2) 필수 파라미터가 없어서 오류가 나는 경우
@RequestParam은 기본적으로 필수값입니다. 없어도 되는 값이라면 required = false나 defaultValue를 사용해야 합니다.
@RequestParam(value = "keyword", required = false) String keyword
@RequestParam(value = "page", defaultValue = "1") int page
3) int에 null이 들어오는 경우
int는 null을 담을 수 없습니다. 파라미터가 없을 수 있다면 기본값을 주는 것이 안전합니다.
@RequestParam(value = "page", defaultValue = "1") int page
4) 폼 name과 DTO 필드명을 다르게 쓰는 경우
DTO로 받을 때는 HTML form의 name과 DTO 필드명이 맞아야 합니다.
<input type="text" name="title">
private String title;
이름이 맞아야 값이 자연스럽게 담깁니다.
5) 모든 값을 @RequestParam으로만 받으려는 경우
입력값이 많아지면 @RequestParam을 여러 개 나열하기보다 DTO로 묶는 것이 좋습니다.
@PostMapping("/write")
public String write(
@RequestParam String title,
@RequestParam String content,
@RequestParam String category,
@RequestParam String writer
) {
return "redirect:/board/list";
}
이런 경우에는 다음처럼 DTO로 받는 편이 더 깔끔합니다.
@PostMapping("/write")
public String write(BoardDto boardDto) {
return "redirect:/board/list";
}
정리
@RequestParam은 요청 파라미터 값을 Controller 메서드에서 받을 때 사용하는 어노테이션입니다. 게시글 번호, 검색어, 페이지 번호처럼 URL이나 폼을 통해 전달되는 값을 받을 수 있습니다.
| @RequestParam | 요청 파라미터 값을 메서드 파라미터로 받습니다. |
| required | 파라미터 필수 여부를 설정합니다. |
| defaultValue | 파라미터가 없을 때 사용할 기본값을 설정합니다. |
| DTO | 입력값이 많을 때 여러 값을 하나의 객체로 받을 수 있습니다. |
처음에는 다음 기준으로 기억하면 좋습니다.
값이 1~2개다
→ @RequestParam
입력값이 여러 개다
→ DTO
값이 없을 수도 있다
→ required = false 또는 defaultValue
페이지 번호처럼 기본값이 필요하다
→ defaultValue 사용
연습해보기
아래 요청을 Controller에서 받아보세요.
GET /board/list?keyword=spring&page=2
GET /board/detail?boardNo=10
GET /board/search?category=title&keyword=java
예시는 다음과 같습니다.
@GetMapping("/board/list")
public String list(
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", defaultValue = "1") int page
) {
return "board/list";
}
다음 글에서는 URL 경로 자체에서 값을 받는 @PathVariable에 대해 정리하겠습니다. /board/detail?boardNo=10과 /board/10의 차이를 비교하면서 보면 이해하기 쉽습니다

.
'Tech Stack > Spring Boot' 카테고리의 다른 글
| [Spring] 20. @ModelAttribute와 DTO 바인딩 (0) | 2026.07.13 |
|---|---|
| [Spring] 19. @PathVariable이란? (0) | 2026.07.12 |
| [Spring] 17. @GetMapping과 @PostMapping (0) | 2026.07.10 |
| [Spring] 16. @RequestMapping이란? (0) | 2026.07.09 |
| [Spring] 14. Bean 생명주기 (0) | 2026.07.08 |