控制器已准备好接收参数。假设调用URL http://localhost:8080/api/v1/customers?status=ACTIVATED 。Spring 将尝试将来自 http 参数 status 的值转换为有效的状态枚举。
在这种情况下,两个值都匹配:http 参数和状态枚举值。因此,API 返回的响应是激活客户的列表
"id": 3,
"name": "name 3 surname 3",
"email": "[email protected]",
"dateOfBirth": "09-03-1986",
"status": "activated"
"id": 6,
"name": "name 6 surname 6",
"email": "[email protected]",
"dateOfBirth": "18-06-1992",
"status": "activated"
"id": 9,
"name": "name 9 surname 9",
"email": "[email protected]",
"dateOfBirth": "27-09-1998",
"status": "activated"
如果参数与任何枚举值不匹配或者无效,会发生什么情况?那么,如果它们不匹配或者无效,Spring 将抛出 ConversionFailedException。
让我们通过以下调用来演示它。首先,URL 是http://localhost:8080/api/v1/customers?status=activated
反应并不是我们所期望的
"status": 400,
"message": "There was a error converting the value activated
to type Status. ",
"timestamp": "2023-06-24T19:33:26.6583667"
第二个 URL 为http://localhost:8080/api/v1/customers?status=DELETED
在这种情况下,可以接受来自服务器的响应,因为状态不存在。
"status": 400,
"message": "There was a error converting the value DELETED to
type Status.",
"timestamp": "2023-06-24T19:08:49.6261182"
出现此行为的原因是 Spring 使用 StringToEnumConverterFactory 类。Convert 方法委托给 Enum valueOf 方法,如果未找到枚举常量,该方法将抛出 IllegalArgumentException。
@Nullable
public T convert(String source) {
return source.isEmpty() ? null : Enum.valueOf(this.enumType,
source.trim());
我们希望改变这种行为并允许使用小写字母进行过滤。与 JPA 部分中所做的类似,我们必须编写一个自定义转换器。
添加自定义转换器非常简单。只需实现 Converter 接口并重写其转换方法即可。Convert 方法采用两种泛型类型:源类型和结果类型。
@Component
public class StringIgnoreCaseToEnumConverter implements
Converter<String, Customer.Status> {
@Override
public Customer.Status convert(String source) {
return Customer.Status.valueOf(source.toUpperCase());
上面的方法接受传入的 String。在通过 Enum.valueOf 返回枚举常量之前,它会被转换为大写。因此,字符串“activated”将变为“ACTIVATED”。因此,它将返回枚举常量 Status.ACTIVATED。
现在让我们重新测试之前的 URL 并检查结果。调用 URL http://localhost:8080/api/v1/customers?status=activated会生成我们想要的输出
"id": 3,
"name": "name 3 surname 3",
"email": "[email protected]",
"dateOfBirth": "09-03-1986",
"status": "activated"
本文详细讲解了如何在持久层和Web层使用枚举。这里总结一下它的要点。
对于持久层,JPA 提供了开箱即用的 ORDINAL 和 STRING 选项。如果这不能满足应用程序的要求,自定义转换器可以完全控制映射的完成方式。
对于 Web 层,Spring MVC 为请求参数和路径变量提供了枚举支持。如果存在精确匹配,它会自动将 String 转换为枚举。可以通过实现转换器来更改此行为。
更多精彩内容欢迎B站搜索千锋教育
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
[email protected]