使用Spring配置CXF以使用MOXY进行XML编组/解组

我有一个Java服务器应用程序,它使用CXF提供SOAP和REST Web服务。 目前它使用JAX-B的参考实现进行XML编组/解组,但我已经将它配置为用jackson代替Jettison进行JSON编组/解组。 我使用Spring进行DI和应用程序上下文配置。

REST Web服务配置代码段如下所示:

web.xml中

 Myapp REST Services MyappWebServices org.apache.cxf.transport.servlet.CXFServlet 1   MyappWebServices /services/*  

applicationContext.xml中

             

此配置有效,将返回XML或JSON,具体取决于HTTP Accept标头。 我喜欢这个配置的是它基于Spring,并且创建和使用备用JSON编码器非常容易。 有关配置CXF的详细信息,请参见此处 。

我的问题是,现在我有一个新的(额外的)REST Web服务提供,我想为这个新的Web服务使用不同的JAX-B XML绑定。 我知道MOXy可以做到这一点,但我无法弄清楚如何配置CXF端点,以便它将使用MOXy进行编组/解组(以及如何告诉Moxy我的自定义XML映射文件)。 我还希望这个新的Web服务返回XML或JSON,具体取决于Accept标头。 我也读过MOXy 2.4+也可以处理它!

理想情况下,我可以在不影响其他现有servlet的情况下将MOXy用于此新端点。

注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB(JSR-222)专家组的成员。


我不知道CXF的确切配置,但下面我提供了一些使用MOXy和Spring的链接。 请随时与我联系 ,我可以帮助您实现这一点:

我的问题是,现在我有一个新的(额外的)REST Web服务提供,我想为这个新的Web服务使用不同的JAX-B XML绑定。 我知道MOXy可以做到这一点,但我无法弄清楚如何配置CXF端点,以便它将使用MOXy进行编组/解组(以及如何告诉Moxy我的自定义XML映射文件)。

将MOXy与JAX-RS实现一起使用时,可以使用ContextResolver从MOXy的外部映射文件引导:

 package blog.bindingfile.jaxrs; import java.io.*; import java.util.*; import javax.ws.rs.Produces; import javax.ws.rs.ext.*; import javax.xml.bind.*; import org.eclipse.persistence.jaxb.JAXBContextFactory; import blog.bindingfile.Customer; @Provider @Produces({"application/xml", "application/json"}) public class CustomerContextResolver implements ContextResolver { private JAXBContext jc; public CustomerContextResolver() { ClassLoader cl = Customer.class.getClassLoader(); InputStream bindings = cl.getResourceAsStream("blog/bindingfile/binding.xml"); try { Map props = new HashMap(1); props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, bindings); jc = JAXBContext.newInstance(new Class[] {Customer.class} , props); } catch(JAXBException e) { throw new RuntimeException(e); } finally { try { bindings.close(); } catch(IOException e) { throw new RuntimeException(e); } } } public JAXBContext getContext(Class clazz) { if(Customer.class == clazz) { return jc; } return null; } } 

对于Complext示例

有关在Spring中使用MOXy的更多信息


我还希望这个新的Web服务返回XML或JSON,具体取决于Accept标头。 我也读过MOXy 2.4+也可以处理它!

是的,JSON绑定正被添加到EclipseLink 2.4中。 要在您的应用程序中利用它,应该是创建MessageBodyReaderMessageBodyWriter的简单问题:

 package org.example; import java.io.*; import java.lang.annotation.Annotation; import java.lang.reflect.*; import javax.xml.transform.stream.StreamSource; import javax.ws.rs.*; import javax.ws.rs.core.*; import javax.ws.rs.ext.*; import javax.xml.bind.*; @Provider @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class MOXyJSONProvider implements MessageBodyReader, MessageBodyWriter{ @Context protected Providers providers; public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return true; } public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { try { Class domainClass = getDomainClass(genericType); Unmarshaller u = getJAXBContext(domainClass, mediaType).createUnmarshaller(); u.setProperty("eclipselink.media-type", mediaType.toString()); u.setProperty("eclipselink.json.include-root", false); return u.unmarshal(new StreamSource(entityStream), domainClass).getValue(); } catch(JAXBException jaxbException) { throw new WebApplicationException(jaxbException); } } 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 httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { try { Class domainClass = getDomainClass(genericType); Marshaller m = getJAXBContext(domainClass, mediaType).createMarshaller(); m.setProperty("eclipselink.media-type", mediaType.toString()); m.setProperty("eclipselink.json.include-root", false); 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; } private JAXBContext getJAXBContext(Class type, MediaType mediaType) throws JAXBException { ContextResolver resolver = providers.getContextResolver(JAXBContext.class, mediaType); JAXBContext jaxbContext; if(null == resolver || null == (jaxbContext = resolver.getContext(type))) { return JAXBContext.newInstance(type); } else { return jaxbContext; } } private Class getDomainClass(Type genericType) { if(genericType instanceof Class) { return (Class) genericType; } else if(genericType instanceof ParameterizedType) { return (Class) ((ParameterizedType) genericType).getActualTypeArguments()[0]; } else { return null; } } } 

您也可以创建JSONProvider的扩展:

了解更多信息

  • MOXy作为您的JAX-RS JSON提供者 – 客户端
  • MOXy作为您的JAX-RS JSON提供程序 – 服务器端
  • 将EclipseLink MOXy指定为JAXB提供程序