Hibernate Validator 和 Jackson:使用 @JsonProperty 值作为 ConstraintViolation PropertyPath?

2023-11-27

假设我有一个简单的 POJO,如下所示,用 Jackson 2.1 和 Hibernate Validator 4.3.1 注释进行注释:

final public class Person {
  @JsonProperty("nm")
  @NotNull
  final public String name;

  public Person(String name) {
      this.name = name;
  }
}

我将这样的 JSON 发送到 Web 服务:

{"name": null}

Hibernate 在报告 ConstraintViolation 时使用类成员标识符“name”而不是 JsonProperty 注释值。有谁知道是否可以让 Hibernate 验证器查看类的注释并使用该值?


不幸的是,没有简单的方法可以做到这一点。但这里有一些可以帮助您的见解:

解析约束违规

来自ConstraintViolationException,你可以得到一组ConstraintViolation,暴露约束违规上下文:

  • ConstraintViolation#getLeafBean():如果是 bean 约束,则此方法返回应用该约束的 bean 实例。
  • ConstraintViolation#getPropertyPath():返回无效属性的路径。

从属性路径中,可以得到叶子节点:

Path propertyPath = constraintViolation.getPropertyPath();
Optional<Path.Node> leafNodeOptional = 
        StreamSupport.stream(propertyPath.spliterator(), false).reduce((a, b) -> b);

然后检查节点的类型是否为PROPERTY并得到它的名字:

String nodeName = null;

if (leafNodeOptional.isPresent()) {
    Path.Node leafNode = leafNodeOptional.get();
    if (ElementKind.PROPERTY == leafNode.getKind()) {
        nodeName = leafNode.getName();
    }
}

与杰克逊一起反思课堂

要从叶 bean 类获取可用的 JSON 属性,您可以使用 Jackson 进行内省(请参阅此answer和这个answer欲了解更多详情):

Class<?> beanClass = constraintViolation.getLeafBean().getClass();
JavaType javaType = mapper.getTypeFactory().constructType(beanClass);

BeanDescription introspection = mapper.getSerializationConfig().introspect(javaType);
List<BeanPropertyDefinition> properties = introspection.findProperties();

然后通过将叶节点名称与Field名字来自于BeanPropertyDefinition:

Optional<String> jsonProperty = properties.stream()
        .filter(property -> nodeName.equals(property.getField().getName()))
        .map(BeanPropertyDefinition::getName)
        .findFirst();

使用 JAX-RS?

使用 JAX-RS(如果您正在使用它),您可以定义一个ExceptionMapper处理ConstraintViolationExceptions:

@Provider
public class ConstraintViolationExceptionMapper 
                 implements ExceptionMapper<ConstraintViolationException> {

    @Override
    public Response toResponse(ConstraintViolationException exception) {
        ...
    }
}

要使用ObjectMapper在你的ExceptionMapper,你可以提供一个ContextResolver<T> for it:

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperContextResolver() {
        mapper = createObjectMapper();
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }

    private ObjectMapper createObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
    }
}

注入Providers界面在你的ExceptionMapper:

@Context
private Providers providers;

查找您的ContextResolver<T>然后得到ObjectMapper实例:

ContextResolver<ObjectMapper> resolver = 
        providers.getContextResolver(ObjectMapper.class, MediaType.WILDCARD_TYPE);
ObjectMapper mapper = resolver.getContext(ObjectMapper.class);

如果您有兴趣获得@XxxParam名字可以参考这个answer.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate Validator 和 Jackson:使用 @JsonProperty 值作为 ConstraintViolation PropertyPath? 的相关文章

