users@jersey.java.net

[Jersey] Re: XmlHeader automated

From: Martin Matula <martin.matula_at_oracle.com>
Date: Tue, 04 Oct 2011 23:39:47 -0700

On 4.10.2011 1:29, Lukas Lentner wrote:
>
> It's no problem for me to upgrade.
>
> Is there a newer version which has this feature?
>
> (I'm not talking about the XmlHeader Annotation, cause it's a) not
> automatically added and b) absolut URLs must be hardcoded in the code)
>

Oh, I see. That should be possible now. Try to provide a custom
JAXBContext and set the header in the createMarshaller() method on the
marshaller before returning it. I.e. something like this (untested):

@Provider
public class PlanetJAXBContextProvider implements ContextResolver<JAXBContext> {
     private static final Map<Class, JAXBContext> jaxbContexts =
             new WeakHashMap<Class, JAXBContext>();

     @Context UriInfo uriInfo;

     public JAXBContext getContext(Class<?> type) {
         synchronized (jaxbContexts) {
             JAXBContext c = jaxbContexts.get(type);
             if (c == null) {
                 try {
                     c = new WrappingContext(JAXBContext.newInstance(type));
                 } catch (JAXBException e) {
                     // log warning/error; null will be returned which indicates that this
                     // provider won't/can't be used.
                 }

                 jaxbContexts.put(type, c);
             }
         }
         return c;
     }

     private class WrappingContext extends JAXBContext {
         private final JAXBContext inner;

         public WrappingContext(JAXBContext inner) {
             this.inner = inner;
         }

         @Override
         public Marshaller createMarshaller() throws JAXBException {
             Marshaller m = inner.createMarshaller();
             String headerValue = "set to your desired value utilizing uriInfo";
             try {
                 // standalone jaxb ri
                 m.setProperty("com.sun.xml.bind.xmlHeaders", headerValue);
             } catch (PropertyException e) {
                 try {
                     // jaxb ri from jdk
                     m.setProperty("com.sun.xml.internal.bind.xmlHeaders", headerValue);
                 } catch (PropertyException ex) {
                     // other jaxb implementation
                     Logger.getLogger(AbstractJAXBProvider.class.getName()).log(
                             Level.WARNING, "@XmlHeader annotation is not supported with this JAXB implementation. Please use JAXB RI if you need this feature.");
                 }
             }
             return m;
         }

         // TODO: implement all the other instance methods of JAXBContext by delegating to inner
     }
}

See if it works.
Martin