You could create a MessageBodyWriter for this use case. Through the ContextResolver mechanism you can get the JAXBContext associated with your domain model. Then you can get a Marshaller from the JAXBContext and set the JAXB_SCHEMA_LOCATION on it and do the marshal.
package org.example;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.*;
import javax.xml.bind.*;
@Provider
@Produces(MediaType.APPLICATION_XML)
public class FormattingWriter implements MessageBodyWriter<Object>{
@Context
protected Providers providers;
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
public void writeTo(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
try {
ContextResolver<JAXBContext> resolver
= providers.getContextResolver(JAXBContext.class, mediaType);
JAXBContext jaxbContext;
if(null == resolver || null == (jaxbContext = resolver.getContext(type))) {
jaxbContext = JAXBContext.newInstance(type);
}
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "foo bar");
m.marshal(object, entityStream);
} catch(JAXBException jaxbException) {
throw new WebApplicationException(jaxbException);
}
}
public long getSize(Object t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
}
UPDATE
One other question. What is the connection between the my rest resource and the provider?
You still implement your resource the same way. The MessageBodyWriter mechanism is just a way to override how the writing to XML will be done. The @Provider annotation is a signal to the JAX-RS application to have this class automatically registered.
My resource class would return a Foo object. I take it I should be implementing a
MessageBodyWriter<Foo>?
You could implement it as MessageBodyWriter<Foo> if you only want it applied to the Foo class. If you want it to apply to more than just Foo you can implement to the isWriteable method to return true for the appropriate classes.