Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jettison / String returned as integer when marshalling

There's a 'feature' of Jettison, outlined in a JIRA entry way back in 2008, which refers to the following problem:

Let's say I ask the value of "element" to be "00102"; the output may look like follows:

{ "Response": 
    { "element": "00102" }
}

but now I set "element" to be "102":

{ "Response":
    { "element": 102 }
}

I understand Jettison is trying to be helpful... but seriously, I don't need it to decide this sort of thing on my behalf. No-thank-you.

Current work-around

For the moment, I've used a solution outlined by the user here, who adds the following to the bean config:

<bean id="simpleConverter" class="org.codehaus.jettison.mapped.SimpleConverter"/>

<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider">
    <property name="typeConverter" ref="simpleConverter"/>
</bean>

This partly solves the issue, in so much as to say that all elements are forced to be strings even if they're clearly integers. Now, at least, I know exactly what structure my data is going to hold, and the element type is not going to change from a string to an integer and back again without my knowledge.

Problem

However, I'm unable to output another element now as an integer, even if I'd now wish to do so. It seems as if I can only force the output of elements to string across the entire service, rather than on a per-element basis.

Aside from the 'using Jackson' suggestions (which I can't follow, as the framework explicitly uses Jettison) are there any other ways I could specify which elements I'd like to force as a string in my JSON output?

like image 654
Ron Avatar asked Nov 11 '22 11:11

Ron


1 Answers

The SimpleConverter also convert double and booleans to string, and that is a problem.

You can override the default converter only for your 'special' numbers. Unfortunately there is no way to see the context of original field to convert

public class MyConverter extends org.codehaus.jettison.mapped.DefaultConverter {

    public Object convertToJSONPrimitive(String text) {
        Object primitive = super.convertToJSONPrimitive(text);

        //Apply your conversion rule;
        if (primitive != null 
                && primitive instanceof Long 
                && text.startsWith("0"))
            return text;
        else 
            return primitive;
    }
}

You can see the full code of DefaultConverter here

And the CXF configuration

<bean id="myConverter" class="MyConverter"/>

<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider">
    <property name="typeConverter" ref="myConverter"/>
</bean>
like image 82
pedrofb Avatar answered Nov 13 '22 08:11

pedrofb