调用cxf-rest服务时float被强转为int问题

调用cxf-rest服务时float被强转为int问题

最近使用cxf-rest开发一个rest接口(由于是老系统,所以使用技术比较旧),在对接口进行测试的时候,有如下用例:

Json字段类型为float,Java Object字段类型为Integer,预期返回 NumberFormatException 错误。

实际执行过程中发现并未抛错,而是将float强转为int。

经查服务端使用的是codehaus.jackson进行的转换,经过代码追踪发现在将Json转换为Java Object时,如果Json字段值为float,会将其强转为int。

具体代码如下:
org.codehaus.jackson.map.deser.std.StdDeserializer#_parseInteger

protected final Integer _parseInteger(JsonParser jp, DeserializationContext ctxt)
        throws IOException, JsonProcessingException
    {
        JsonToken t = jp.getCurrentToken();
        if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
            return Integer.valueOf(jp.getIntValue());
        }
        if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
            String text = jp.getText().trim();
            try {
                int len = text.length();
                if (len > 9) {
                    long l = Long.parseLong(text);
                    if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
                        throw ctxt.weirdStringException(_valueClass,
                            "Overflow: numeric value ("+text+") out of range of Integer ("+Integer.MIN_VALUE+" - "+Integer.MAX_VALUE+")");
                    }
                    return Integer.valueOf((int) l);
                }
                if (len == 0) {
                    return (Integer) getEmptyValue();
                }
                return Integer.valueOf(NumberInput.parseInt(text));
            } catch (IllegalArgumentException iae) {
                throw ctxt.weirdStringException(_valueClass, "not a valid Integer value");
            }
        }
        if (t == JsonToken.VALUE_NULL) {
            return (Integer) getNullValue();
        }
        // Otherwise, no can do:
        throw ctxt.mappingException(_valueClass, t);
    }

如果希望改变这种转换逻辑,可以重新注册下IntegerDeserializer。参考实现如下:

@Test
public void test() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new SimpleModule("integer", Version.unknownVersion()).addDeserializer(Integer.class, new JsonDeserializer<Integer>() {
        @Override
        public Integer deserialize(JsonParser jp, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
            JsonToken t = jp.getCurrentToken();
            if (t == JsonToken.VALUE_NUMBER_INT) { // coercing should work too
                return Integer.valueOf(jp.getIntValue());
            }
            if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
                String text = jp.getText().trim();
                try {
                    int len = text.length();
                    if (len > 9) {
                        long l = Long.parseLong(text);
                        if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
                            throw ctxt.weirdStringException(Integer.class,
                                    "Overflow: numeric value (" + text + ") out of range of Integer (" + Integer.MIN_VALUE + " - " + Integer.MAX_VALUE + ")");
                        }
                        return Integer.valueOf((int) l);
                    }
                    if (len == 0) {
                        return (Integer) getEmptyValue();
                    }
                    return Integer.valueOf(NumberInput.parseInt(text));
                } catch (IllegalArgumentException iae) {
                    throw ctxt.weirdStringException(Integer.class, "not a valid Integer value");
                }
            }
            if (t == JsonToken.VALUE_NULL) {
                return (Integer) getNullValue();
            }
            // Otherwise, no can do:
            throw ctxt.mappingException(Integer.class, t);
        }
    }));
}

或者在Json中使用设置字段值为String类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值