Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

Rewrite GsonJsonProvider using the Jacskon Library?

Avatar

Level 8

I need to rewrite the GsonJsonProvider using the Jackson library. 

 

This is the original code:

@Component(immediate = true)
@Provider
public class GsonJsonProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object>, JaxRsComponent {
private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();

@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isApplicationJson(mediaType);
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isApplicationJson(mediaType);
}

@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) {
// To conform with readFrom specification, reader and entityStream is not closed
InputStreamReader reader = new InputStreamReader(entityStream, MessageUtils.getCharset(mediaType));
if (genericType == null) {
return gson.fromJson(reader, type);
} else {
return gson.fromJson(reader, genericType);
}
}

@Override
public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
// To conform with writeTo specification, writer and entityStream is not closed
OutputStreamWriter writer = new OutputStreamWriter(entityStream, MessageUtils.getCharset(mediaType));
if (genericType == null) {
gson.toJson(o, writer);
} else {
gson.toJson(o, genericType, writer);
}
writer.flush();
}

private boolean isApplicationJson(MediaType mediaType) {
return mediaType.equals(MediaType.APPLICATION_JSON_TYPE);
}
}

 

 

And this is my rewriten code that is not working:

@Component(immediate = true)
@Provider
public class JacksonJsonProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object> {

private ObjectMapper objectMapper;

public JacksonJsonProvider() {
objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
}

@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isApplicationJson(mediaType);
}

@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
InputStreamReader reader = new InputStreamReader(entityStream, MessageUtils.getCharset(mediaType));
if (genericType == null) {
return objectMapper.readValue(reader, type);
} else {
return objectMapper.readValue(reader, objectMapper.getTypeFactory().constructType(genericType));
}
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isApplicationJson(mediaType);
}

@Override
public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(entityStream, MessageUtils.getCharset(mediaType));
if (genericType == null) {
objectMapper.writeValue(writer, o);
} else {
objectMapper.writerFor(objectMapper.getTypeFactory().constructType(genericType)).writeValue(writer, o);
}
writer.flush();
}

private boolean isApplicationJson(MediaType mediaType) {
return mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE);
}
}

 When I do a POST request to upload data for an asset I get the following:

javax.servlet.ServletException: org.glassfish.jersey.server.internal.process.MappableException: java.io.IOException: Stream closed
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:432)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
    at io.wcm.caravan.jaxrs.publisher.impl.ServletContainerBridge.service(ServletContainerBridge.java:112)
    at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:126)
    at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:86)
    at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:308)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:149)
    at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:81)
    at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:131)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:149)
    at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:81)
    at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:73)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:149)
    at org.apache.felix.http.base.internal.dispatch.InvocationChain.doFilter(InvocationChain.java:81)
    at org.apache.felix.http.base.internal.dispatch.Dispatcher$1.doFilter(Dispatcher.java:152)
    at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager$2.doFilter(WhiteboardManager.java:1000)
    at com.adobe.granite.auth.oauth.impl.OAuthCallbackFilter.doFilter(OAuthCallbackFilter.java:69)
    at org.apache.felix.http.base.internal.handler.PreprocessorHandler.handle(PreprocessorHandler.java:137)
    at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager$2.doFilter(WhiteboardManager.java:1006)
    at com.adobe.granite.auth.ims.impl.IMSClusterExchangeTokenPreprocessor.doFilter(IMSClusterExchangeTokenPreprocessor.java:281)
    at org.apache.felix.http.base.internal.handler.PreprocessorHandler.handle(PreprocessorHandler.java:137)
    at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager$2.doFilter(WhiteboardManager.java:1006)
    at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:326)
    at org.apache.felix.http.base.internal.handler.PreprocessorHandler.handle(PreprocessorHandler.java:137)
    at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager$2.doFilter(WhiteboardManager.java:1006)
    at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:97)
    at org.apache.felix.http.base.internal.handler.PreprocessorHandler.handle(PreprocessorHandler.java:137)
    at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager$2.doFilter(WhiteboardManager.java:1006)
    at org.apache.felix.http.base.internal.whiteboard.WhiteboardManager.invokePreprocessors(WhiteboardManager.java:1010)
    at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:94)
    at org.apache.felix.http.base.internal.dispatch.DispatcherServlet.service(DispatcherServlet.java:49)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:554)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:516)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:137)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
    at java.base/java.lang.Thread.run(Thread.java:834)
2 Replies

Avatar

Community Advisor

Hello @anasustic - 

 

The issue seems to be related to a closed input stream.The InputStream is being closed somewhere before it's being read by the ObjectMapper. 

 

 

@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
                       MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
    try (InputStreamReader reader = new InputStreamReader(entityStream, MessageUtils.getCharset(mediaType))) {
        if (genericType == null) {
            return objectMapper.readValue(reader, type);
        } else {
            return objectMapper.readValue(reader, objectMapper.getTypeFactory().constructType(genericType));
        }
    }
}

 

 

 

 

 

Avatar

Level 8

Hi @Tanika02 

Thanks for your reply 

Can you suggest a remedy for my issue?

The original GsonJsonProvider.java is working flawlessly. The new JacksonJsonProvider that I rewrote is giving me errors. Everything else is the same.