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

带枚举的Spring的@RequestParam

锺离良哲
2023-03-14

我有这个枚举:

public enum SortEnum {
    asc, desc;
}

我想用作rest请求的参数:

@RequestMapping(value = "/events", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<Event> getEvents(@RequestParam(name = "sort", required = false) SortEnum sort) {

当我发送这些请求时效果很好

/events 
/events?sort=asc
/events?sort=desc

但当我发送:

/events?sort=somethingElse

我收到了500条回复,控制台上有这样一条消息:

2016-09-29 17:20:51.600 DEBUG 5104 --- [  XNIO-2 task-6] com.myApp.aop.logging.LoggingAspect   : Enter: com.myApp.web.rest.errors.ExceptionTranslator.processRuntimeException() with argument[s] = [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type [java.lang.String] to required type [com.myApp.common.SortEnum]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam com.myApp.common.SortEnum] for value 'somethingElse'; nested exception is java.lang.IllegalArgumentException: No enum constant com.myApp.common.SortEnum.somethingElse]
2016-09-29 17:20:51.600 DEBUG 5104 --- [  XNIO-2 task-6] com.myApp.aop.logging.LoggingAspect   : Exit: com.myApp.web.rest.errors.ExceptionTranslator.processRuntimeException() with result = <500 Internal Server Error,com.myApp.web.rest.errors.ErrorVM@1e3343c9,{}>
2016-09-29 17:20:51.601  WARN 5104 --- [  XNIO-2 task-6] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type [java.lang.String] to required type [com.myApp.common.SortEnum]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam com.myApp.common.SortEnum] for value 'somethingElse'; nested exception is java.lang.IllegalArgumentException: No enum constant com.myApp.common.SortEnum.somethingElse

有没有办法防止spring抛出这些异常并将枚举设置为null?

编辑

斯特雷洛克公认的答案有效。然而,我决定处理MethodArgumentTypeMismatchException。

@ControllerAdvice
public class ExceptionTranslator {

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public ResponseEntity<Object> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        Class<?> type = e.getRequiredType();
        String message;
        if(type.isEnum()){
            message = "The parameter " + e.getName() + " must have a value among : " + StringUtils.join(type.getEnumConstants(), ", ");
        }
        else{
            message = "The parameter " + e.getName() + " must be of type " + type.getTypeName();
        }
        return buildResponse(HttpStatus.UNPROCESSABLE_ENTITY, message);
    }

共有3个答案

公孙鸿才
2023-03-14

您需要执行以下操作

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    dataBinder.registerCustomEditor(YourEnum.class, new YourEnumConverter());
}

请参阅以下内容:https://machiel.me/post/java-enums-as-request-parameters-in-spring-4/

羊舌高爽
2023-03-14

您可以创建一个自定义转换器,当提供无效值时,该转换器将返回null,而不是异常。

像这样的东西:

@Configuration
public class MyConfig extends WebMvcConfigurationSupport {
   @Override
   public FormattingConversionService mvcConversionService() {
       FormattingConversionService f = super.mvcConversionService();
       f.addConverter(new MyCustomEnumConverter());
       return f;
   }
}

一个简单的转换器可能如下所示:

public class MyCustomEnumConverter implements Converter<String, SortEnum> {
    @Override
    public SortEnum convert(String source) {
       try {
          return SortEnum.valueOf(source);
       } catch(Exception e) {
          return null; // or SortEnum.asc
       }
    }
}
咸玄天
2023-03-14

如果您使用的是Spring Boot,这就是您不应该使用WebMvcConfigurationSupport的原因。

最佳实践是,您应该实现interfaceorg。springframework。果心转换转换器。转换器,并带有注释组件。然后Spring Boot将自动加载所有转换器的bean。Spring启动代码

@Component
public class GenderEnumConverter implements Converter<String, GenderEnum> {
    @Override
    public GenderEnum convert(String value) {
        return GenderEnum.of(Integer.valueOf(value));
    }
}

演示工程

 类似资料:
  • 问题内容: 这不是卡住我的问题,而是我正在寻找一种编写代码的整洁方法。 本质上,我正在编写一个事件驱动的应用程序。用户触发一个事件,该事件被发送到适当的对象,然后这些对象处理事件。现在,我正在编写偶数处理程序方法,并且希望使用switch语句确定如何处理事件。现在,在我研究通用结构时,事件类非常简单: 然后,在另一堂课中,我会看到类似以下内容的内容: 我会 喜欢 做的就是这样的事情(尽管我当然会坚

  • 问题内容: 我有一个使用枚举的数据库表。这已经可以与hibernate(使用XML)一起使用了,我正尝试将其转换为注释,因为这是仍在使用xml表示法的最后一部分。 列定义: 以下作品: 这不起作用: 注释样式在启动时导致以下异常:org.hibernate.HibernateException:UserDTO中列状态的列类型错误。找到:枚举,预期:varchar(255) 我有什么办法强迫它像使用

  • 我有基于spring boot 1.2.3的应用程序。其中一个模型非常具体:包含枚举列表。当我试图调用spring jpa查询时,sql的一部分消失[C.categories IN(:category)被替换为(.IN(?))]。我想这可能是图书馆的一些问题,或者我做错了什么。 你知道怎么解决这个问题吗? 目标模型包含: 枚举模型:

  • 问题内容: 我们有一个带有枚举字段-的实体,我们想使用JPA注释-为它设置默认值。 但是,当我们将实体保存到数据库时,此字段的值为和。对于布尔字段- 正确的默认值()已保存。 如果改为使用:,则会在保存时得到以下异常: 我们做错了什么?为什么它仅适用于布尔值? 问题答案: 当某些SQL代码在未为emailCommunicationStatus列指定任何值的情况下插入一行时,您所做的工作很有用。在这

  • 问题内容: Enumeration <有区别吗?扩展ZipEntry>和Enumeration ?如果是这样,有什么区别? 问题答案: 拥有其中一种后,您在做什么上没有实际差异,因为type参数仅在“输出”位置使用。另一方面,在您可以 用作 其中一个的方面有很大的不同。 假设您有一个-您无法将其传递给作为其参数之一的方法。您 可以 将其传递给采用方法。 当您有一个在输入和输出位置都使用type参数

  • 问题内容: 枚举具有获取枚举常量的方法,并且在具有 我发现的名称的类中存在的相同类型的方法都给出相同的输出。那还有什么其他区别。如果没有区别,那么为什么要添加JSL ? 问题答案: 包括该方法的原因是它可以与任何方法一起使用。相比之下, 用于特定方法的方法仅适用于该特定方法…,因为类不能被多态使用。 显然,该方法仅在您实现 需要 针对多种类型使用的代码的情况下才真正有用……而泛型则不会削减它。