- MOXy作為您的JAX-RS JSON提供程序–服務器端
- MOXy作為您的JAX-RS JSON提供程序–客戶端
為什么選擇EclipseLink JAXB(MOXy)?
以下是將MOXy用作JSON綁定提供程序的一些優點:
- JSON綁定提供程序中對JAXB注釋的最廣泛支持。
- 支持XML和JSON: 綁定到JSON和XML – Geocode示例 。
- MOXy包含@XmlInverseReference之類的擴展名,用于將JPA實體映射到JSON和XML: 第3部分–將JPA實體映射到XML(使用JAXB) 。
- 外部映射文檔可作為注釋的替代方法: JAX-RS Service中的MOXy的XML元數據 。
客戶服務
使用@Produces和@Consumes批注控制JAX-RS服務理解的消息類型。 在這篇文章中,我指定了除“ application / xml”外,所有操作現在都支持“ application / json”。 以下帖子提供了對該服務的更詳細描述: 創建RESTful Web服務–第4/5部分 。
package org.example;import java.util.List;
import javax.ejb.*;
import javax.persistence.*;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;@Stateless
@LocalBean
@Path("/customers")
public class CustomerService {@PersistenceContext(unitName="CustomerService",type=PersistenceContextType.TRANSACTION)EntityManager entityManager;@POST@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})public void create(Customer customer) {entityManager.persist(customer);}@GET@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})@Path("{id}")public Customer read(@PathParam("id") long id) {return entityManager.find(Customer.class, id);}@PUT@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})public void update(Customer customer) {entityManager.merge(customer);}@DELETE@Path("{id}")public void delete(@PathParam("id") long id) {Customer customer = read(id);if(null != customer) {entityManager.remove(customer);}}@GET@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})@Path("findCustomersByCity/{city}")public List<Customer> findCustomersByCity(@PathParam("city") String city) {Query query = entityManager.createNamedQuery("findCustomersByCity");query.setParameter("city", city);return query.getResultList();}}
MOXyJSONProvider
我們將實現JAX-RS MessageBodyReader / MessageBodyWriter,以插件支持MOXy的JSON綁定。 此實現足夠通用,可以直接使用MOXy作為JAXB提供程序為任何JAX-RS服務啟用JSON綁定。 一些有趣的注意事項:
- MOXy沒有編譯時間依賴性。
- eclipselink.media-type屬性用于在unmarshaller(第34行)和marshaller(第55行)上啟用JSON綁定。
- eclipselink.json.include-root屬性用于指示@XmlRootElement批注在JSON綁定中應被忽略(第35和56行)。
- 創建JAXBContext時,代碼首先檢查以查看是否已為此類型注冊JAXBContext(第70和71行)。 如果要利用MOXy的外部映射文檔: JAX-RS Service中的MOXy的XML元數據,這將很有用。
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 implementsMessageBodyReader<Object>, MessageBodyWriter<Object>{@Contextprotected Providers providers;public boolean isReadable(Class<?> type, Type genericType,Annotation[] annotations, MediaType mediaType) {return true;}public Object readFrom(Class<Object> type, Type genericType,Annotation[] annotations, MediaType mediaType,MultivaluedMap<String, String> 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<String, Object> 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<JAXBContext> 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;}}}
服務器設置
如果將GlassFish用作應用程序服務器,則需要使用EclipseLink 2.4安裝中的對應軟件包替換以下EclipseLink軟件包。
- org.eclipse.persistence.antlr.jar
- org.eclipse.persistence.asm.jar
- org.eclipse.persistence.core.jar
- org.eclipse.persistence.jpa.jar
- org.eclipse.persistence.jpa-modelgen.jar
- org.eclipse.persistence.moxy.jar
- org.eclipse.persistence.oracle.jar
進一步閱讀
如果您喜歡這篇文章,那么您可能也會對以下內容感興趣:
- RESTful服務
- MOXy作為您的JAX-RS JSON提供程序–客戶端
- 創建一個RESTful服務
- 第1部分–數據庫
- 第2部分–將數據庫映射到JPA實體
- 第3部分–將JPA實體映射到XML(使用JAXB)
- 第4部分– RESTful服務
- 第五部分–客戶
- JAX-RS服務中的MOXy的XML元數據
- JSON綁定
- 使用EclipseLink MOXy進行JSON綁定– Twitter示例
- 綁定到JSON和XML –地理編碼示例
- 應用服務器集成
- GlassFish 3.1.2充滿了MOXy(EclipseLink JAXB)
- EclipseLink MOXy是WebLogic Server 12c中的JAXB提供程序
參考: MOXy作為您的JAX-RS JSON提供程序–來自Java XML和JSON綁定博客的JCG合作伙伴 Blaise Doughan的服務器端 。
翻譯自: https://www.javacodegeeks.com/2012/04/moxy-as-your-jax-rs-json-provider.html