JAXB unmarshalling an invalid integer

In our product we use apache CXF. Due to performance limitations, the schema check is set to false. Now, for an integer element, if I provide an invalid value, JAXB disables it from something else. For instance,

9999999999 is converted to 1410065407.

988888888888 converted to 1046410808.

My question is what follows logic (formula) here?

How to deal with this (assuming that the check will be disabled)? I want this value to be rejected.

+4
source share
1 answer

Note. I am EclipseLink JAXB (MOXy) and a member of the JAXB Expert Group (JSR-222) .

SHORT ANSWER

This is apparently a bug in the JAXB reference implementation. I would recommend introducing an error for it in the following place:

The same usage example works correctly in EclipseLink JAXB (MOXy).


LONG RESPONSE

The following is a complete example demonstrating the problem:

Root

The following is a domain class with int and integer fields.

 package forum13216624; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Root { int int1; int int2; Integer integer1; Integer integer2; } 

Input.xml

Below is an XML document with values ​​from your question.

 <?xml version="1.0" encoding="UTF-8"?> <root> <int1>9999999999</int1> <int2>988888888888</int2> <integer1>9999999999</integer1> <integer2>988888888888</integer2> </root> 

Demo

In the demo code below, I pointed out ValidationEventHandler to Unmarshaller . This should catch the ValidationEvent for any invalid values ​​detected during the unmarhsal operation.

 package forum13216624; import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); unmarshaller.setEventHandler(new ValidationEventHandler() { @Override public boolean handleEvent(ValidationEvent event) { System.out.println(event.getMessage()); return true; }} ); File xml = new File("src/forum13216624/input.xml"); Root root = (Root) unmarshaller.unmarshal(xml); System.out.println(root.int1); System.out.println(root.int2); System.out.println(root.integer1); System.out.println(root.integer2); } } 

Conclusion - JAXB Link Implementation

This result is consistent with the behavior you see.

 1410065407 1046410808 1410065407 1046410808 

Exit - EclipseLink JAXB (MOXy)

If you specify MOXy as your JAXB provider (see http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html ), this use case works as expected. You will get a ValidationEvent for each invalid value, and if ValidationEvent processed, the field / property will not be set to an invalid value.

 Exception Description: The object [9999999999], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[int1-->int1/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer]. Internal Exception: java.lang.NumberFormatException: For input string: "9999999999" Exception Description: The object [988888888888], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[int2-->int2/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer]. Internal Exception: java.lang.NumberFormatException: For input string: "988888888888" Exception Description: The object [9999999999], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[integer1-->integer1/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer]. Internal Exception: java.lang.NumberFormatException: For input string: "9999999999" Exception Description: The object [988888888888], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[integer2-->integer2/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer]. Internal Exception: java.lang.NumberFormatException: For input string: "988888888888" 0 0 null null 

POTENTIAL PROGRAM

If your fields / properties are of type integer and you can switch from the JAXB implementation reference, you can create an XmlAdapter to make your own integer to / from String conversions.

Integeradapter

The following is an XmlAdapter example that demonstrates how you could provide your own transformation logic.

 package forum13216624; import javax.xml.bind.annotation.adapters.XmlAdapter; public class IntegerAdapter extends XmlAdapter<String, Integer>{ @Override public Integer unmarshal(String string) throws Exception { return Integer.valueOf(string); } @Override public String marshal(Integer integer) throws Exception { return String.valueOf(integer); } } 

package info

Using the @XmlJavaTypeAdapter annotation at the package level means that the XmlAdapter will apply to all fields / properties of type integer for classes in this package.

 @XmlJavaTypeAdapter(value=IntegerAdapter.class, type=Integer.class) package forum13216624; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

Output

Below is the updated output when using RI. The int values ​​are still untrue, but the integer values ​​are null and ValidationEvents , as expected.

 java.lang.NumberFormatException: For input string: "9999999999" java.lang.NumberFormatException: For input string: "988888888888" 1410065407 1046410808 null null 

Additional Information

+7
source

Source: https://habr.com/ru/post/1443909/


All Articles