부모 클래스와 달리 응답처리 기능이 존재한다. 즉, 웹전용 클래스이다
@RequestBody 로 파라미터를 찾을시 ArgumentResolver 구현체로 RequestResponseBodyMethodProcessor를 사용한다
// ReqeustBody annotation이 있는지
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestBody.class);
}
HttpMessageConverter 또한 여러 구현체가 있다
// 요청본문을 읽을 수 있는지 판단한다
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
@Nullable
protected Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter, Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
ServletServerHttpRequest inputMessage = this.createInputMessage(webRequest);
Object arg = this.readWithMessageConverters(inputMessage, parameter, paramType);
if (arg == null && this.checkRequired(parameter)) {
throw new HttpMessageNotReadableException("Required request body is missing: " + parameter.getExecutable().toGenericString(), inputMessage);
} else {
return arg;
}
}
this.returnValueHandlers.handleReturnValue
public boolean supportsReturnType(MethodParameter returnType) {
return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);
}
hnadleReturnValue 실행
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
mavContainer.setRequestHandled(true);
ServletServerHttpRequest inputMessage = this.createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = this.createOutputMessage(webRequest);
if (returnValue instanceof ProblemDetail detail) {
outputMessage.setStatusCode(HttpStatusCode.valueOf(detail.getStatus()));
if (detail.getInstance() == null) {
URI path = URI.create(inputMessage.getServletRequest().getRequestURI());
detail.setInstance(path);
}
this.invokeErrorResponseInterceptors(detail, (ErrorResponse)null);
}
this.writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}
}
writeWithMessageConverters 쓰기작업하면서 messageConverter 사용
acceptableTypes = this.getAcceptableMediaTypes(request);
acceptable 한지 확인
일련의 과정 진행 후 하나의 컨버터가 선택된다
쓰기작업
switch (converterTypeToUse) {
case BASE -> converter.write(body, selectedMediaType, outputMessage);
case GENERIC -> ((GenericHttpMessageConverter)converter).write(body, targetType, selectedMediaType, outputMessage);
case SMART -> ((SmartHttpMessageConverter)converter).write(body, targetResolvableType, selectedMediaType, outputMessage, (Map)null);
}