ValueInstantiator#_createFromStringFallbacks doesn't trim when value is a carriage-return string

66 views
Skip to first unread message

G.M

unread,
Aug 15, 2017, 12:42:36 PM8/15/17
to jackson-user
We needs some help for this case :

we use :
jackson 2.9.0
jdk 1.8

XML to deserialize :
<?xml version="1.0" encoding="utf-8"?>
<RESPONSE>
<RPBODY>
<DATA>
</DATA>
</RPBODY>
</RESPONSE>



Main.java
public class JacksonTest {

    public static void main(String[] args) throws JsonParseException, IOException {

        ObjectMapper objectMapper = new XmlMapper();
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
        objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        
        
        JacksonTest test = new JacksonTest();
        InputStream inputStream = test.getClass().getResourceAsStream("emptyData2.xml");
        test.parse(objectMapper.getFactory(), inputStream, DataTestRoot.class, "UTF-8");
    }

    public <T> T parse(JsonFactory jfactory, InputStream in, Class<T> klass, String charset) throws JsonParseException, IOException {
        
        if (jfactory == null) {
            throw new IllegalArgumentException("this method must be used with an instance initialized with a ObjectMapper");
        }

        T result = null;

        JsonParser p = jfactory.createParser(in);
        JsonToken jToken = null;
        while ((jToken = p.nextToken()) != null) {
            if (jToken == JsonToken.FIELD_NAME) {
                String fieldName = p.getCurrentName();
                if ("RPBODY".equals(fieldName)) {
                    p.nextToken();
                    try {
                        result = p.readValueAs(klass);
                    } catch (Throwable e) {
                        throw new IOException(e);
                    }
                } else if ("RPHEADER".equals(fieldName)) {
                    p.nextToken();
                    JsonNode rpHeader = p.readValueAs(JsonNode.class);
                    String status = rpHeader.get("STATUSID").asText();
                    long statusId = 0;
                    if (NumberUtils.isNumber(status)) {
                        statusId = NumberUtils.toLong(status);
                    }
                    if (statusId < 0) {
                        throw new IOException(status);
                    }
                }
            }
        }
        return result;
    }
        
    private static class DataTestRoot {
        @JacksonXmlProperty(localName = "DATA")
        public DataListTest data;
    }

    private static class DataListTest {
        @JacksonXmlProperty(localName = "ITEM")
        @JacksonXmlElementWrapper(localName = "ITEM", useWrapping = false)
        public List<Data> datas;
    }

}


Error :
Exception in thread "main" java.io.IOException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `jackson.JacksonTest$DataListTest` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('
')
at [Source: (BufferedInputStream); line: 5, column: 10] (through reference chain: ch.hcuge.deja.jackson.JacksonTest$DataTestRoot["DATA"])



the error seems to be in this method : com.fasterxml.jackson.databind.deser.ValueInstantiator#_createFromStringFallbacks
the String value parsed is "\n\t\t" (cf PJ)

but no trim is done in the test if (value.length() == 0)


What's wrong ? our system to parse an XML request ? we forget something ?

thanks for your help.






Reply all
Reply to author
Forward
0 new messages