Ticket #1082 (closed Enhancement: fixed)

Opened 4 years ago

Last modified 4 years ago

set cache-control header on certain jersey resources via annotation and resourcefilter

Reported by: Malte Owned by: Malte
Priority: Major Milestone: Release 4.8.9
Component: DeepaMehta Standard Distribution Version: 4.8.8
Keywords: Cc: jri, dgf, JuergeN
Complexity: 3 Area:
Module:

Description

As for IE10, IE11 and Edge Browsers all response to AJAX GET Requests seem to get cached aggressively. This effectively de-functions my single page app in those browsers completely and leads to duplicate tags and multiple user entries. Controlling the browsers caching behaviour from server side suddenly seems urgent and as the best option. I would appreciate any help and I would favor the 2nd solution.

  1. Option
        @GET
        @Path("/my/json")
        @Produces(MediaType.APPLICATION_JSON)
        @Override
        public Response getUsersAngebotsinfoResponse() {
            Response.ResponseBuilder response = null;
            List<Topic> all = getUsersAngebotsinfoTopics();
            response = Response.ok(sortTopicsDescByModificationDate(all));
            response.header("Cache-Control", "no-cache, no-store, must-revalidate");
            response.header("Pragma", "no-cache");
            response.header("Expires", 0);
            return response.build();
        }
    

But that leads to the following error message but is it really necessary for me to implement a MessageBodyWriter? for a standard Java List?

Aug 08, 2017 11:13:30 AM de.deepamehta.core.util.UniversalExceptionMapper logException
SCHWERWIEGEND: Request "GET /angebote/my/json" failed. Responding with 500 (Internal Server Error). The original exception/error is:
com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type class java.util.ArrayList, 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:1448)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350)
	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:339)
	at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:300)
	at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76)
	at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49)
	at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:229)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
	at org.eclipse.jetty.server.Server.handle(Server.java:370)
	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
	at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
	at java.lang.Thread.run(Thread.java:748)
  1. Option:

See https://stackoverflow.com/questions/10934316/jersey-default-cache-control-to-no-cache and http://alex.nederlof.com/blog/2013/07/28/caching-using-annotations-with-jersey/

Question: Can I register my own jersey ResourceFilterFactory in a plugin?

  1. Option: I could use POST requests as a quick-hack instead to solve my problem in time.

I would appreciate any help & thanks for your support!

Change History

comment:1 Changed 4 years ago by jri

Try a DM ServiceResponseFilterListener. This way you can interfere with every Jersey request, after the resource method is executed, but before the response is sent. You can use it in particular to set response headers.

import de.deepamehta.core.service.event.ServiceResponseFilterListener;
import com.sun.jersey.spi.container.ContainerResponse;
import javax.ws.rs.core.MultivaluedMap;

class MyPlugin implements ServiceResponseFilterListener {

    @Override
    public void serviceResponseFilter(ContainerResponse response) {
        MultivaluedMap headers = response.getHttpHeaders();
        headers.putSingle("Cache-Control", "max-age=0");
    }
}

Consider inspecting the response (e.g. response.getEntity()) or the request (response.getContainerRequest()) if you want set headers conditionally.

See the "DM4 Caching" plugin as an example.

Last edited 4 years ago by jri (previous) (diff)

comment:2 Changed 4 years ago by jri

Can I register my own jersey ResourceFilterFactory? in a plugin?

No, at the moment unfortunately DM does not support this.

comment:3 Changed 4 years ago by jri

Can this ticket be closed?

comment:4 Changed 4 years ago by Malte

  • Status changed from new to closed
  • Resolution set to fixed

Yes, implementing a ServiceResponseFilterListener? did the trick for me.
Thanks for your support.

Note: See TracTickets for help on using tickets.