За последние пару дней я снова познакомился со своим хорошим другом Джерси, и когда я начал подниматься и бегать, мне напомнили, что вещи, которые казались легкими в то время, не так просты, когда начинали с нуля.
В конце концов я остановился на использовании Солнечный Глисона «s Д4-минимальное хранилище , какие провода до Джерси с Джексоном, Guice и молы , которые , казалось , как хорошее место для начала.
Я предпочитаю создавать объекты JSON явно, а не настраивать автоматическое сопоставление, поэтому первым делом я изменил JacksonResource, чтобы у него была конечная точка, которая возвращала созданный вручную объект JSON:
@Path("/jackson") public class JacksonResource { @GET @Produces( { MediaType.APPLICATION_JSON }) @Path("/awesome/{who}") public Response sayOtherGreeting(@PathParam("who") String name) { ObjectNode result = JsonNodeFactory.instance.objectNode(); result.put("name", name); return Response.ok().entity(result).build(); } }
Когда я попытался поразить это в браузере, я получил следующее исключение:
SEVERE: The registered message body writers compatible with the MIME media type are: application/json -> com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App */* -> com.sun.jersey.core.impl.provider.entity.FormProvider com.sun.jersey.server.impl.template.ViewableMessageBodyWriter com.sun.jersey.core.impl.provider.entity.StringProvider com.sun.jersey.core.impl.provider.entity.ByteArrayProvider com.sun.jersey.core.impl.provider.entity.FileProvider com.sun.jersey.core.impl.provider.entity.InputStreamProvider com.sun.jersey.core.impl.provider.entity.DataSourceProvider com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General com.sun.jersey.core.impl.provider.entity.ReaderProvider com.sun.jersey.core.impl.provider.entity.DocumentProvider com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General com.sun.jersey.json.impl.provider.entity.JSONWithPaddingProvider com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy Jul 21, 2013 11:11:17 AM com.sun.jersey.spi.container.ContainerResponse logException SEVERE: Mapped exception to response: 500 (Internal Server Error) javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class org.codehaus.jackson.node.ObjectNode, and Java type class org.codehaus.jackson.node.ObjectNode, and MIME media type application/json was not found at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1451) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263) at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178) at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91) at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62) at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118) at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1338) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:484) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111) at org.eclipse.jetty.server.Server.handle(Server.java:350) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454) at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:890) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:944) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:606) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538) at java.lang.Thread.run(Thread.java:722) Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class org.codehaus.jackson.node.ObjectNode, and Java type class org.codehaus.jackson.node.ObjectNode, and MIME media type application/json was not found ... 35 more
Это та же самая проблема, о которой я писал в прошлом году в отношении Клиента Джерси .
Это заняло у меня некоторое время, но в конце концов я нашел решение проблемы, скрытой примерно на полпути вниз по посту StackOverflow за похожее исключение .
Нам нужно добавить следующее свойство в нашу конфигурацию Джерси:
Map<String, Object> config = new HashMap<String, Object>(); config.put("com.sun.jersey.api.json.POJOMappingFeature", true);
Если мы отредактируем SampleConfig из шаблона, он теперь будет выглядеть так:
public class SampleConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new ServletModule() { @Override protected void configureServlets() { /* bind the REST resources */ bind(BenchResource.class); bind(SampleResource.class); bind(JacksonResource.class); /* bind jackson converters for JAXB/JSON serialization */ bind(MessageBodyReader.class).to(JacksonJsonProvider.class); bind(MessageBodyWriter.class).to(JacksonJsonProvider.class); Map<String, String> initParams = new HashMap<String, String>(); initParams.put("com.sun.jersey.config.feature.Trace", "true"); initParams.put("com.sun.jersey.api.json.POJOMappingFeature", "true"); serve("*").with( GuiceContainer.class, initParams); } }); } }
Если мы нажмем «/ jackson / awesome / mark», теперь он вернет JSON, как и ожидалось:
$ curl http://localhost:8080/jackson/awesome/mark -w "\n" {"name":"mark"}