2012-01-18 3 views
2

JAXWS/JAXB 웹 서비스 환경에서 작업하고 있습니다. JAXWS는 즉시 JAXB를 사용하여 웹 서비스 페이로드를 마샬링/비 마샬링합니다.감사를 위해서만 base64Binary 데이터를 스크럽하도록 JAXB Marshaller에 지시 할 수 있습니까?

또한 모든 요청 및 응답 페이로드를 감사해야한다는 요구 사항이 있습니다.

필자는 감사를위한 페이로드의 간결하고 마샬링 된 표현을 원합니다 (관련없는 쪽 메모로 - java.util.concurrent.BlockingQueue 및 일부 소비자 스레드를 사용하여 감사 데이터에 감사 배치 데이터 소스).

일부 웹 서비스 응답 페이로드에는 바이너리 컨텐트 (mtom)가 포함되어 있지만 직렬화 된 base64가 너무 커서 감사를 마샬링하고 싶지 않습니다.

내 경우에는 모든 경우에 바이너리 컨텐츠를 스크럽하지만 웹 서비스 응답 페이로드를 마샬링하는 주요 목적을 위해 스크럽하지 않는 마샬 러 (auditng 전용)를 작성해야합니다. XSD를 Java xjc로 사용합니다. 두 컨텍스트/마샬 러에 대해 동일한 XSD/JAXB 네임 스페이스를 사용해야합니다.

자바 형식 변환기 :

<jxb:javaType name="" 
     parseMethod="com.xxx.xxx.ws.converter.XXXLongConverter.parseXXXLong" 
      printMethod="com.xxx.xxx.ws.converter.XXXLongConverter.printXXXLong" /> 

나는 마샬 용 어댑터 http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html#setAdapter%28java.lang.Class,%20A%29 등록을 취소해야하고 내가 잭스 - WS에 대한 그에 후크를 생각하지 않습니다 1. 때문에 작동하지 않습니다이다. 2. JAXB가 등록을 취소하기 위해 생성하려고하는 클래스 이름을 보장 할 수 없습니다.

내 XMLAdapter를 만들고 annox jaxb 플러그인 을 사용했지만 위와 같은 이유 때문에 작동하지 않았습니다.

업데이트 : 이제 바이너리 데이터를 제거하기 위해 마샬링하기 전에 페이로드 (감사 대상)를 수동으로 그리고 반사적으로 보았습니다.하지만 그 것이 가치가 있었는지에 대해서는 너무 많은 고통이되었습니다.

나는 또한 저지 JSON serialization supporting JAXB 을 사용하고 감사의 간결 것을 언급해야하지만 난 그 거리에 걸리거나 내 기본 문제에 추가 생각하지 않는다 :

내가 한 마샬의 데이터를 청소할 수있는 방법

/Unmarshaller에 JAXB 컨텍스트가 원래 다른 JAXB 컨텍스트는 아닌 둘 다?

업데이트 : 이렇게하는 방법을 알지 못했습니다. 현재로서는 프레임 워크가있는 그대로는 불가능합니다. 업데이트 : 사실이 아닙니다. AttachmentMarshaller를 확장하거나 (이것을 많이 사용하고 그것을 사용합니다) 또는 "Need-aware"XmlAdapter를 작성하면 감사 특정 marshaller에 대해 @Blaise가 아래 답변으로 작동합니다.

업데이트 : 내 유스 케이스를 완성하기 위해 한 걸음 더 나아갈 수 있다면 ... 위에서 언급 한 것처럼 감사의 간결을 위해 JSONJAXBContext의 Json Serialization을 저지 apis를 사용하여 구체적으로 JSONMarshaller하지만 인터페이스는 setAdapter 및 setAttachmentMarshaller를 정의하지 않습니다. JSONJAXBContext.createJSONMarshaller()의 출현은 이러한 방법을 정의하는 JSONMarshallerImpl 구현입니다. 나는 어쩔 수없이 내재적으로 애쓰는 마샬 러를 설정할 수 있도록 내재적으로 캐스팅 할 것이다.

답변

1
내가 한 마샬/Unmarshaller에 데이터를 청소할 수 있지만 어떻게

하지 다른 하지만 모두 그 기원 같은 JAXB 컨텍스트입니까?


당신은 AttachemntMarshaller 당신 자신의 구현을 설정하고 감사에 사용하는 것을 Marshaller에 설정할 수 있습니다.

루트 아래

