Mit Standard-Anbieter/MessageBodyWriters in Jersey 2
Nur beginnend mit Jersey, ich habe versucht, zu reproduzieren das einfache Beispiel in der neuesten Jersey-Dokumentation"Gebäude-Antworten'. Dieser Teil, soweit ich das verstanden habe, sollte zeigen, wie Response
und ResponseBuilder
können verwendet werden, um leicht eine Antwort zurück, die in Kombination mit Entity<T>
für response-content.
Nun, die Dokumentation besagt, dass mehrere Datentypen werden standardmäßig unterstützt (hier: 'Darstellungen und Java-Typen'). String
prime unter Ihnen, passend zu jedem media-Typ.
Alle Varianten die ich ausprobiert habe, die folgende ist die einfachste:
@POST
public Response post() {
URI createdUri;
try {
createdUri = new URI("http://test.lan");
} catch (final URISyntaxException e) {
throw new WebApplicationException(e);
}
return Response.created(createdUri).entity(Entity.text("someContent")).build();
}
Habe ich immer bekommen den gleichen Fehler (full stacktrace unten) auf, der die Anforderung aufruft:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=text/plain, type=class javax.ws.rs.client.Entity, genericType=class javax.ws.rs.client.Entity.
Ich glaube, es ist zu sagen, dass ein passender Anbieter wurde nicht gefunden für diese Entity generic-Typ. Allerdings Zeichenfolge unterstützt werden sollte OOTB?
Fand ich, dass StringMessageProvider
ist wahrscheinlich das Trikot 1 Umsetzung dieses Anbieters, und die nächsten verwandten Klassen fand ich in meinem Jersey 2 Bibliotheken arer Klassen in org.glassfish.jersey.message.internal
in jersey-common. Unter den vielen Anbietern gibt es die StringMessageProvider
, die mir erscheint wie eine mögliche soll-provider für diesen.
Ich habe mir die Ausgabe, und während es gibt viele Menschen, die diese bekommen, wenn fälschlicherweise versucht, einen custom-Provider, fand ich nichts über die Standard-OOTB-Anbieter, die nicht arbeiten..
Ich habe meine libs, und nun habe ich folgende Abhängigkeiten in meinem pom (unter anderem):
- jersey-container-servlet-core
- jersey-client -
- jersey-common
- jersey-server
Habe ich online geschaut, aber das scheint alles was ich brauche, obwohl ich noch nicht mit Gewissheit, das richtige gefunden-provider-Klassen für String und JAXB/JSON, in die Gläser.
Kontext
- Maven-Projekt
- mit tomcat-servlet-api-6.0.29
- Version 2.6 von allen erwähnt-jersey-libs
- Eclipse kepler
- Mit tomcat6-maven-plugin zum ausführen von eingebetteten tomcat (funktioniert soweit)
Fiddler Anfrage verwendet, um zu testen
POST HTTP/1.1
User-Agent: Fiddler
Host: 127.0.0.1
Content-Length: 0
Wieder versucht, verschiedene Variationen.
Vollständigen stacktrace
06-Jan-2015 21:13:54 org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
SEVERE: MessageBodyWriter not found for media type=text/plain, type=class javax.ws.rs.client.Entity, genericType=class javax.ws.rs.client.Entity.
06-Jan-2015 21:13:54 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet TestService threw exception
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=text/plain, type=class javax.ws.rs.client.Entity, genericType=class javax.ws.rs.client.Entity.
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:247)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1154)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:571)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:378)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:368)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:262)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:319)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:219)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
BEARBEITEN
Den gleichen Fehler (für application/json) ocurs nun habe ich annotiert eine Klasse mit @XmlRootElement
und versuchen Sie es zurückgeben in einer Methode, die je das Trikot docs:
@GET
@Produces(MediaType.APPLICATION_JSON)
public Foo sampleFoo() {
Foo foo = new Foo();
return foo;
}
Wo Foo
versehen mit @XmlRootElement
.
Ich habe auch jersey-media-json-jackson als Abhängigkeit, die ich sehen kann, enthält eine explizite JSONJaxb Anbieter. Jedoch, es scheint nicht aufgenommen zu werden, irgendwie.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ersten Ausgabe:
javax.ws.rs.client.Person
ist eine client-side-Klasse. Die JAX-RS Spezifikation sagt nichts über seine Verwendung auf der server-Seite. Aber ich kann bestätigen, mit vielen verschiedenen tests, dass das Ergebnis ähnlich sein wird, was Sie sehen, (mit Jersey zumindest). Mit Resteasy, es wird nur senden, dieEntity.toString()
Da diese nicht für die Arbeit entweder Resteasy oder Jersey, ich will nicht sagen, dass es ein bug ist, aber möglich ist ein Fehler in der Jersey Dokumentation, die exampled it-Nutzung wie folgt:
Den oben genannten Fehler für mich auch. Aber Sie sind nicht falsch ist zu sagen
als Sie sind. Um dein Beispiel funktioniert, ändern Sie einfach die
Entity.text("someContent")
einfach"someContent"
Und nur der Vollständigkeit halber, client-Seite Verwendung könnte so Aussehen
die funktioniert Prima.
Zweite Frage:
Bis (ich glaube) Jersey 2.9, die
jersey-media-json-jackson
Modul ist nicht automatisch konfiguriert. Also mit 2,6, legen wir die Konfiguration entweder durch Paket-Scannen in derweb.xml
oder in derApplication
Unterklasse. So oder so, eineweb.xml
erforderlich ist. Wie gesagt hier in Bezug auf eine 2.x-servlet-Umgebung, die von Tomcat 6 ist.So zu Scannen, für die JSON-provider-Klassen, sollten Sie das Paket in der
jersey.config.server.provider.packages
init-param. Ein Beispiel web.xml wäre so etwas wie diesSind Sie auch erlaubt die Verwendung einer
Application
Unterklasse (dieResourceConfig
reicht aus). Wir müssen nur geben Sie es in dieweb.xml
. Eine Beispielkonfiguration könnte so etwas wieHinweis: All dies wurde getestet, gegen Ihres gleichen Umgebung, neben der Nutzung von Eclipse. Ich bin mit Netbeans, aber es sollte keinen Unterschied machen. Auch die nur Maven-Abhängigkeiten, die ich brauchte, waren
Auf einer anderen Anmerkung, zur Vereinfachung der Entwicklung, die ich gerade erstellt eine einfache Maven-archetype-mit den folgenden Koordinaten
Können Sie auch sehen Erstellen Sie ein Neues Projekt von Maven Archetype
Application
Klasse höher. Ich vermisste die Tatsache, dassEntity
wurde ein client-Paket Klasse. Es bekommen jetzt alle, aber noch scheint ein wenig seltsam und verwirrend für den Anfang.Soweit die text/plain-format, funktioniert das?
Für die JSON-Ausgabe habe ich diese Abhängigkeiten
sowie eine jaxb-Implementierung. Jeder wird das tun, ich benutze
Ich auch definieren ein Objekt-mapper-Anbieter, aber ich bin mir nicht 100% sicher, dass es erforderlich ist (es sei denn, Sie anpassen möchten):
Außerdem denke ich, musst du dich registrieren die Jackson-feature:
Sollte ich beachten Sie, dass dieser ist so konfiguriert, dass alle mit Jersey 2.11.
jackson-databind
Artefakt verfügbar ist. Ich sollte nicht denken, das jaxb impl Abhängigkeit erforderlich ist, wie Jackson sich selbst stellt, die. Dieser behebt nicht mein problem, denn ich verwende Jersey 2.6 zu JDK 6 kompatibel.In meinem Fall, ich habe die jersey-media-json-jackson-Abhängigkeit. Es funktionierte für mich.