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
相关产品推荐
相关产品推荐

