[Spring] HTTP 기본 요청 , 헤더 조회

hi·2022년 9월 9일
0

@RequestMapping

@RequestMapping("/hello-basic")

  • 기본 요청
  • /hello-basic/hello-basic/ 둘은 같게 인식
  • HTTP 메서드 모두 허용
  • @RequestMapping({"/hello-basic", "/hello-go"}) 다중 설정 가능

메서드 매핑

@RequestMapping(value = "/hello", method = RequestMethod.GET)

  • 축약하여 사용 가능
    @GetMapping( )
    @PostMapping( )
    @PutMapping( )
    @DeleteMapping( )
    @PatchMapping( )

PathVariable 경로 변수

@GetMapping("/mapping/{userId}")

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {

	log.info("userId={}", data);
	return "ok";
}
  • 변수명이 같으면 생략 가능

public String mappingPath(@PathVariable("userId") String data)
public String mappingPath(@PathVariable userId)

  • 다중 사용 가능
    @GetMapping("/mapping/users/{userId}/orders/{orderId}")

params 특정 파라미터 조건

@GetMapping(value = "/mapping-param", params = "key=value")

params="key"
param="!key"
params="key=value"
params="key!=value"
params= {"key=value", "key2=value2"}
  • 특정 파라미터가 있거나 없는 조건을 추가
  • 잘 사용하지는 않음

headers 특정 헤더 조건

@GetMapping(value = "/mapping-param", headers = "key=value")

  • 파라미터 매핑과 같으나, HTTP 헤더를 사용

consume 미디어 타입 조건

@PostMapping(value = "/mapping-consume", consumes = "application/json")

consumes="application/json"
consumes="!application/json"
consumes="application/*"
consumes="*\/*"
MediaType.APPLICATION_JSON_VALUE
  • HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑
  • 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type) 반환

produce 미디어 타입 조건

@PostMapping(value = "/mapping-produce", produces = "text/html")

produces = "text/html"
produces = "!text/html"
produces = "text/*"
produces = "*\/*"
  • HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑
  • 맞지 않으면 HTTP 406 상태코드(Not Acceptable) 반환

요청 파라미터

@RequestParam

