我在使用Spring Boot的API构建的json映射中使用了蛇形外壳。 spring使您可以使用以下命令在application.properties文件中轻松定义它:
spring.jackson.property-naming-strategy=SNAKE_CASE
这很好。但是,如果我添加验证并且尝试发布无效的json正文,则响应消息中包含驼峰大小写的缺少字段。这是我的控制器和传输对象:
import javax.validation.constraints.NotNull;
public class MyObject {
@NotNull
String camelCasedField;
public MyObject() {}
public String getCamelCasedField() {
return camelCasedField;
}
public void setCamelCasedField(String camelCasedField) {
this.camelCasedField = camelCasedField;
}
}
控制器:
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@RestController
@RequestMapping("/api/test")
public class MyController {
@PostMapping
public void createTenant(@RequestBody @Valid MyObject myObject) {}
}
如果我发布以下json主体,则一切正常: _ {“ camel_cased_field”:“测试”}
如果我发布一个空的json正文,则会收到预期的错误,但字段名称是驼峰大小写而不是蛇形大小写:
{
"timestamp": "2018-08-23T07:43:18.987+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"NotNull.myObject.camelCasedField",
"NotNull.camelCasedField",
"NotNull.java.lang.String",
"NotNull"
],
"arguments": [
{
"codes": [
"myObject.camelCasedField",
"camelCasedField"
],
"arguments": null,
"default_message": "camelCasedField",
"code": "camelCasedField"
}
],
"default_message": "must not be null",
"object_name": "myObject",
"field": "camelCasedField", // should be camel_cased_field
"rejected_value": null,
"binding_failure": false,
"code": "NotNull"
}
],
"message": "Validation failed for object='myObject'. Error count: 1",
"path": "/api/test"
}
是否有一种方法可以针对Spring应用程序的所有端点进行修复?
答案 0 :(得分:0)
默认情况下,javax.validation
框架将使用Bean字段框,通常是Java Bean字段的驼峰框。
但是有一种改变方式。这不是一个简单的方法,但是有一种方法。
RestControllerAdvice
来处理项目中的异常。 (通常是大多数spring应用程序的一部分)MethodArgumentNotValidException
和ConstraintViolationException
异常添加处理程序。一种用于POST正文违规,另一种用于路径/查询字符串验证违规。MethodArgumentNotValidException
公开了一个BindingResult
字段,该字段具有FieldError
对象的列表,并且每个字段错误对象都有一个名为“ field
”的字段。您需要使用反射将此字段的值从骆驼肠衣设置为所需的任何肠衣。ConstraintViolationException
公开了一个您可以操纵的名为“ propertyPath
”的字段。请注意,如果您未在http 400响应中原样发出MethodArgumentNotValidException
,则可以避免反射和避免很多痛苦。通常,人们处理此异常并提取字段名称和消息,然后在http 400(或422 :))响应中将这些消息作为列表发出。如果这样做,则只需转换字段名称,而不会弄乱FieldError
对象内部的私有值。
以下是示例:
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ExceptionResolver {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(value = HttpStatus.UNPROCESSABLE_ENTITY)
public ErrorResponse handleMethodArgumentNotValidException(HttpServletRequest request,
MethodArgumentNotValidException ex) {
final List<String> errorMessages = new ArrayList<>();
final BindingResult bindingResult = ex.getBindingResult();
if (bindingResult.hasErrors()) {
final List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrorList) {
String kebabFieldName = YOUR_METHOD_TO_CONVERT_CAMEL_TO_KEBAB(fieldError.getField());
// use kebabFieldName and message to construct your response.
}
}
}
}
如果您使用google-guava帮助器jar,则是YOUR_METHOD_TO_CONVERT_CAMEL_TO_KEBAB的示例。
String kebab = com.google.common.base.CaseFormat.LOWER_CAMEL
.to(CaseFormat.LOWER_UNDERSCORE, fieldError.getField());
如果您找到更简单的方法,请告诉我!干杯。