我是REST环境的新手,我有一个名为Operations的非常简单的bean,具有以下属性
localForage.getItem("data").then((result) => {
dataArray = dataArray.concat(result);
localForage.removeItem("data");
localForage.setItem("data", dataArray);
});
所以要创建一个操作bean,请求JSON将是
public class Operations
{
String operationName,
int operationPriority,
boolean isOperationParallel,
boolean expirationPolicy
}
在服务器端将请求JSON映射到Operations bean我已经使用了Spring ResquestBody,默认情况下,它会使用最后一个键值覆盖重复键,例如,如果下面是请求,则'{
"operationName": "NewOperation",
"operationPriority": 2,
"isOperationParallel": false,
"expirationPolicy": 30
}'
将是operationName
NewOperationTwo
现在我的QA告诉我它应该导致'{
"operationName": "NewOperation",
"operationName": "NewOperationTwo",
"operationPriority": 2,
"isOperationParallel": false,
"expirationPolicy": 30
}'
作为HTTP状态响应。我还被告知如果像“狗”这样的未知属性:“Barks”,它也应该导致400响应也作为request-body的一部分传递,默认情况下Jackson也会忽略它。
现在我的观点是,我可以通过解析请求并查找重复和未知属性来发送400 BAD_REQUEST
,但这是否需要此开销?因为如果它是一个授权,那么Spring默认会返回一个400
响应,而不是。
任何人都可以帮助我,因为对于请求正文中的重复和未知密钥,标准REST API响应是什么?如果我不将BAD_REQUEST作为响应抛出会产生什么后果?
答案 0 :(得分:0)
没有为Json中的重复和未知Key定义标准REST API响应。但是,如果您使用Content-Type
或application/x-www-form-urlencoded
mulitpart/from-data
,请求参数名称应该是唯一的。这不适用于JSON。因为无法确定每个应用程序中的json fromat。
因此,orginazation的业务需求决定了应该如何处理这种情况。软件开发人员角色是在应用程序中实现此约束。
因此,如果您的质量保证工程师说400状态应该被送回来重复 和未知的领域。必须这样做
<强>更新强>
如果JSON请求/响应结构已修复。然后,您可以使用JAXB并将值对象(VO)等模式对象设计为常规POJO来处理传入和传出数据。 使用JAXB将Json绑定到java对象,之后可以使用框架提供的评估功能。如果没有它,它将减少你所付出的巨大努力。如果您正在使用泽西岛,请通过暂停链接获得更多想法
答案 1 :(得分:0)
很抱歉对解决方案的回复很晚,但这就是我的目标,
我为jackson创建了一个自定义的HttpMessageConverter,最初我在MappingJackson2HttpMessageConverter&amp; MappingJacksonHttpMessageConverter 但请阅读Jackson并使用MappingJackson2HttpMessageConverter。
以下是自定义消息转换器,基本上需要覆盖其中的三个方法
read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException
是包含来自请求主体的消息并将其传递给ObjectMapper
的方法public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
private static final Logger logger =
private ObjectMapper objectMapper;
private boolean prefixJson = false;
/*
* (non-Javadoc)
*
* @see org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#setPrefixJson(boolean)
*/
@Override
public void setPrefixJson(boolean prefixJson) {
this.prefixJson = prefixJson;
super.setPrefixJson(prefixJson);
}
/*
* (non-Javadoc)
*
* @see org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#read(java.lang.reflect.Type,
* java.lang.Class, org.springframework.http.HttpInputMessage)
*/
@Override
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
objectMapper.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, true);
objectMapper.configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true);
InputStream istream = inputMessage.getBody();
String responseString = IOUtils.toString(istream);
try {
return objectMapper.readValue(responseString, OperatorTokenDefinition.class);
} catch (UnrecognizedPropertyException ex) {
throw new YourCustomExceptionClass();
} catch (InvalidFormatException ex) {
throw new YourCustomExceptionClass();
} catch (IgnoredPropertyException ex) {
throw new YourCustomExceptionClass();
} catch (JsonMappingException ex) {
throw new YourCustomExceptionClass();
} catch (JsonParseException ex) {
logger.error("Could not read JSON JsonParseException:{}", ex);
throw new YourCustomExceptionClass();
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#supports(java.lang.Class)
*/
@Override
protected boolean supports(Class<?> arg0) {
return true;
}
/*
* (non-Javadoc)
*
* @see org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal(java.lang.Object,
* org.springframework.http.HttpOutputMessage)
*/
@Override
protected void writeInternal(Object arg0, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
objectMapper = new ObjectMapper();
String json = this.objectMapper.writeValueAsString(arg0);
outputMessage.getBody().write(json.getBytes(Charset.defaultCharset()));
}
/**
* @return
*/
private ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
source.setUseCodeAsDefaultMessage(true);
return source;
}
}
现在我们只需要在Spring上下文中注册Custom MessageConverter。在配置类中.Below是代码
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
CustomMappingJackson2HttpMessageConverter jsonConverter =
CustomMappingJackson2HttpMessageConverter();
List<MediaType> mediaTypeList = new ArrayList<MediaType>();
mediaTypeList.add(MediaType.APPLICATION_JSON);
jsonConverter.setSupportedMediaTypes(mediaTypeList);
converters.add(jsonConverter);
super.configureMessageConverters(converters);
}