Джерси сериализует наследуемое имущество дважды - PullRequest
4 голосов
/ 10 марта 2011

У меня есть Java-бин без каких-либо аннотаций. И у меня есть класс, унаследованный от этого компонента с аннотациями JAXB.

Джерси (JAX-RS) сериализует второй класс в JSON. И унаследованные свойства встречаются в JSON дважды: с именем из аннотации XmlElement и с именем 'camel-case' свойства java-bean. Вот код, который иллюстрирует это:

class MyBean {

   private Integer beanField;

   public Integer getBeanField() { return beanField; }

   public void setBeanField(Integer value) { this.beanField = value; }

}

@XmlRootElement
class AnnotatedBean extends MyBean {

  @Override
  @XmlElement(name="field")
  public Integer getBeanField() { return super.getBeanField(); }
}

}

После сериализации я получаю следующий JSON:

{ 
   "field" : 5,
   "beanField" : 5
}

(хотя я хочу, чтобы оно содержало только одно поле с именем field).

Я исследовал реализацию маршаллера JAXB и обнаружил, что он маршалирует свойства всех суперклассов данного класса (а это значит, что в моем примере избавиться от нечетного свойства beanField невозможно).

Но я все еще надеюсь, что могу что-то упустить. Есть ли способ сериализации только аннотированных свойств?

1 Ответ

4 голосов
/ 10 марта 2011

Чтобы получить только аннотированные свойства, используйте XmlAccessType.NONE:

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
class AnnotatedBean extends MyBean {
    ...
}
<Ч />

Отображение класса третьей стороны с использованием внешних метаданных

Вы можете использовать расширение внешних метаданных в EclipseLink JAXB (MOXy), я технический руководитель. Это позволяет вам предоставлять метаданные для сторонних классов. В этом примере метаданные будут выглядеть так:

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="third.party.package">
    <java-types>
        <java-type name="MyBean" xml-transient="true"/>
    </java-types>
</xml-bindings>

Чтобы использовать MOXy, вам нужно добавить файл с именем jaxb.properties в классы вашей модели со следующей записью:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

В следующей статье приведены инструкции по настройке MOXy для работы с Jersery:

Средство разрешения контекста - использование метаданных

Вам потребуется использовать ContextResolver, чтобы получить свой JAXBContext для использования файла внешних привязок. Метаданные указываются через свойство при создании экземпляра JAXBContext:

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextFactory;

@Provider
@Produces({"application/xml", "application/json"})
public class AnnotatedBeanContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext jaxbContext;

    public PurchaseOrderContextResolver() {
        try {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/blog/bindingfile/binding.xml"));
        jaxbContext = JAXBContext.newInstance(new Class[] {AnnotatedBean.class}, properties);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public JAXBContext getContext(Class<?> clazz) {
        if(AnnotatedBean.class == clazz) {
            return jaxbContext;
        }
        return null;
    }

}
...