相关文章推荐

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account No _valueDeserializer assigned when @JacksonXmlProperty.localName and field name have the same name. No _valueDeserializer assigned when @JacksonXmlProperty.localName and field name have the same name. billoneil opened this issue Dec 5, 2017 · 3 comments

I'm not sure exactly how this was tracked down but our XML serializer started breaking between version 2.8.7 and 2.8.8 with a

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: No _valueDeserializer assigned
 at [Source: (StringReader); line: 4, column: 32] (through reference chain: JacksonTest$RootObject["Event"]->JacksonTest$Event["EventId"])

It appears the actual change was in jackson-databind-2.8.7-2.8.8 since there are no notable changes in jackson-dataformat-xml-2.8.7-2.8.8 but seems related to the XML annotations. Here is the best example I could come up with to reproduce.

public class JacksonTest {
	private static final String XML =
		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
		"<dataroot xmlns:od=\"urn:schemas-microsoft-com:officedata\" generated=\"2017-06-07T10:11:20\">\n" + 
		"    <Event>\n" + 
		"        <EventId>34906566143035</EventId>\n" + 
		"    </Event>\n" + 
		"</dataroot>";
	static class Event {
	       @JacksonXmlProperty(localName = "EventId")
		private String EventId;
		public String getEventId() {
			return EventId;
		public void setEventId(String eventId) {
			this.EventId = eventId;
	@JacksonXmlRootElement(localName = "dataroot")
	static class RootObject {
	    @JacksonXmlProperty(localName = "Event")
	    Event event;
	    @JacksonXmlProperty(localName = "generated")
	    String generated;
	public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
		JacksonXmlModule module = new JacksonXmlModule();
        XmlFactory factory = new XmlFactory();
        XMLOutputFactory outputFactory = new WstxOutputFactory();
        //fix default namespace issue
        outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", true);
        //Woodstox is the recommended Stax XML API implementation by fasterXml/Jackson
        factory.setXMLOutputFactory(outputFactory);
        factory.setXMLInputFactory(new WstxInputFactory());
	XmlMapper xm = new XmlMapper(factory, module);
	// serialization features
        xm.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        xm.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
	// deserialization features
        xm.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        //this is for deserialization only and means we don't need to camelCase  xml property names
        xm.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
        // enable JAXB as primary introspector
        AnnotationIntrospector jaxbIntrospector = new JaxbAnnotationIntrospector(xm.getTypeFactory());
        AnnotationIntrospector jacksonXmlIntrospector = new JacksonXmlAnnotationIntrospector();
        AnnotationIntrospector pair = new AnnotationIntrospectorPair(jaxbIntrospector, jacksonXmlIntrospector);
        xm.setAnnotationIntrospector(pair);
        RootObject obj = xm.readValue(XML, new TypeReference<RootObject>() {});

However, commenting out the XML annotation will work.

	static class Event {
	        //@JacksonXmlProperty(localName = "EventId")
		private String EventId;
		public String getEventId() {
			return EventId;
		public void setEventId(String eventId) {
			this.EventId = eventId;

Removing the setter and keeping the annotation will also work.

	static class Event {
	        @JacksonXmlProperty(localName = "EventId")
		private String EventId;
		public String getEventId() {
			return EventId;

Fixing the case of the field will also work.

	static class Event {
	       @JacksonXmlProperty(localName = "EventId")
		private String eventId;
		public String getEventId() {
			return eventId;
		public void setEventId(String eventId) {
			this.eventId = eventId;

And finally commenting out MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES seems to work.

//xm.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);

This issue only appears to happen when the field name and annotation names match AND there is a setter. From version 2.8.8+ this throws an exception. I can fix this on our end with any of the mentioned fixes just thought I would mention it.

Hmmh. That is unfortunate. I assume further 2.8 versions have same problem? (2.8.9 - 2.8.11)

Aside from this, would it be possible to try out 2.9? (I'll do that when I get a chance)

 
推荐文章