Frage

Ich habe einen JAX-RS REST-Dienst Jersey umgesetzt. Eines der coolen Features von JAX-RS / Jersey ist, wie leicht ein POJO in einen REST-Dienst eingeschaltet werden, indem einfach ein paar Java-Annotationen Beregnung ... darunter einen trivialen einfachen Mechanismus für POJOs zu JSON übersetzen -. Mit JAXB Anmerkungen

Nun würde Ich mag Lage seines Vorteil dieser kühlen JSON-ifying Funktionalität zu übernehmen für Nicht-REST Zwecke - ich würde gerne in der Lage sein, nur einige dieser Objekte auf der Festplatte serialisiert, wie JSON Text. Hier ist ein Beispiel JAXB Objekt, das ich wollen würde serialisiert:

@XmlRootElement(name = "user")
public class UserInfoImpl implements UserInfo {

    public UserInfoImpl() {} 

    public UserInfoImpl(String user, String details) {
        this.user = user;
        this.details = details;
    }

    public String getUser() { return user; }
    public void setUser(String user) { this.user = user; }

    public String getDetails() { return details; }
    public void setDetails(String details) { this.details = details; }

    private String user;
    private String details;
}

Jersey kann man von diesen in json ohne zusätzliche Informationen wenden. Ich frage mich, wenn Jersey diese Funktionalität in der API für Bedürfnisse wie meine ausgesetzt? Ich habe kein Glück gehabt zu finden, es so weit ...

Danke!

UPDATE 2009-07-09 : Ich habe gelernt, dass ich die Provider-Objekt verwenden kann fast genau das tun, was ich will:

  @Context Providers ps;
  MessageBodyWriter uw = ps.getMessageBodyWriter(UserInfoImpl.class, UserInfoImpl.class, new Annotation[0], MediaType.APPLICATION_JSON_TYPE);

  uw.writeTo(....)

... Dies schreibt das Objekt als json einen Output, was für mich vollkommen sein würde, aber ich kann an dem Provider nur erhalten Objekt mit @Context von einem @Component Objekt. Wer weiß, wie es für den Zugriff von einem normalen, nicht-kommentierte POJO? Dank!

War es hilfreich?

Lösung

Jersey verwendet ein paar verschiedene Frameworks je nachdem, ob Sie kartiert () verwenden, badgerfish () oder natürliche () Notation. Natürliche ist in der Regel derjenige Leute wollen. Und das mit dem sehr gut umgesetzt (und sehr schnell) Standalone-Jackson JSON-Prozessor, glaube ich, die von Object- geht> JAXB-> JSON. Allerdings Jackson bietet auch eigenen JAX-RS-Providers es direkt Object-> JSON gehen.

In der Tat, fügten sie hinzu, auch die Unterstützung für JAXB Annotationen. Werfen Sie einen Blick auf

http://wiki.fasterxml.com/JacksonJAXBAnnotations

Ich denke, das ist letztlich das, was Sie suchen. Jackson hat Objekt <-> JSON Verarbeitung ... Jersey macht nur die Anrufe für Sie

Andere Tipps

Hier ist ein einfaches kurzes Beispiel JAXB die Verwendung von Objekten zu JSON zur Karte (mit Jackson):

http://ondra.zizka.cz/ stranky / programovani / java / jaxb-json-jackson-howto.texy

ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(pojoObject);

JAXB Anmerkungen funktionieren, wenn in XML serialisiert. Das Hauptproblem ist, dass JAXB nicht leere Arrays unterstützen. Also, wenn so etwas wie dieses Serialisierung ...

List myArray = new ArrayList();

... JSon über jaxb anottations alle leere Arrays werden null statt [].

Um dies zu lösen, können Sie einfach Ihre POJOs direkt an json über jackson serialisiert werden.

Werfen Sie einen Blick auf diese aus Jersey in der Bedienungsanleitung: http://jersey.java.net/nonav/documentation/latest /user-guide.html#d0e1959

Dies ist der beste Weg, Jackson Anbieter ohne JAXB zu verwenden. Darüber hinaus können Sie immer die neueste Version von Jackson verwendet von downlaoding jackson-all-x.y.z-jar von Netz.

Diese Methode wird nicht mit Ihren jaxb Anmerkungen stören, damit ich einen Versuch haben würde vorschlagen!

Da Jersey eine Referenzimplementierung von JAX-RS und JAX-RS ist vollständig fokussiert ist eine Standardmethode des Endpunkts für den REST-Service bei der Umsetzung der Nutzlast der Fragen der Serialisierung auf der Bereitstellung von auf andere Standards gelassen.

