[스프링 숲] 메세지 컨버터, BufferedReader-BufferedWriter

byeol·2023년 4월 16일
0

최주호님의 스프링부트 개념정리 강의를 들으며 생겼던 의문점(✅)들을 정리해보려고 합니다.
평소에 Json에 대해 떠다녔던 개념들을 정리하겠습니다.

메세지 컨버터

메세지 컨버터는 중간 데이터의 역할을 합니다.

만약에
외국인과 대화를 할 때 나와 외국인이 모두가 이해할 수 있는 중간데이터가 존재한다면
한국어를 외국어로 바꾸거나
외국어를 한국어로 바꾸지 않고

모두가 이해할 수 있는 중간데이터로 바꾸는 일이 더 편리합니다.

즉 Java의 object를 파이썬 object로 바꾸는 일은 어렵지만
중간 데이터인 Json으로 바꾸는 일은 쉽습니다.

이와 같이 Json과 같이 중간데이터로 바꾸는 역할을 담당하는 것이 메세지 컨버터입니다.

✅ 그렇다면 응답과 요청을 Json의 형태로 하는 방법에 대해 궁금증이 생겼습니다.

  • Response
    class에 @RestController 어노테이션을 붙이면 하위 메소드들은 모두 @ResponseBody 어노테이션을 가지게 되며 return의 객체를 Json의 형태로 반환합니다.

    @RestController
    public class TestController {
    
      @RequestMapping("/test1")
      public Blog test1(){
    
          Blog blog = new Blog();
    
          blog.setTitle("테스트1");
          blog.setContent("테스트1 내용");
    
          return blog;
    
      }
    }

    혹은 @Controller가 붙은 클래스 중에서 몇 개를 Json형태의 응답을 보내고 싶을 때는 @ResponseBody를 붙입니다.

    @Controller
    public class TestController {
    
     @ResponseBody
     @RequestMapping("/test1")
     public Blog test1(){
    
         Blog blog = new Blog();
    
         blog.setTitle("테스트1");
         blog.setContent("테스트1 내용");
    
         return blog;
    
     }
    }
  • Request
    커맨드 객체에 @RequestBody를 선언해서 Json으로 오는 요청 객체를 Java 객체로 바꿉니다.

    @RestController
    public class RestMemberController {
        ...
        @PostMapping("/api/members")
        public ResponseEntity<Object> newMember(
                            // 다음 어노테이션을 붙임으로, JSON 형식의 문자열을 해당 자바 객체로 변환
                @RequestBody @Valid RegisterRequest regReq ) {
            try {
                Long newMemberId = registerService.regist(regReq);
                URI uri = URI.create("/api/members/" + newMemberId);
                return ResponseEntity.created(uri).build();
            } catch (DuplicateMemberException dupEx) {
                return ResponseEntity.status(HttpStatus.CONFLICT).build();
            }
        }
        ...
    }

reference

스프링은 BufferedReader와 BufferedWriter를 쉽게 사용할 수 있다.

통신은 0,1과 같이 전류가 흐르는가 흐르지 않는가로 나뉘는 bit단위로 통신합니다.
하지만 우리의 언어는 하나의 bit로 이루어진 것이 아니라 여러개의 bit로 이루어져 있습니다.
처음 통신은 영어권에서 시작했기 때문에
영어의 알파벳은 8개의 bit로 통신이 가능했고 그래서 8개씩 끊어 읽으라는 약속을 하게 되었습니다. 그래서 이 8bit를 1Byte라고 논리적인 단위로 만들게 되었습니다. 통신의 최소 단위는 1Byte입니다.

통신은 1Byte를 최소 단위로 하는 Byte Stream을 통해서 이루어지며 프로그램에서 이를 읽을 때InputStrem을 통해 읽습니다. 바이트로 읽기 때문에 이는 데이터를 처리할 때 불편하기 때문에 InputStreamReader를 통해서 1Byte를 하나의 문자로 바꾸게 됩니다. 그러나 들어오는 문자는 하나의 문자가 아니라 여러개의 문자로 이루어져 있습니다. "곰"이라는 하나의 문자가 아니라 "안녕"처럼 여러개의 문자로 이루어져 있을 수 있습니다.

따라서 여러 개의 문자를 읽기 위해서 InputStreamReader를 배열로 만들어 받으려고 했으나 배열의 경우에는 크기를 고정시켜 정해놓아야 합니다.
따라서 들어오려는 문자의 길이를 알고 있어야 하는데 들어오는 모든 문자의 길이를 예상하는 것은 쉽지 않습니다.

만약에 문자열의 최대를 10이라고 가정하고 배열의 길이를 10으로 해놓는다면
하나의 문자가 100번 들어오고 10개로 이루어진 단어가 50번 들어온다면
메모리 낭비가 일어납니다.

따라서 BufferedReader를 이용해서 가변 길이의 문자를 받게됩니다.

BufferedReader br = new BufferedReader(InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(OutputStreamWriter(System.out);

위와 같이 선언해서 주고 받아야 합니다.

하지만 스프링에서는 좀 더 편리하게 받을 수 있도록
@ResponseBody와 @RequestBody를 제공합니다.
즉 위와 같이 BufferedReader와 BufferedWriter를 선언하지 않고도 쉽게 사용하게 된 것입니다.

profile
꾸준하게 Ready, Set, Go!

0개의 댓글