쿼리 파라미터, HTML Form

shinyeongwoon·2022년 12월 28일
0

spring MVC

목록 보기
27/32
post-custom-banner

HTTP 요청 메세지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법을 알아보자

Client에서 Server로 요청 데이터를 전달할 때는 주로 3가지 방법을 사용한다

  1. GET - QueryParameter
  • /url?username=hello&age=20
  • 메세지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
  • ex) 검색, 필터, 페이징등에서 많이 사용하는 방식
  1. POST - HTML Form
  • content-type : application/x-www-form-urlencoded
  • 메세지 바디에 QueryParameter 형식으로 전달 username=hello&age=20
  • ex) 회원가입, 상품 주문, HTML Form 사용
  1. HTTP message body에 데이터를 직접 담아서 요청
  • HTTP API에서 주로 사용, JSON,XML,TEXT
  • 데이터 형식은 주로 JSON 사용
  • POST,PUT, PATCH

요청 파라미터 - queryParameter, HTML Form

HttpServletRequestrequest.getParameter()를 사용하면 다음 두가지 요청 파라미터를 조회할 수 있다.

GET, 쿼리 파라미터 전송
예시 : http://localhost:8080/request-param?username=hello&age=20

Post, HTML Form 전송
예시

POST /request-param ...
content-type : application/x-www-form-urlencoded

username=hello&age=20

GET 쿼리 파라미터 전송 방식이든, POST HTML Form 전송 방식이든 둘 다 형식이 같으므로 구분 없이 조회할 수 있다.
이것을 간단히 요청 파라미터(request parameter)조회라 한다.

RequestParamController

경로 : hello.springmvc.basic.request

package hello.springmvc1.basic.request;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Controller
public class RequestParamController {

    @RequestMapping("/request-param-v1")
    public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));

        log.info("username={}, age={}",username,age);

        response.getWriter().write("ok");

    }

}

request.getParameter()

여기서는 단순히 HttpServletRequest가 제공하는 방식으로 요청 파라미터를 조회했다.

GET 실행 : http://localhost:8080/request-param-v1?username=hello&age=20

Post Form 페이지 생성

리소스는 /resources/static아래에 두면 스프링 부트가 자동으로 인식한다.

main/resources/static/basic/hello-form.html

<!DOCTYPE html>
  <html>
  <head>
      <meta charset="UTF-8">
      <title>Title</title>
  </head>
      <body>
        <form action="/request-param-v1" method="post">
			username: <input type="text" name="username" /> age: <input type="text" name="age" /> <button type="submit">전송</button>
        </form>
    </body>
</html>

POST Form 실행 : http://localhost:8080/basic/hello-form.html

🤞 참고 )
Jar를 사용하면 webapp경로를 사용할 수 없다.
이제 부터 정적 리소스도 클래스 경로에 함께 포함해야 한다.

HTTP 요청 파라미터 - @RequestParam

스프링이 제공하는 @RequestParam을 사용하면 요청 파라미터를 매우 편리하게 사용할 수 있다.

    /**
     * @RequestParam 사용
     * - 파라미터 이름으로 바인딩
     * @ResponseBody 추가
     * - view 조회를 무시하고, HTTP message body에 직접 해당 내용 입력
     */
    @ResponseBody
    @RequestMapping("/request-param-v2")
    public String requestParamV2(
            @RequestParam("username") String memberName,
            @RequestParam("age") int memberAge
    ){
        log.info("username = {} , age ={}",memberName,memberAge);
        return "ok";
    }

@RequestParam : 파라미터 이름으로 바인딩
@ResponseBody : View 조회를 무시하고, HTTP message body에 직접 해당 내용 입력

@RequestParam의 name(value)속성이 파라미터 이름으로 사용

  • @RequestParam("username") String memberName -> request.getParameter("username")
   /**
     * @RequestParam 사용
     * HTTP 파라미터 이름이 변수 이름과 같으면 @RequestParam(name="xx") 생략 가능
     */
    @ResponseBody
    @RequestMapping("/request-param-v3")
    public String requestParamV3(
            @RequestParam String username,
            @RequestParam int age
    ){
        log.info("username ={} , age={}",username,age);
        return "ok";
    }