Ich glaube, dass, wenn sie Objektserialisierung in dem JAX-RS enthalten Standard schnell ein großes mehrköpfigen Tier werden würde, das wäre schwer zu einige seine Fokus zu implementieren und zu verlieren.

ich zu schätzen, wie konzentriert Jersey auf der Bereitstellung von sauberen und einfach REST-Endpunkte zu verwenden. In meinem Fall habe ich subclassed nur ein Elternteil, das alle JAXB Sanitär in es so Rangier Objekte zwischen Binär- und XML ist sehr sauber ist.

Mit einem wenig Jersey spezifischen Bootstrapping, können Sie es verwenden, um die notwendigen JSON-Objekte für Sie zu erstellen. Sie müssen die folgenden Abhängigkeiten schließen (Sie Bündel verwenden können, aber es wird zu Problemen führen, wenn Sie Weld zum Testen verwenden):

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.12</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.12</version>
    </dependency>

Von dort können Sie eine JAXB kommentierte Klasse erstellen. Im Folgenden ist ein Beispiel:

@XmlRootElement
public class TextMessage {
private String text;
    public String getText() { return text; }
    public void setText(String s) { this.text = text; }
}

Dann können Sie den folgenden Komponententest erstellen:

    TextMessage textMessage = new TextMessage();
    textMessage.setText("hello");
    textMessage.setUuid(UUID.randomUUID());

    // Jersey specific start
    final Providers ps = new Client().getProviders();
    // Jersey specific end
    final MultivaluedMap<String, Object> responseHeaders = new MultivaluedMap<String, Object>() {

        @Override
        public void add(final String key, final Object value) {
        }

        @Override
        public void clear() {
        }

        @Override
        public boolean containsKey(final Object key) {
            return false;
        }

        @Override
        public boolean containsValue(final Object value) {
            return false;
        }

        @Override
        public Set<java.util.Map.Entry<String, List<Object>>> entrySet() {
            return null;
        }

        @Override
        public List<Object> get(final Object key) {
            return null;
        }

        @Override
        public Object getFirst(final String key) {
            return null;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public Set<String> keySet() {
            return null;
        }

        @Override
        public List<Object> put(final String key, final List<Object> value) {
            return null;
        }

        @Override
        public void putAll(
                final Map<? extends String, ? extends List<Object>> m) {
        }

        @Override
        public void putSingle(final String key, final Object value) {
        }

        @Override
        public List<Object> remove(final Object key) {
            return null;
        }

        @Override
        public int size() {
            return 0;
        }

        @Override
        public Collection<List<Object>> values() {
            return null;
        }
    };

    final MessageBodyWriter<TextMessage> messageBodyWriter = ps
            .getMessageBodyWriter(TextMessage.class, TextMessage.class,
                    new Annotation[0], MediaType.APPLICATION_JSON_TYPE);
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Assert.assertNotNull(messageBodyWriter);

    messageBodyWriter.writeTo(textMessage, TextMessage.class,
            TextMessage.class, new Annotation[0],
            MediaType.APPLICATION_JSON_TYPE, responseHeaders, baos);
    final String jsonString = new String(baos.toByteArray());
    Assert.assertTrue(jsonString.contains("\"text\":\"hello\""));

Der Vorteil dieses Ansatzes ist es alles in der JEE6 API hält, werden keine externen Bibliotheken explizit benötigt, außer für das Testen und die Anbieter zu bekommen. Allerdings müssen Sie eine Implementierung von MultivaluedMap schaffen, da es nichts in der Norm vorgesehen ist und wir nicht wirklich verwenden. Es können auch langsamer als Gson und viel komplizierter als nötig.

Ich verstehe XML Ansichten, aber es würde einige Voraussicht gezeigt hat JSON-Unterstützung für POJOs als Standardausrüstung erfordern. Mit JSON-Kennungen mit Sonderzeichen für den Arzt up macht keinen Sinn, wenn Ihre Implementierung ist JSON und Ihr Kunde ist eine JavaScript-RIA.

Auch nicht, dass Java Beans sind NICHT POJOs. Ich möchte so etwas wie dies auf der äußeren Oberfläche meiner Web-Tier verwenden:

public class Model
{
   @Property height;
   @Property weight;
   @Property age;
}

Kein Standardkonstruktor, kein Getter / Setter Lärm, nur ein POJO mit eigenen Anmerkungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top