随机推荐

  • (React) CSSTransition 与 css 模块

    我正在尝试在我的项目中实现 CSSTransition 到模式 问题是我正在使用 css 模块 我的模态的渲染方法 render return
  • 检测 html 表单是否被编辑的通用方法

    我有一个选项卡式 html 表单 从一个选项卡导航到另一选项卡时 即使数据没有更改 当前选项卡的数据也会保留 在数据库上 我想仅在编辑表单时才进行持久性调用 该表单可以包含任何类型的控件 不一定要通过键入一些文本来弄脏表单 但在日历控件中选
  • 如果为空则创建新实例的简写?

    在 Javascript 中我可以这样做 var myVar returnNull new MyObject 在 C 中 我目前正在这样做 var myVar returnObjectOrNull if myVar null myVar n
  • 在 mongodb 中存储赞成票/反对票

    我有一个收藏Posts and Users用户可以对每个帖子投赞成票 反对票 将其存储在 mongodb 数据库中以确保用户不能多次为给定文档投票的最佳方法是什么 我想出的最简单的 nosql ish 解决方案是存储在每个内部投票的 use
  • 跨平台网络 API [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我想知道是否有一个 API 可以在 Windows Mac 和 Linux 上运行网络 我想做一个2人可以通过TCP连接玩的纸牌游戏 有几个选项可以
  • 使用ngrx一次获取store的当前状态

    您好 我想知道是否有人知道如何在无需订阅的情况下获取商店的当前状态 我目前正在使用 ngrx 订阅商店并访问其状态以设置组件的属性 但由于我订阅了该属性 所以它会不断刷新 因此 我正在寻找一种仅获取此属性一次的方法 以便我可以显示数据而无需
  • Android 滑动布局来关闭

    我正在尝试制作一个可滑动的布局 这样你就可以像现在在谷歌中一样滑动它来关闭 我设法使用以下代码让它在诸如按钮之类的视图上工作 SwipeDismissTouchListener public class SwipeDismissTouchL
  • 为什么 C# 似乎部分未转义命令行参数?

    我试图将多个路径作为参数传递给控制台应用程序 但收到 路径中的非法字符 错误 参数的最后两个字符似乎出现了错误 C test 对于转义的双引号 例如 如果我用 C 创建一个新的空控制台应用程序 如下所示 static void Main s
  • 命令光标的对象不可下标

    我是 Python 和 MongoDB 的新手 我正在使用 Flask python 和 MongoDB 开始一个新项目 当我尝试使用返回数据时aggregate 函数 它给我以下错误 命令光标的对象不可下标 这是我的查询代码 Data d
  • 使用 contenteditable div 而不是 textarea 的自动完成似乎不起作用

    我正在使用 Andrew Whitaker 的自动完成插件 这个问题也提到了 jquery 自动完成 mention 如果我使用 contenteditable div 而不是文本区域 这将不起作用 这是我的代码 div div MyTex
  • Python 中的曲面曲率 Matlab 等效项

    我试图计算由点数组 x y z 给出的曲面的曲率 最初我试图拟合多项式方程 z a bx cx 2 dy exy fy 2 然后计算高斯曲率 K frac F xx cdot F yy F xy 2 1 F x 2 F y 2 2 然而 如
  • 如何检查两个模板参数是否完全相同?

    如何修改以下函数模板 使其返回 42 if 模板参数T and U是完全相同的类型吗 template
  • 运行用 C 编写的程序时“未找到”Cygwin1.dll。如何让 Windows 找到它?

    所以我试图运行我的第一个用 C 编写的 hello world 程序 IS 在 eclipse 中编译它并且没有错误 但是当我尝试运行它时我得到 此应用程序无法启动 因为找不到 cygwin1 dll I found 这个帖子这似乎表明我应
  • 获取属性的 JsonPropertyAttribute

    我发现一篇文章对我遇到的问题提供了很好的答案 但我似乎找不到我正在寻找的小细节 public class myModel JsonProperty PropertyName id public long ID get set JsonPro
  • Java 中的花括号本身意味着什么?

    我有一些 Java 代码以两种方式使用花括号 Curly braces attached to an if statement if node getId null node getId apply this Curly braces by
  • 为什么需要等效方法重载?

    我浏览了Google制作的一些JAVA代码 发现了ImmutableSet http google collections googlecode com svn trunk javadoc com google common collect
  • 使用CSS删除图像之间的空格[重复]

    这个问题在这里已经有答案了 Given img src img src 结果是两个图像之间只有一个空格 看起来正常的行为是将任意数量的空格 换行符和制表符显示为单个空格 我知道我可以执行以下操作 img src img src OR img
  • JSF 视图在每个 ajax 请求上重建

    我的 JSF RichFaces Facelets ajax 请求遇到性能问题 据我所知 因为每个 ajax 请求都会重建整个组件树 即使我使用 ajaxSingle true 在 a4j region 中包装部分 声明一个用于重新渲染的部
  • SQL服务器; TEXT 列上的索引

    我有一个包含几列的数据库表 他们中的大多数是VARCHAR x 类型列 其中一些列上有索引 以便我可以快速搜索其中的数据 然而 其中一列是TEXT列 因为它包含大量数据 23 kb 纯 ascii 文本等 我希望能够在该栏中搜索 WHERE
  • Hibernate Validator 和 Jackson:使用 @JsonProperty 值作为 ConstraintViolation PropertyPath?

    假设我有一个简单的 POJO 如下所示 用 Jackson 2 1 和 Hibernate Validator 4 3 1 注释进行注释 final public class Person JsonProperty nm NotNull f