当前位置: 首页 > 知识库问答 >
问题:

Spring蛇案例及验证错误响应

杜昆琦
2023-03-14

我正在使用snake-case对我的API构建与springboot进行json映射。spring允许您在应用程序中轻松定义这一点。属性文件,其中包含:

spring.jackson.property-naming-strategy=SNAKE_CASE

这个很好用。但是,如果我添加了验证,并试图发布一个无效的json正文,那么响应消息将包含camel案例中缺少的字段。以下是我的控制器和传输对象:

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\u cased\u字段”:“test”}

如果我张贴一个空的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应用程序的所有endpoint的问题?

共有1个答案

郎和志
2023-03-14

默认情况下,javax。验证framework将使用Bean字段大小写,这通常是javabean字段的驼峰大小写。

但有一种方法可以改变这一点。这不是一个简单的方法,但是有一种方法。

  • 定义RestControllerAdvice以处理项目中的异常。(这通常是大多数spring应用程序的一部分)
  • MethodArgumentNotValidExceptionConstraintViolationException异常添加处理程序。一个用于POST正文冲突,另一个用于路径/查询字符串验证冲突
  • MethodArgumentNotValidException公开一个BindingResult字段,该字段包含一个FieldError对象列表,每个FieldError对象都有一个名为“field”的字段。您需要使用反射将此字段的值从驼峰大小写设置为所需的大小写
  • 类似地,ConstraintViolationException公开了一个名为“propertyPath”的字段,您可以对该字段进行操作

请注意,如果您没有像http 400响应中那样发出MethodArgumentNotValidException,您可以避免反射和许多痛苦。通常,人们处理这个异常并提取字段名和消息,然后在HTTP400(或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.
      }
    }
  }
}

YOUR_METHOD_TO_CONVERT_CAMEL_TO_KEBAB的一个例子是,如果你使用谷歌番石榴助手罐。

String kebab = com.google.common.base.CaseFormat.LOWER_CAMEL
                    .to(CaseFormat.LOWER_UNDERSCORE, fieldError.getField());

如果你有更简单的方法,请告诉我!干杯

 类似资料:
  • 状态{statuscode=network_error,resolution=null} 任何形式的帮助都将受到高度赞赏。

  • 问题内容: 非常奇怪的错误。我使用的是http://developers.facebook.com/docs/authentication/。所以我创建了对fb的请求并传递redirect_uri。我在本地主机上使用测试站点。所以如果我通过 redirect_uri = http://localhost/test_blog/index.php 它工作正常,但如果我通过 redirect_uri =

  • 问题内容: 我想自定义弹簧验证错误 但是我做不到。要采取的步骤是什么? 问题答案: 该JSR 303的默认邮件插补算法,您可以通过提供捆绑命名的资源来定制信息。在类路径中创建一个文件,其中包含: 这将更改@Size约束的默认消息,因此您应该使用@Size约束而不是特定于Hibernate的@Length约束。 您可以更改特定约束实例的消息,而不是更改所有约束的默认消息。message在约束上设置属

  • 嗨,我到处找,但找不到解决方案。我正在Jquery函数中调用ajax,并从spring输入表单提交数据:输入到控制器。控制器通过JSR 303 Hibernate验证验证日期,并通过JSON将错误返回给同一Jquery函数(通过JSON接收数据),并在jsp中显示错误。一切正常,但显示的错误消息只是dafault或来自验证注释的消息参数。我想从ValidationMessages中获取错误消息。属

  • 我正在使用powermock。mockstatic这条线吹,这样我就可以控制它的返回值,因为它唯一的摆动我不必测试它。 但是它会抛出java.lang.VerifyError。我做了很多嘲笑这种事情,没有例外。删除“准备测试”和“运行”有所帮助,但是当我这样做的时候我会失去powermock。我的详细错误也在下面;

  • 我得到了以下错误无法构建Hibernate SessionFactory;嵌套异常是org.hibernate.tool.schema.spi.模式管理异常:模式验证:缺少表[my.table] 这有版本问题吗?大多数示例都不使用模式,即使是官方的?https://github.com/spring-projects/spring-boot/tree/main/spring-boot-tests/