[Spring] 내가보는 annotation 정리

이혜지·2021년 1월 14일
1

Spring

목록 보기
1/15
post-thumbnail

@RequestBody
@ResponseBody
@RequestParam

들어가면서


스프링에서 비동기 처리를 하는 경우 @RequestBody@ResponseBody를 사용합니다. 두가지를 사용하여 어떻게 비동기 처리를 하는 지 알아보자.

클라이언트와 서버의 비동기 통신 처리


웹에서 이루어지는 데이터를 가져오고, 전송하는 이러한 동작들은 클라이언트(client)와 서버(Server)간의 통신이 이루어지기 때문에 가능하다.

예를들어 우리가 브라우저에서 검색 키워드를 입력하고 검색버튼을 누르게 되면 검색 키워드가 클라이언트(ex.Js)를 통해서 서버(ex.Java)로 전송이 되며 서버에서 검색 키워드를 이용하여, 클라이언트에서 요청한 메시지를 처리하고, 응답을 만들어서 다시 클라이언트로 보내며 클라이언트는 화면에 뿌리는 역할을 하게 된다.

여기서 중요한 것이
요청(request)과 응답(response)이다. 즉, 클라이언트에서 서버로 통신하는 메시지를 요청 메시지라고 하며, 서버에서 클라이언트로 통신하는 메시지를 응답 메시지라고 한다.

보통 웹에서 화면 전환(refresh, f5)이 없이 이루어지는 동작들은 대부분 비동기 통신으로 이루어진다. 비동기 통신을 하기위해서 클라이언트가 서버로 요청 메시지의 본문에 데이터를 담아서 보내야하며, 서버도 클라이언트로 응답을 보내기 위해서는 응답 메시지의 본문에 데이터를 담아서 보내야한다.

여기서 또 중요한 것은 본문(body)이다.
위에서 첫 번째로 강조한 포인트 요청과 응답, 두번째로 강조한 포인트인 본문 이렇게 요청본문(RequestBody)와 응답 본문(ResponseBody)라는 단어가 만들어진다.

그러면 본문에 담겨야 하는 데이터의 형식은 무엇일까?

대표적으로 사용되는것이 JSON형식이다.(Javascript Object Notation)이다.

요청 본문에 담긴 값을 자바 객체로 Conversion


@RequestBody를 통해 자바 객체로 Conversion을 할때 그냥 변환되는것이 아니라, HttpMessageConverter를 사용하는데 아래의 메서드에 각종의 메시지 컨버터가 설정되어있다.

만약 요청이 json으로 들어온 경우 요청헤더에(request header)에 컨텐츠 타입(Content-Type)을 알려줘야 한다. 그러면 헤더에 있는 컨텐츠 타입을 보고 JSON을 컨버팅 할 수 있는 컨버터(Jaction2ObjectMapperBuilder)를 사용해야겠다 라고 JSON을 자바 객체로 변환하는 메시지 컨버터를 사용하여 요청 본문에 담긴 데이터를 자바 객체로 변환하게 되는 것이다.

@RestController
@RequestMapping("/api")
public class HttpMessageController{
	/**
  * @RequestBody를 통해 자바 객체로 변환할 때 HttpMessageConverter를 사용하여 
  * 헤더에 담긴 컨텐츠 타입을 보고 어떤 메시지 컨버터를 사용할 것인지 판단하여 
  * 요청 본문에 담긴 값을 자바 객체로 변환
  */
  @GetMapping
  public String create(@RequestBody Event event){
  	//생략
  	return "redirect:/api/list";
  }
}

Jackson2ObjectMapperBuiler는 스프링부트에서 JacksonAutoConfiguration클래스에서 자동으로 설정하기 때문에 별다른 설정없이 JSON을 자바 객체로 변환하는 ObjectMapper를 사용할 수 있다.

Jackson2ObjectMapperBuiler내부를 보면 autoDetectGettersSetters()라는 메서드를 사용합니다. 즉, JSON타입으로 변환하기 위한 객체(DTO)에 gettersetter메서드가 존재해야 한다는 뜻입니다.

public Jackson2ObjectMapperBuilder autoDetectGettersSetters(boolean autoDetectGettersSetters){
	this.features.put(MapperFeature.AUTO_DETECT_GETTERS, autoDetectGettersSetters); this.features.put(MapperFeature.AUTO_DETECT_SETTERS, autoDetectGettersSetters);
this.features.put(MapperFeature.AUTO_DETECT_IS_GETTERS, autoDetectGettersSetters);
}

만약 getter/setter가 존재하지 않으면 응답 메시지를 내보낼때 Jackson2ObjectMapperBuilder를 제대로 사용하지 못해서 JSON타입으로 변환이 제대로 되지않아 클라이언트(JS)단에서 success()함수로 결과값(res)를 받아올 수 없다.

@RequiredArgsConstructor
@RequestMapping("/test")
@RestController
public class RequestBodyTestController{
	private final TestService testService;
    
	/*
   * TestDto 에 getter, setter 메서드가 없으면
   * JSON 타입 변환에 실패하여 JS 의 success 함수가 아닌 error 함수를 타게 된다.
   */
   @RequestMapping(/"search)
   public TestDto search(TestVo testVo){
   	TestVo result = testService.findTest(testVo);
    return result.toDto();
   }
}

스프링부트의 pom.xml을 보면 (혹은 gradle의 build.gradle) spring-boot-starter-web이 존재하는데 내부에 들어가보면 jackson-databind 의존성이 자동으로 잡혀있는것을 볼 수 있다. 해당 의존성이 있어야 JSON타입으로 제대로 변환이 된다.

정리


클라이언트에서 서버로 필요한 데이터를 전송하기 위해서 JSON이라는 데이터를 요청 본문에 담아서 서버로 보내면, 서버에서는 @RequestBody어노테이션을 사용하여 http 요청 본문에 담긴 값들을 자바 객체로 변환시켜, 객체에 저장시킵니다.

서버에서 클라이언트로 응답 데이터를 전송하기 위해서 @ResponseBody를 사용하여 자바 객체를 Http 응답 본문의 객체로 변환하여 클라이언트로 전송 시키는 역할을 합니다.

@RequestParam


@RequestParam어노테이션은 단일 파라미터를 전달 받을때 사용하는 어노테이션 이다.

JSP 작성

left메뉴를 하나 생성, form으로 전달할 데이터를 지정한다.

<form id="frm" method="get" action="">
	<input type="hidden" name="pageName" id="pageName">
    	<input type="hidden" name="country" id="country" value="러시아">
 </form>

Controller 작성

아래와 같이 @RequestParam 메서드를 작성하고, jsp로부터 전달된 key를 작성한다.

@RequestMapping(value="/ReqParam.do")
	public String ReqParam(@RequestParam String country) throws Exception{
    	System.out.println("@RequestParam : " + country);
        return "DataReqRes/RequestParam.tiles";
    }

이러면 key에 대한 value가 확인된다.

profile
공유 문화를 지향하는 개발자입니다.

1개의 댓글

comment-user-thumbnail
2023년 3월 14일

제가 스프링에서 ajax로 json데이터를 보내다가 에러가 났는데 스프링에선 json을 자바 객체로 변환해줄 클래스가 없는거 맞나요??

답글 달기