Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events

Rewrite GsonJsonProvider using the Jacskon Library?

Avatar

Level 7

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 7

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.