Wildfly - JAXB und JsonB gemeinsam nutzen

mrBrown

Super-Moderator
Mitarbeiter
Ich hab aktuell in Problem mit der Serialisierung von Klassen als XML und Json, vielleicht kennt sich jemand zufällig damit aus.

Ich hab eine einfache Jax-rs-Applikation, die einfach nur ein simples DTO zurückgibt.
Das DTO ist annotiert mit JAXB und JsonB-Annotationen (zB, da Adapter aus beiden APIs benutzt werden).
Die Serialisierung als XML klappt problemlos, die Serialisierung als Json allerdings nicht.
Statt Json-B zu nutzen, nutzt er (wenn ich’s richtig sehe) Jackson und serialisiert das ganze anhand der JAXB-Annotationen, welches zB bei Nutzung der Adapter fehlschlägt. Lässt man die JAXB-Annotationen weg, wird passend mit JsonB serialisiert, dann scheitert aber natürlich JAXB...


Probiert hab ich bisher, Jackson explizit zu ignorieren (findet dann gar keinen MessageBody-Writer für Json), und die Klasse mit @NoJackson bzw @IgnoreMediaTypes zu annotieren, hat aber bisher nichts gebracht.


Hat vielleicht irgendjemand eine Idee?
 

mrBrown

Super-Moderator
Mitarbeiter
Das wird im Wildfly genutzt - aber das Problem ist ja eben, dass es bei mir nur genutzt wird, wenn in der Klasse keinerlei JAXB-Annotationen vorhanden sind.



Java:
class TestDto {
  @JsonbProperty("jsonb-id")
  public String id = "id";
}
Führt zu
Code:
{
    "json-id": "id"
}


Aber
Java:
@XmlRootElement(name = "test")
class TestDto {
  @XmlAttribute(name = "xml-id")
  @JsonbProperty("jsonb-id")
  public String id = "id";
}
Führt zu
Code:
{
    "xml-id": "id"
}


Java:
@ApplicationPath("")
public class AppConfig extends Application {

}
Java:
@Path("test")
public class TestResource {
    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public TestDto getTest() {
        return new TestDto();
    }
}
 

mihe7

Top Contributor
Hm... hab das mal in Payara Micro probiert:
Class org.eclipse.yasson.internal.model.GetFromField can not access a member of class app.TestDto with modifiers "public"

XML funktioniert. Strange.
 

mrBrown

Super-Moderator
Mitarbeiter
Das sollte sich allerdings mit @IgnoreMediaTypes ignorierbar sein:
https://docs.jboss.org/resteasy/docs/3.6.0.Final/userguide/html_single/index.html#Possible_Jackson_Problems hat gesagt.:
If your Jackson classes are annotated with JAXB annotations and you have the resteasy-jaxb-provider in your classpath, you may trigger the Jettision JAXB marshalling code. To turn off the JAXB json marshaller use the @org.jboss.resteasy.annotations.providers.jaxb.IgnoreMediaTypes("application/*+json") on your classes.

Und Json-B sollte zumindest meinem Verständnis trotzdem Vorrang haben:
https://docs.jboss.org/resteasy/docs/3.6.0.Final/userguide/html_single/index.html#d4e1500 hat gesagt.:
To satisfy JAX-RS 2.1 requirements, JsonBindingProvider takes precedence over the other providers for dealing with JSON payloads, in particular the Jackson one.

Vielleicht gibts da noch irgendwelche geheimen Flags die man kennen muss...
 

mrBrown

Super-Moderator
Mitarbeiter
Du bist genial...ich hab gefühlt ewig nach nem issue dazu gesucht.

Scheint leider erst in Resteasy 4 geändert zu sein, aber lässt sich sicher auch in unsere Version lokal irgendwie patchen...
 

mihe7

Top Contributor
Du bist genial...ich hab gefühlt ewig nach nem issue dazu gesucht.
Eigentlich merke ich immer mehr, wie viel ich nicht weiß :(

aber lässt sich sicher auch in unsere Version lokal irgendwie patchen...
Jo....

Mit
Code:
diff --git a/providers/json-binding/src/main/java/org/jboss/resteasy/plugins/providers/jsonb/JsonBindingProvider.java b/providers/json-binding/src/main/java/org/jboss/resteasy/plugins/providers/jsonb/JsonBindingProvider.java
index b4cc73d..b2b5559 100644
--- a/providers/json-binding/src/main/java/org/jboss/resteasy/plugins/providers/jsonb/JsonBindingProvider.java
+++ b/providers/json-binding/src/main/java/org/jboss/resteasy/plugins/providers/jsonb/JsonBindingProvider.java
@@ -20,11 +20,6 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlSeeAlso;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
 import org.apache.commons.io.input.ProxyInputStream;
 import org.jboss.resteasy.plugins.providers.jsonb.i18n.Messages;
@@ -60,12 +55,7 @@ public class JsonBindingProvider extends AbstractJsonBindingProvider
       {
          return false;
       }
-      if (isGenericJaxb(type, genericType))
-      {
-         return false;
-      }
-      return (isSupportedMediaType(mediaType))
-              && ((FindAnnotation.hasJsonBindingAnnotations(annotations)) || (!isJaxbClass(type)));
+      return isSupportedMediaType(mediaType);
    }
 
    @Override
@@ -119,12 +109,7 @@ public class JsonBindingProvider extends AbstractJsonBindingProvider
       {
          return false;
       }
-      if (isGenericJaxb(type, genericType))
-      {
-         return false;
-      }
-      return (isSupportedMediaType(mediaType))
-            && ((FindAnnotation.hasJsonBindingAnnotations(annotations)) || (!isJaxbClass(type)));
+      return isSupportedMediaType(mediaType);
    }
 
    @Override
@@ -150,42 +135,4 @@ public class JsonBindingProvider extends AbstractJsonBindingProvider
       }
    }
    
-   private boolean isGenericJaxb(Class<?> type, Type genericType)
-   {
-      if (Map.class.isAssignableFrom(type) && genericType != null)
-      {
-         Class<?> valueType = Types.getMapValueType(genericType);
-         if (valueType != null && isJaxbClass(valueType))
-         {
-            return true;
-         }
-      }
-
-      if ((Collection.class.isAssignableFrom(type) || type.isArray()) && genericType != null)
-      {
-         Class<?> baseType = Types.getCollectionBaseType(type, genericType);
-         if (baseType != null && isJaxbClass(baseType))
-         {
-            return true;
-         }
-      }
-      return false;
-   }
-
-   private boolean isJaxbClass(Class<?> classType)
-   {
-      if (JAXBElement.class.equals(classType))
-      {
-         return true;
-      }
-      for (Annotation a : classType.getAnnotations()) {
-         Class<? extends Annotation> c = a.annotationType();
-         if (c.equals(XmlRootElement.class) || c.equals(XmlType.class) ||c.equals(XmlJavaTypeAdapter.class) ||c.equals(XmlSeeAlso.class))
-         {
-            return true;
-         }
-      }
-      return false;
-
-   }
 }
liefern
Code:
curl -H "Accept: application/xml" http://localhost:8080/jpa/test
vs
curl -H "Accept: application/json" http://localhost:8080/jpa/test
die Ausgaben
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><test xml-id="id"/>
vs
{"jsonb-id":"id"}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Configuration WildFly Web Tier 7

Ähnliche Java Themen

Neue Themen


Oben