본문 바로가기
SPRING

[SPRING] HTTP 요청 데이터 매핑(단순 텍스트) - 2

by steadyMan 2022. 3. 12.

클라이언트에서 HTTP 요청을 통해 전달한 HTTP 메시지 바디의 데이터를 서버에서

매핑하는 방법에 대해 학습한 내용입니다. 

 

개인적인 학습의 대한 정리 내용입니다.

 

GET 방식의 URL 쿼리 파라미터, POST 방식의 HTML Form 전송을 제외한

HTTP message body에 데이터를 직접 담아서 요청은 @RequestParam, @ModelAttribute 애노테이션을

사용한 매핑을 할 수 없습니다.

메시지 바디를 직접 조회하는 기능은 요청 파라미터를 조회하는 @RequestParam , @ModelAttribute 와는 전혀 관계가 없다

 

그렇다면 어떻게 매핑할 수 있을까? 

1. HttpServletRequest.getInputStream

HTTP 메시지 바디를  InputStream을 이용하여 읽은 후 바이너리 데이터를

원하는 인코딩 타입의 문자열로 변환하여 사용할 수 있으며 write 메소드를 통해 HTTP 응답 메세지 바디에 문자열을 입력할 수 있다. 

@Slf4j
@Controller
public class RequestBodyController {
    @PostMapping("/request-body-string-v1")
    public void requestBodyString(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        // Stream은 바이트 코드이기 때문에 문자로 전환할때 인코딩타입을 지정해야한다.
        String messageBody = StreamUtils.copyToString(inputStream,StandardCharsets.UTF_8); 

        log.info("messageBody={}", messageBody);
        response.getWriter().write("ok");
    }
}

스프링이 InputStream(Read), OutPutStream(Writer) 파라미터를 지원하기 때문에 위의 과정을 축소할 수 있다. 

@PostMapping("/request-body-param")
public void requestBodyStringV2(InputStream inputStream, Writer responseWriter) throws IOException {
	String messageBody = StreamUtils.copyToString(inputStream,StandardCharsets.UTF_8);
	log.info("messageBody={}", messageBody);
	responseWriter.write("ok");
}

 

2. HttpEntity 

스프링MVC에서는 HttpEntity 파라미터를 지원한다. 

HttpEntity은 HTTP header, body 정보를 편하게 조회하며 응답에서도  사용 가능하다. 

응답의 경우 메시지 바디 정보를 직접 반환(view 조회X) 하며  헤더 정보 포함 가능하다. 

@PostMapping("/request-body-entity")
public HttpEntity<String> requestBody(HttpEntity<String> httpEntity) { 
 	String messageBody = httpEntity.getBody(); // getBody를 통해 body의 데이터 리턴받는다. 
    
 	log.info("messageBody={}", messageBody);
 	return new HttpEntity<>("ok"); // response body에 데이터 직접 입력
}

HttpEntity 제네릭에 입력된 자료형에 맞게 변환하여 주입해준다.

 

3. RequestEntitiy, ResponseEntity 

HttpEntity 를 상속(Extends)받은 다음 객체들도 같은 기능을 제공한다.

  • RequestEntity  : HTTP요청의 HttpMethod, url 정보 추가 제공
  • ResponseEntity  : HTTP응답 바디 메시지, 상태 코드, 헤더정보 설정 가능
@GetMapping("/response-body-v4")
public ResponseEntity<HelloData> responseBodyV4(RequestEntity<String> test) {
    log.info("test = {}", test.getMethod());
    log.info("test = {}", test.getUrl());
    log.info("getBody = {}", test.getBody());

    HelloData helloData = new HelloData();
    helloData.setUsername("userA");
    helloData.setAge(20);
    // Http 상태코드를 변경할 수 있다.
    return new ResponseEntity<>(helloData, HttpStatus.OK);
}

ResponseEntity 응답 결과

 

위의 기능들을 좀 더 편리하게 사용할 수 있도록 스프링은 애노테이션을 제공한다. 

4. @RequestBody,  @ResponseBody

@RequestBody 애노테이션을 사용하면 HTTP 메시지 바디 정보를 편리하게 조회할 수 있지만

HTTP 헤더 정보를 조회할 수 없다. 

 

@ResponseBody를 사용하면 응답 결과를 HTTP 메시지 바디에 직접 담아서 전달할 수 있지만 

HTTP 헤더 정보를 주입할 수 없다. 

 

Http 상태코드를 입력해야한다면 @ResponseStatus(HttpStatus) 애노테이션을 통하여 입력가능하다.

@ReponseStatus(HttpStatus.OK)
@ResponseBody
@PostMapping("/request-body-anno")
public String requestBodyStringV4(@RequestBody String messageBody) {
	log.info("messageBody={}", messageBody);
 	return "ok";
}

 

 

참고사항

class에 @RestController 입력하면 

  • @Controller 입력
  • 클래스 내부의 메소드에 @ResponseBody입력

두 사항을 수행한것과 같다. 

@Slf4j
@RestController
public class ResponseBodyController {
	
}

@Controller, @ResponseBody 애노테이션이 포함되어있다.

 

 

 

댓글