You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Micronaut Serde布尔反序列化行为存疑,是否需提交Issue?

Micronaut Serde布尔值反序列化行为疑问

在使用Micronaut Serde进行JSON反序列化时,布尔值存在如下处理逻辑:

  • 字符串类型:仅当值为小写"true"时返回true,其余所有字符串(包括""、"True"、"TRUE"、"enabled"等)均返回false
  • 数值类型:仅当值为0时返回false,其余所有非0数值(如99)均返回true
    这种行为可能导致API生成错误的条目。

根据JSON规范,布尔值应为无引号的true或false,严格来说不应接受字符串形式的布尔值。对比JavaScript的处理逻辑:在浏览器控制台执行JSON.parse("True")或JSON.parse("TRUE")时,会直接抛出SyntaxError: Unexpected token 'T', "True" is not valid JSON。

实际行为测试代码

import io.micronaut.serde.ObjectMapper
import io.micronaut.serde.annotation.Serdeable
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

@MicronautTest
class CurrentBehaviorOfBooleanSerdeSpec extends Specification {

    @Inject ObjectMapper objectMapper

    // All asserts in this method are passing
    void "test current behavior"() {
        expect:
        objectMapper.readValue('{"enabled": true}', Test).enabled == true
        objectMapper.readValue('{"enabled": "true"}', Test).enabled == true
        objectMapper.readValue('{"enabled": false}', Test).enabled == false
        objectMapper.readValue('{"enabled": "false"}', Test).enabled == false

        // If there is at least one uppercase letter, returns false, even if the value is true
        // It is acceptable because true or false as a string is not in the Json specification
        objectMapper.readValue('{"enabled": "True"}', Test).enabled == false
        objectMapper.readValue('{"enabled": "TRUE"}', Test).enabled == false

        // Any numeric value other than 0 returns true
        objectMapper.readValue('{"enabled": 0}', Test).enabled == false
        objectMapper.readValue('{"enabled": 1}', Test).enabled == true
        objectMapper.readValue('{"enabled": 99}', Test).enabled == true

        // Any string value other than true returns false
        objectMapper.readValue('{"enabled": ""}', Test).enabled == false
        objectMapper.readValue('{"enabled": " " }', Test).enabled == false
        objectMapper.readValue('{"enabled": "enabled"}', Test).enabled == false
    }

    @Serdeable
    static class Test {
        Boolean enabled
    }

}

预期行为

所有不符合规范的无效值在反序列化时应抛出InvalidPropertyFormatException,而非返回默认的true或false,仅接受以下合法值:

  • 无引号的JSON布尔值true/false
  • 字符串形式的"true"/"false"
  • 数值0(转为false)和1(转为true)

预期行为测试代码

import io.micronaut.serde.ObjectMapper
import io.micronaut.serde.annotation.Serdeable
import io.micronaut.serde.exceptions.InvalidPropertyFormatException
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

@MicronautTest
class ExpectedBehaviorOfBooleanSerdeSpec extends Specification {

    @Inject ObjectMapper objectMapper

    // All asserts in this method are passing
    void "test expected behavior with valid values"() {
        expect:
        objectMapper.readValue('{"enabled": true}', Test).enabled == true
        objectMapper.readValue('{"enabled": "true"}', Test).enabled == true
        objectMapper.readValue('{"enabled": false}', Test).enabled == false
        objectMapper.readValue('{"enabled": "false"}', Test).enabled == false

        // Could only accept numeric values 0 and 1
        objectMapper.readValue('{"enabled": 0}', Test).enabled == false
        objectMapper.readValue('{"enabled": 1}', Test).enabled == true
    }

    // All asserts in this method are failing
    void "test expected behavior with invalid values"() {
        when:
        // Any string value other than true or false could throw an exception, instead of returning false
        objectMapper.readValue('{"enabled": "True"}', Test).enabled
        objectMapper.readValue('{"enabled": "TRUE"}', Test).enabled
        objectMapper.readValue('{"enabled": "False"}', Test).enabled
        objectMapper.readValue('{"enabled": "FALSE"}', Test).enabled
        objectMapper.readValue('{"enabled": ""}', Test).enabled
        objectMapper.readValue('{"enabled": " " }', Test).enabled
        objectMapper.readValue('{"enabled": "enabled"}', Test).enabled

        // Any numeric value other than 0 and 1 could throw an exception, instead of returning true
        objectMapper.readValue('{"enabled": 99}', Test).enabled

        then:
        thrown(InvalidPropertyFormatException)
    }

    @Serdeable
    static class Test {
        Boolean enabled
    }

}

请问该当前行为是否为Micronaut Serde的预期设计?是否需要提交Issue,将其修正为符合JSON规范的异常抛出行为?

内容的提问来源于stack exchange,提问作者Eduardo Guimaraes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:00:23