自定义Bean Validation异常处理器实现与应用

ops/2025/2/2 6:21:21/

在Java的JAX-RS框架中,Bean Validation是一个非常强大的功能,它可以用于验证输入数据是否符合预期的规则。然而,默认情况下,当验证失败时,Jersey会抛出ConstraintViolationException,并返回一个“Bad Request”(400)错误。虽然这已经足够用于基本的验证,但有时候我们可能需要更详细的错误信息来帮助用户理解问题所在。本文将通过一个完整的示例,展示如何实现自定义的ExceptionMapper来返回更友好的验证错误信息。

  1. 实现自定义ExceptionMapper
    为了实现自定义的异常处理逻辑,我们需要创建一个实现了ExceptionMapper接口的类。以下是具体的实现代码:
    java复制
    @Provider
    public class MyExceptionMapper implements ExceptionMapper {
    @Override
    public Response toResponse(final ConstraintViolationException exception) {
    return Response.status(Response.Status.BAD_REQUEST)
    .entity(prepareMessage(exception))
    .type(“text/plain”)
    .build();
    }

    private String prepareMessage(ConstraintViolationException exception) {
    StringBuilder msg = new StringBuilder();
    for (ConstraintViolation<?> cv : exception.getConstraintViolations()) {
    msg.append(cv.getPropertyPath()).append(" “).append(cv.getMessage()).append(”\n");
    }
    return msg.toString();
    }
    }
    在这个实现中,toResponse方法会捕获ConstraintViolationException,并调用prepareMessage方法来生成详细的错误信息。prepareMessage方法会遍历所有的验证错误,并将它们格式化为一个字符串,最终返回给客户端。

  2. 创建带有验证注解的JAX-RS资源
    接下来,我们需要创建一个JAX-RS资源类,并在其中使用Bean Validation注解来定义验证规则。以下是一个简单的示例:
    java复制
    @Path(“/customers”)
    public class CustomerResource {
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public String createCustomer(@NotNull @FormParam(“name”) String name,
    @NotNull @FormParam(“address”) String address,
    @NotNull @Pattern(regexp = “\d{3}-\d{3}-\d{4}”)
    @FormParam(“phone-number”) String phoneNumber) {
    System.out.println(“-- in createCustomer() method --”);
    return String.format(“created dummy customer name: %s, address: %s, phoneNumber:%s%n”,
    name, address, phoneNumber);
    }
    }
    在这个资源类中,我们定义了一个createCustomer方法,它接收三个表单参数:name、address和phone-number。我们使用了@NotNull注解来确保这些参数不能为空,并且使用了@Pattern注解来验证phone-number是否符合特定的格式。

  3. 测试自定义异常处理逻辑
    为了测试我们的自定义异常处理逻辑,我们可以编写一个简单的JAX-RS客户端来发送请求并接收响应。以下是客户端的代码:
    java复制
    public class MyClient {
    public static void main(String[] args) throws Exception {
    Form form = new Form();
    form.param(“name”, null)
    .param(“address”, null)
    .param(“phone-number”, “343-343-343”);
    Client client = ClientBuilder.newBuilder().build();
    WebTarget target = client.target(“http://localhost:8080/customers”);
    Future future = target.request(MediaType.APPLICATION_FORM_URLENCODED)
    .buildPost(Entity.form(form))
    .submit(Response.class);
    Response r = future.get();
    if (r.getStatus() != Response.Status.OK.getStatusCode()) {
    System.out.println(r.getStatus() + " - " + r.getStatusInfo());
    }
    System.out.println(r.readEntity(String.class));
    }
    }
    在这个客户端中,我们故意发送了一个无效的请求,其中name和address参数为空,phone-number参数不符合格式。运行客户端后,我们得到了以下输出:
    复制
    400 - Bad Request
    createCustomer.arg0 may not be null
    createCustomer.arg1 may not be null
    createCustomer.arg2 must match “\d{3}-\d{3}-\d{4}”
    可以看到,我们的自定义ExceptionMapper成功地返回了详细的验证错误信息。

  4. 项目依赖与技术栈
    为了运行上述示例,我们需要以下依赖和环境:
    jersey-server 2.25.1:Jersey核心服务器实现。
    jersey-container-servlet 2.25.1:Jersey核心Servlet 3.x实现。
    jersey-bean-validation 2.25.1:Jersey扩展模块,提供对Bean Validation(JSR-349)API的支持。
    JDK 1.8
    Maven 3.5.4
    通过上述依赖和环境,我们可以轻松地实现和测试自定义的Bean Validation异常处理逻辑。
    总结
    通过实现自定义的ExceptionMapper,我们可以更好地控制Bean Validation失败时的响应行为,从而为用户提供更友好的错误信息。这不仅可以提高用户体验,还可以帮助开发人员更快地定位问题。希望本文的示例能够帮助你更好地理解和应用这一技术。


http://www.ppmy.cn/ops/154964.html

相关文章

数据结构与算法之位运算: LeetCode 2166. 设计位集 (Ts版)

设计位集 https://leetcode.cn/problems/design-bitset/description/ 描述 位集 Bitset 是一种能以紧凑形式存储位的数据结构。请你实现 Bitset 类。 Bitset(int size) 用 size 个位初始化 Bitset &#xff0c;所有位都是 0void fix(int idx) 将下标为 idx 的位上的值更新为…

pytorch使用SVM实现文本分类

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 完整代码&#xff1a; import torch import torch.nn as nn import torch.optim as optim import jieba import numpy as np from sklearn.model_selection import train_test_split from sklearn.feature_extract…

Excel分区间统计分析(等步长、不等步长、多维度)

在数据分析过程中&#xff0c;可能会需要统计不同数据区间的人数、某个数据区间的平均值或者进行分组区间统计&#xff0c;本文从excel函数到数据透视表的方法&#xff0c;从简单需求到复杂需求&#xff0c;采用不同的方法进行讲解&#xff0c;尤其是通过数据透视表的强大功能大…

C++语法·食二

目录 目录 迭代器 1.意义 2.分类 &#xff08;1&#xff09;单向迭代器 &#xff08;2&#xff09;双向迭代器 &#xff08;3&#xff09;随机迭代器 list list的使用 1.构造 2.容量 3.访问和遍历&#xff08;list不支持[ ]下标访问&#xff09; 4.修改 5.操作 …

10.4 LangChain核心架构揭秘:模块化设计如何重塑大模型应用开发?

LangChain核心架构揭秘:模块化设计如何重塑大模型应用开发? 关键词: LangChain模块化设计、大模型开发框架、LangChain核心概念、AI应用开发、LLM工程化 一、LangChain的模块化设计哲学:从“手工作坊”到“工业化生产” 传统开发痛点: 代码重复:每个项目从零开始编写胶…

.NET Core缓存

目录 缓存的概念 客户端响应缓存 cache-control 服务器端响应缓存 内存缓存&#xff08;In-memory cache&#xff09; 用法 GetOrCreateAsync 缓存过期时间策略 缓存的过期时间 解决方法&#xff1a; 两种过期时间策略&#xff1a; 绝对过期时间 滑动过期时间 两…

Android createScaledBitmap与Canvas通过RectF drawBitmap生成马赛克/高斯模糊(毛玻璃)对比,Kotlin

Android createScaledBitmap与Canvas通过RectF drawBitmap生成马赛克/高斯模糊&#xff08;毛玻璃&#xff09;对比&#xff0c;Kotlin import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.RectF …

maven如何不把依赖的jar打包到同一个jar?

spring boot项目打jar包部署&#xff1a; 经过以下步骤&#xff0c; 最终会形成maven依赖的多个jar&#xff08;包括lib下添加的&#xff09;、 我们编写的程序代码打成一个jar&#xff0c;将程序jar与 依赖jar分开&#xff0c;便于管理&#xff1a; success&#xff1a; 最终…