in common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java [164:244]
private Object getValueImpl(HttpServletRequest request) throws IOException {
Object body = request.getAttribute(RestConst.BODY_PARAMETER);
if (body != null) {
return convertValue(body, targetType);
}
// edge support convert from form-data or x-www-form-urlencoded to json automatically
String contentType = validContentType(request.getContentType());
// support RFC 7231, ignore case for content-type
if (StringUtils.equalsIgnoreCase(contentType, MediaType.MULTIPART_FORM_DATA)
|| StringUtils.equalsIgnoreCase(contentType, MediaType.APPLICATION_FORM_URLENCODED)) {
return convertValue(request.getParameterMap(), targetType);
}
// for standard HttpServletRequest, getInputStream will never return null
// but for mocked HttpServletRequest, maybe get a null
// like org.apache.servicecomb.provider.springmvc.reference.ClientToHttpServletRequest
InputStream inputStream = request.getInputStream();
if (inputStream == null) {
return null;
}
if (StringUtils.equalsIgnoreCase(contentType, MediaType.APPLICATION_JSON)) {
try {
ObjectReader reader = serialViewClass != null
? RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)
: RestObjectMapperFactory.getRestObjectMapper().reader();
if (decodeAsObject()) {
return reader.forType(OBJECT_TYPE).readValue(inputStream);
}
return reader.forType(targetType == null ? OBJECT_TYPE : targetType)
.readValue(inputStream);
} catch (MismatchedInputException e) {
// there is no way to detect InputStream is empty, so have to catch the exception
if (!isRequired && e.getMessage().contains("No content to map due to end-of-input")) {
LOGGER.info("Empty content and required is false, taken as null");
return null;
}
throw e;
}
}
if (StringUtils.equalsIgnoreCase(contentType, SwaggerConst.PROTOBUF_TYPE)) {
ProtoMapper protoMapper = scopedProtobufSchemaManager
.getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),
REQUEST_BODY_NAME,
requestBody.getContent().get(SwaggerConst.PROTOBUF_TYPE).getSchema());
RootDeserializer<PropertyWrapper<Object>> deserializer = protoMapper.getDeserializerSchemaManager()
.createRootDeserializer(protoMapper.getProto().getMessage(REQUEST_BODY_NAME),
targetType == null ? OBJECT_TYPE : targetType);
PropertyWrapper<Object> result = deserializer.deserialize(inputStream.readAllBytes());
return result.getValue();
}
if (StringUtils.equalsIgnoreCase(contentType, MediaType.TEXT_PLAIN)) {
try {
if (targetType != null && String.class.equals(targetType.getRawClass())) {
return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
ObjectReader reader = serialViewClass != null
? RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)
: RestObjectMapperFactory.getRestObjectMapper().reader();
if (decodeAsObject()) {
return reader.forType(OBJECT_TYPE).readValue(inputStream);
}
return reader.forType(targetType == null ? OBJECT_TYPE : targetType)
.readValue(inputStream);
} catch (MismatchedInputException e) {
// there is no way to detect InputStream is empty, so have to catch the exception
if (!isRequired && e.getMessage().contains("No content to map due to end-of-input")) {
LOGGER.info("Empty content and required is false, taken as null");
return null;
}
throw e;
}
}
throw new IllegalArgumentException(String.format("operation %s not support content-type %s",
operationMeta.getSchemaQualifiedName(), contentType));
}