HTTP 파라미터 이름이 변수 이름과 같으면 @RequestParam(name="xx)생략 가능

 /**
     * @RequestParam tkdyd
     * String, int 등의 단순 타입이면 @RequestParam 도 생략 가능
     */
    @ResponseBody
    @RequestMapping("/request-param-v4")
    public String requestParamV4(String username,int age){
        log.info("username={}, age={}",username,age);
        return "ok";
    }

String,int,Integer등의 단순 타입이면 @RequestParam도 생략 가능

📍 주의
@RequestParam애노테이션을 생략하면 스프링 MVC는 내부에서 required=false를 적용한다. required옵션은 바로 다음에 설명한다.

파라미터 필수 여부 - requestParamRequired

/**
     * @RequestParam.required
     * /request-param-required -> username 이 없으므로 예외
     *
     * 주의!
     * /request-param-required?username= -> 빈문자로 통과
     *
     * 주의!
     * /request-param-required
     * int age -> null을 int에 입력하는 것은 불가능, 따라서 Integer 변경해야 함(또는 다음에 나오는 defaultValue 사용)
     */
    @ResponseBody
    @RequestMapping("/request-param-required")
    public String requestParamRequired(
            @RequestParam(required = true) String username,
            @RequestParam(required = false) Integer age
    ){
        log.info("username={}, age={}",username,age);
        return "ok";
    }

@RequestParam.required

  • 파라미터 필수 여부
  • 기본값이 파라미터 필수(true)이다.

/request-param요청

  • username이 없으므로 400 예외가 발생한다.

📍 주의 - 파라미터 이름만 사용
/request-param?username=
파라미터 이름만 있고 값이 없는 경우 -> 빈문자로 통과

📍 주의 - 기본형(primitive)에 null 입력
/request-param 요청
@RequestParam(required = false) int age

nullint에 입력하는 것은 불가능(500 예외 발생)
따라서 null을 받을수 있는 Integer로 변경하거나, 또는 다음에 나오는 defaultValue사용

기본 값 적용 - requestParamDefault

    /**
     * @RequestParam
     * - defaultValue 사용
     *
     * 참고 : defaultValue 빈 문자의 경우에도 사용
     * /request-param-default?username=
     */
    @ResponseBody
    @RequestMapping("/request-param-default")
    public String requestParamDefault(
        @RequestParam(required = true, defaultValue = "guest") String username,
        @RequestParam(required = false, defaultValue = "-1") int age
    ){
        log.info("username={}, age={}",username,age);
        return "ok";
    }

파라미터에 값이 없는 경우 defaultValue를 사용하면 기본 값을 적용할 수 있다.
이미 기본 값이 있기 때문에 required는 의미가 없다.

defaultValue는 빈 문자의 경우에도 설정한 기본 값이 적용된다.
/request-param-default?username=

파라미터를 Map으로 조회하기 - requestParamMap

    /**
     * @RequestParam Map, MultiValueMpa
     * Map(key=value)
     * MultiValueMap(key=[value1,value2,...]) ex) (key=userIds,value=[id1,id2])
     */
    @ResponseBody
    @RequestMapping("/request-param-map")
    public String requestParamMap(@RequestParam Map<String, Object> paramMap){
        log.info("username={}, age={}",paramMap.get("username"),paramMap.get("age"));
        return "ok";
    }

파라미터를 Map,MultiValueMap으로 조회할 수 있다.
@RequestParam Map

  • Map(key=value)
    @RequestParam MultiValueMap
  • MultiValueMap(key=[value1,value2,...]) ex) (key=userId, value=[id1,id2])
    파라미터의 값이 1개가 확실하다면 Map을 사용해도 되지만, 그렇지 않다면 MultiValueMap을 사용하자
post-custom-banner

0개의 댓글