은 기본적으로 유형 base64Binary의 요소로 표현됩니다 byte[] 속성 샘플 도메인 객체입니다.

package forum8914008; 

import javax.xml.bind.annotation.*; 

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

    byte[] bytes; 

} 

데모

첫번째 보안관 아래의 데모 코드 XML로 개체를 한 다음 그것을 AttachmentMarshaller 세트의 사용자 지정 impplementation와 두 번째로 마샬링.

package forum8914008; 

import javax.activation.DataHandler; 
import javax.xml.bind.*; 
import javax.xml.bind.attachment.AttachmentMarshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Root.class); 

     Root root = new Root(); 
     root.bytes = "Hello World".getBytes(); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 

     marshaller.setAttachmentMarshaller(new AttachmentMarshaller() { 

      @Override 
      public boolean isXOPPackage() { 
       return true; 
      } 

      @Override 
      public String addMtomAttachment(DataHandler arg0, String arg1, 
        String arg2) { 
       return "fake"; 
      } 

      @Override 
      public String addMtomAttachment(byte[] arg0, int arg1, int arg2, 
        String arg3, String arg4, String arg5) { 
       return "fake"; 
      } 

      @Override 
      public String addSwaRefAttachment(DataHandler arg0) { 
       return "fake"; 
      } 

     }); 
     marshaller.marshal(root, System.out); 
    } 

} 

출력 아래

데모 코드를 실행 한 출력됩니다. byte []가 클 경우 첫 번째 XML 문서가 상당히 커질 수 있습니다. 두 x 째 XML.서는 동일한 크기를 유지합니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <bytes>SGVsbG8gV29ybGQ=</bytes> 
</root> 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <bytes> 
     <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="fake"/> 
    </bytes> 
</root> 
0
내가 한 마샬/Unmarshaller에 데이터를 청소할 수 있지만 어떻게

하지 다른 하지만 모두 그 기원 같은 JAXB 컨텍스트입니까?


당신은 XmlAdapter이 사용 사례를 지원할 수있다.

(때문에) XmlAdapter (ByteArrayAdapter)

다음 XmlAdapterbyte[]byte[]을 변환하는 데 사용됩니다. 기본 상태에서는 원래 byte[]을 반환 할 것이고, 빈 상태 []를 반환하는 감사 상태도 있습니다.

package forum8914008; 

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

public class ByteArrayAdapter extends XmlAdapter<byte[], byte[]> { 

    private boolean audit; 

    public ByteArrayAdapter() { 
     this(false); 
    } 

    public ByteArrayAdapter(boolean audit) { 
     this.audit = audit; 
    } 

    @Override 
    public byte[] marshal(byte[] bytes) throws Exception { 
     if(audit) { 
      return new byte[0]; 
     } 
     return bytes; 
    } 

    @Override 
    public byte[] unmarshal(byte[] bytes) throws Exception { 
     return bytes; 
    } 

} 

은 패키지 정보

@XmlJavaTypeAdapter 주석은 XmlAdapter를 등록 TP 사용된다. 패키지 수준에서 사용될 경우 해당 패키지의 지정된 유형의 모든 속성에 적용됩니다 (http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html 참조).

@XmlJavaTypeAdapter(value=ByteArrayAdapter.class, type=byte[].class) 
package forum8914008; 

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

루트 아래

기본적으로 base64Binary 인 유형의 요소로 표현 될 바이트 [] 속성 샘플 도메인 개체이다.

package forum8914008; 

import javax.xml.bind.annotation.*; 

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

    byte[] bytes; 

} 

데모

첫번째 보안관 아래의 데모 코드하는 것입니다 상태 ByteArrayAdapter 세트 개체를 두 번 실제 byte[]과 보안관을 반환합니다 ByteArrayAdapter의 기본 상태와 객체 byte[] 값을 모두 비어있는 byte[]으로 변환하십시오.

package forum8914008; 

import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Root.class); 

     Root root = new Root(); 
     root.bytes = "Hello World".getBytes(); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 

     marshaller.setAdapter(new ByteArrayAdapter(true)); 
     marshaller.marshal(root, System.out); 
    } 

} 

출력 아래

데모 코드를 실행 한 출력됩니다. XmlAdapterbyte[] 유형의 모든 매핑 된 입력란/속성에 적용됩니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <bytes>SGVsbG8gV29ybGQ=</bytes> 
</root> 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <bytes></bytes> 
</root> 
관련 문제