【问题标题】:HttpMessageNotReadableException instead of BeanPropertyBindingResultHttpMessageNotReadableException 而不是 BeanPropertyBindingResult
【发布时间】:2018-05-22 09:47:45
【问题描述】:

我有一个带有 Double 字段的表单。当我添加一个不是 Double ('foo') 的值时,它应该给我一个 BeanPropertyBindingResult 并带有该字段的错误。但相反,我得到了HttpMessageNotReadableException

奇怪的是,从我的 JUnit 测试中,我确实得到了 BeanPropertyBindingResult

这是我的代码(如果需要更多我会提供它,我会尝试专注于我认为需要的内容)。

我有一个 Angular 前端:

首先是我从 Angular 得到的错误:

2018-05-22 11:28:59.143 WARN 1262 --- [XNIO-8 task-4] o.z.p.spring.web.advice.AdviceTrait:错误请求:JSON 解析 错误:无法从 String 反序列化 java.lang.Double 类型的值 “dddddddd”:不是有效的 Double 值;嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidFormatException:不能 从字符串“dddddddd”反序列化 java.lang.Double 类型的值:不是 [来源: java.io.PushbackInputStream@36d5105f;行:1,列:1294](通过 参考链:nl.tibi.sbys.service.dto.ProjectDTO["travelRate"]) 2018-05-22 11:28:59.146 警告 1262 --- [XNIO-8 任务 4] .m.m.a.ExceptionHandlerExceptionResolver : 已解决的异常导致 通过 Handler 执行: org.springframework.http.converter.HttpMessageNotReadableException: JSON 解析错误:无法反序列化 java.lang.Double 类型的值 来自字符串“dddddddd”:不是有效的 Double 值;嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidFormatException:不能 从字符串“dddddddd”反序列化 java.lang.Double 类型的值:不是 [Source: java.io.PushbackInputStream@36d5105f; 处的有效 Double 值; 行:1,列:1294](通过参考链: nl.tibi.sbys.service.dto.ProjectDTO["travelRate"])

当我从我的 junit 测试中运行代码时,我得到了这个,这是我认为最好的:

2018-05-22 11:32:00.516 警告 18426 --- [主要] o.z.p.spring.web.advice.AdviceTrait:错误请求: org.springframework.validation.BeanPropertyBindingResult: 1 个错误 字段“travelRate”上的对象“projectDTO”中的字段错误:被拒绝 值 [3,5];代码 [typeMismatch.projectDTO.travelRate,typeMismatch.travelRate,typeMismatch.java.lang.Double,typeMismatch]; 论据 [org.springframework.context.support.DefaultMessageSourceResolvable: 代码 [projectDTO.travelRate,travelRate];论据 [];默认 消息 [travelRate]];默认消息 [无法转换属性 “java.lang.String”类型的值到所需类型“java.lang.Double” 对于属性“travelRate”;嵌套异常是 java.lang.NumberFormatException:对于输入字符串:“3,5”]

我的角度代码是这样发送的:

update( project: Project ): Observable<EntityResponseType> {
    const copy = this.convert( project );
    return this.http.put<Project>( this.resourceUrl, copy, { observe: 'response' } )
        .map(( res: EntityResponseType ) => this.convertResponse( res ) );
}

我的 junit 测试是这样的:

restMockMvc.perform(post(url()).param("travelRate", "3,5").param("name", "name")).andExpect(status().isUnprocessableEntity());

我的方法(由于十进制值错误而没有达到):

   @PostMapping()
   @Timed
   public ResponseEntity<ProjectDTO> createProject(@Valid ProjectDTO projectDTO) throws URISyntaxException {
    log.debug("REST request to save Project : {}", projectDTO);
    ....
    } 

如何从 Angular 获得与 JUnit 测试相同的结果?即如何获得 BeanPropertyBindingResult?

我的解决方法是添加一个 ExceptionHandler 并解析字符串消息并自己创建 BeanPropertyBindingResult

【问题讨论】:

    标签: java angular spring-boot


    【解决方案1】:

    消息很明确:无法将字符串参数转换为您的 Double 属性。

    请求正文读取器发生在您的 bean 验证逻辑之前,因此不会发生 BeanPropertyBindingResult 异常。

    如果您想验证输入是否正确,则必须在 DTO 中将其声明为 String 并使用自定义验证器对其进行验证:

    public class ProjectDTO {
        @Double
        String travelRate;
    }
    

    @Double 是您的自定义验证器。这很容易实现。

    【讨论】:

    • 因为你还没有为 MockMvc 设置 json 转换器
    • 有意思,你能解释一下吗?
    • 添加一个杰克逊转换器作为您的消息转换器,您就会知道原因
    • 你有例子吗?所以你说的是在错误输入后不能让spring boot返回绑定结果而不是HttpMessageNotReadableException?
    猜你喜欢
    • 1970-01-01
    • 2013-11-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    相关资源
    最近更新 更多