2012-11-04 6 views
4

우리 제품에서는 Apache CXF를 사용합니다. 성능 제한으로 인해 스키마 유효성 검사가 false로 설정되었습니다. 이제 잘못된 값을 제공 할 경우 정수 요소의 경우 JAXB에서 다른 값으로 언 마샬링합니다. 예를 들어, 잘못된 정수의 JAXB 비 정렬

9999999999

는 1410065407.

988888888888로 변환되어 1046410808.

내 질문은 여기에 다음되고있는 로직 (공식)은 무엇인가로 변환?

처리 방법 (유효성 검사가 해제 된 것으로 간주)? 나는 그런 가치가 거부되기를 바란다.

답변

7

참고 : 저는 EclipseLink JAXB (MOXy)이며 JAXB (JSR-222) 전문가 그룹의 구성원입니다.

짧은 대답

이것은 JAXB 참조 구현 버그 나타난다. 나는 다음 위치에서의 버그를 입력 할 것을 권장합니다 :

이 같은 사용 사례는 EclipseLink JAXB (목시)에 올바르게 작동합니다.

루트 아래

intinteger 필드가있는 도메인 클래스는 다음과 같습니다


LONG 답변 아래

문제를 보여주는 완벽한 예입니다.

package forum13216624; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    int int1; 
    int int2; 
    Integer integer1; 
    Integer integer2; 

} 

input.xml 아래

는 질문의 값으로 XML 문서입니다.

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

나는 UnmarshallerValidationEventHandler을 지정한 아래의 데모 코드에서 데모

. unmarhsal 작업 중에 잘못된 값이 발견되면이 값은 ValidationEvent입니다.

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); 
    } 

} 

출력 - JAXB 참조 구현

이 출력은 당신이보고있는 행동을 일치합니다.

1410065407 
1046410808 
1410065407 
1046410808 

출력 - 당신이 당신의 JAXB 공급자로 MOXY을 지정하는 경우는 EclipseLink JAXB (목시는)

(참조 : http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html를) 예상대로이 사용 사례 작동합니다. 각 잘못된 값에 대해 ValidationEvent이 표시되고 ValidationEvent이 처리되면 필드/속성이 잘못된 값으로 설정되지 않습니다.

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 

잠재적 해결 과정

당신의 필드/속성 유형 Integer의 그리고 당신은 당신이 당신의 자신의 Integer을 할 /에서 XmlAdapter을 만들 수있는 JAXB 참조 구현으로 전환 할 수있는 경우 String 전환.

IntegerAdapter 아래

는 자신의 변환 로직을 제공 할 수있는 방법을 보여주는 XmlAdapter의 예입니다. 패키지 수준에서 @XmlJavaTypeAdapter 주석을 사용

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); 
    } 

} 

패키지 정보

XmlAdapter이 패키지의 클래스에 대한 유형 Integer의 모든 필드/속성에 적용된다는 것을 의미합니다. 국제 로타리가 사용되는 경우

@XmlJavaTypeAdapter(value=IntegerAdapter.class, type=Integer.class) 
package forum13216624; 

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

출력 아래

업데이트 된 출력됩니다. int 값은 여전히 ​​잘못된 있지만 Integer 값은 nullValidationEvents 예상대로 생성되지 않습니다. 이 문제를 명확히하기위한 추가 정보

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

+1

감사합니다 많이! 우리 제품의 경우 JAXB 참조 구현을 전환 할 수 없지만 string 유형의 정수 요소를 선언하는 것이 잠재적 인 솔루션 일 수 있습니다. –

+1

@ArnabBiswas - 당신은'string' 타입의 원소를 만들 필요가 없습니다.대신'XmlAdapter'를 통해 자신 만의'String' /'Integer' 변환 논리를 제공 할 것을 제안했습니다. 나는 완전한 답을 통해 나의 대답을 업데이트했다. –

+0

다시 한번 감사드립니다. 미안하지만 나는 내 의견에 대해 충분히 명확하지 않았다. 그러나 이것은 내가 또한 고려하고있는 것입니다. –

관련 문제