@ResponseBody
public String requestParam(
	@RequestParam("username") String memberName,
	@RequestParam("age") int memberAge) {
  • 파라미터 이름으로 바인딩

  • 파라미터 이름과 변수명이 같으면 ("name") 생략 가능

public String requestParamV3(
	@RequestParam String username, 
	@RequestParam int age) {
  • String, int, Integer 등의 단순 타입이면 @RequestParam 생략 가능
  • @RequestParam 생략시 스프링 MVC는 내부에서 required=false 적용
public String requestParamV3(String username, int age) {

@ResponseBody

view 조회를 무시하고 HTTP 메시지 바디에 내용 입력

Required

public String requestParamRequired(
	@RequestParam(required = true) String username,
	@RequestParam(required = false) Integer age) {
  • 파라미터 필수 여부
    required = true 필수 (기본값)
    required = false 필수 X

  • int 타입의 경우 생략 불가 (500 예외 발생)
    👉 생략시 null이 되는데 기본형 int는 null값을 넣을 수 없기 때문, 무조건 값이 들어가야 함
    객체형 Integer 로 넣어야 null 가능 (혹은 defaultValue 사용하여 처리)

  • /request-param-required?username= 처럼 끝에 =가 있는 경우 (=파라미터 이름만 있고 값이 없는 경우) null이 아닌 빈 문자로 들어감
    👉 required = true의 경우 예외 X

  • null일 경우 400 예외 발생

defaultValue

  • 기본 값 적용
  • 파라미터에 값이 없는 경우 기본 값 적용
  • 빈 문자의 경우에도 기본 값 적용
public String requestParamDefault(
	@RequestParam(required = true, defaultValue = "guest") String username,
	@RequestParam(required = false, defaultValue = "-1") int age) {

requestParamMap

public String requestParamMap(@RequestParam Map<String, Object> paramMap) {
	log.info("username={}, age={}", paramMap.get("username"),
	paramMap.get("age"));
  • 파라미터를 Map, MultiValueMap으로 조회

  • 파라미터의 값이 1개이면 Map, 그렇지 않으면 MultiValueMap

  • @RequestParam Map
    Map(key=value)

  • @RequestParam MultiValueMap
    MultiValueMap(key=[value1, value2, ...]
    - ex) (key=userIds, value=[id1, id2])

@ModelAttribute

기능 1

  • 요청을 받아 객체를 만들고 객체에 값을 넣어주는 과정을 자동화 한다
public String class(@RequestParam String username, @RequestParam int age) {
	HelloData helloData = new HelloData();
	helloData.setUsername(username);
	helloData.setAge(age);
    
👇 

public String modelAttributeV1(@ModelAttribute HelloData helloData) {}

///

@Data
public class HelloData {
    private String username;
    private int age;
}
  • model.addAttribute(helloData) 코드도 함께 자동 적용됨

💡 @Data
@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 를 자동으로 적용

스프링MVC는 @ModelAttribute 가 있으면 다음을 실행한다

  1. HelloData 객체를 생성
  2. 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티를 찾고 setter를 호출해 파라미터의 값을 입력(바인딩)

ex) 파라미터 이름이 username 이면 setUsername() 메서드를 찾아서 호출하면서 값을 입력한다.

프로퍼티?
getUsername( ), setUsername( ) 메서드가 있으면 이 객체는 username 이라는 프로퍼티를 가지고 있다. username 프로퍼티의 값을 변경하면 setUsername( ) 이 호출되고, 조회하면 getUsername( ) 이 호출된다


기능 2

  • Model에 @ModelAttribute로 지정한 객체를 자동으로 넣어줌
    @ModelAttribute("hello") Item item -> 이름을 hello로 지정
  • 이름 생략시 Class명 첫글자를 소문자로 바꾸고 저장
    @ModelAttribute HlloWorld -> helloWorld로 저장

@ModelAttribute 생략

생략 가능하나 @RequestParam도 생략 가능하기 때문에 혼란

String, int 같은 단순 타입 👉 @RequestParam
(argument resolver 로 지정해둔 타입 제외) 나머지 👉 @ModelAttribute


기능 3

  • 컨트롤러에 있는 별도의 메서드에 적용 가능
    👉 해당 컨트롤러를 요청할 때 자동으로 반환값이 model에 담긴다

  • 반복해서 사용해야 하는 경우 활용


요청 메시지 - 단순 텍스트

InputStream

@PostMapping("")
public void requestBodyString(HttpServletRequest request, HttpServletResponse response) throws IOException {

	ServletInputStream inputStream = request.getInputStream();
	String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

}

메시지 바디의 데이터를 직접 읽음

InputStream , OutputStream

 @PostMapping("")
 public void requestBodyStringV2(InputStream inputStream, Writer responseWriter) throws IOException {

	String messageBody = StreamUtils.copyToString(inputStream, 	StandardCharsets.UTF_8);
    
	log.info("messageBody={}", messageBody);
    
	responseWriter.write("ok");
}

스프링 MVC에서 지원하는 파라미터

InputStream (Reader) : 요청 메시지 바디의 내용 직접 조회
OutputStream (Writer) : 응답 메시지 바디에 직접 결과 출력

HttpEntity

  • HTTP header, body 정보를 조회

    • 메시지 바디 정보 직접 조회
    • 요청 파라미터를 조회하는 기능과는 관계 없음 @RequestParam , @ModelAttribute
  • 응답에도 사용 가능
    - 메시지 바디 정보 직접 반환

    • 헤더 정보 포함 가능
    • view 조회 X
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) throws IOException {

	String messageBody = httpEntity.getBody();
	log.info("messageBody={}", messageBody);

	return new HttpEntity<>("ok");
}

HTTPEntity를 상속받은 다음 객체들도 같은 기능을 제공

  • RequestEntity
    - HttpMethod, url 정보 추가, 요청에서 사용
  • ResponseEntity
    - HTTP 상태 코드 설정 가능 , 응답에서 사용
return new ResponseEntity<String>("Hello World", responseHeaders, 
HttpStatus.CREATED)

@RequestBody

@ResponseBody
@PostMapping("")
public String requestBodyStringV4(@RequestBody String messageBody) {
 	
    log.info("messageBody={}", messageBody);
 	return "ok";
}

@RequestBody

  • 메시지 바디 정보 직접 조회
    헤더 정보는 HttpEntity, @RequestHeader 사용

  • 요청 파라미터를 조회하는 @RequestParam, @ModelAttribute와는 관계 없이
    메시지 바디를 직접 조회

@ResponseBody

  • 응답 결과를 메시지 바디에 직접 담아 전달

정리
요청 파라미터 조회 : @RequestParam, @ModelAttribute
HTTP 메시지 바디 직접 조회 : @RequestBody

0개의 댓글