title: Jersey ContextResolver GetContext() called only once
body: <p>I have the following <code>ContextResolver&lt;ObjectMapper&gt;</code> implementation, which based on the query params should return the corresponding JSON mapper (pretty/DateToUtc/Both):</p>
  
  <pre><code>import javax.ws.rs.Produces;
  import javax.ws.rs.core.Context;
  import javax.ws.rs.core.MediaType;
  import javax.ws.rs.core.MultivaluedMap;
  import javax.ws.rs.core.UriInfo;
  import javax.ws.rs.ext.ContextResolver;
  import javax.ws.rs.ext.Provider;
  
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.SerializationFeature;
  
  @Provider
  @Produces(MediaType.APPLICATION_JSON)
  public class JsonMapper implements ContextResolver&lt;ObjectMapper&gt; {
  
      private ObjectMapper prettyPrintObjectMapper;
      private ObjectMapper dateToUtcMapper;
      private ObjectMapper bothMapper;
      private UriInfo uriInfoContext;
  
      public JsonMapper(@Context UriInfo uriInfoContext) throws Exception {
          this.uriInfoContext = uriInfoContext;
  
          this.prettyPrintObjectMapper = new ObjectMapper();
          this.prettyPrintObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);
  
          this.dateToUtcMapper = new ObjectMapper();
          this.dateToUtcMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
  
          this.bothMapper = new ObjectMapper();
          this.bothMapper.enable(SerializationFeature.INDENT_OUTPUT);
          this.bothMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
      }
  
      @Override
      public ObjectMapper getContext(Class&lt;?&gt; objectType) {
          System.out.println("hi");
          try {
              MultivaluedMap&lt;String, String&gt; queryParameters = uriInfoContext.getQueryParameters();
              Boolean containsPretty = queryParameters.containsKey("pretty");
              Boolean containsDate   = queryParameters.containsKey("date_to_utc");
              Boolean containsBoth   = containsPretty &amp;&amp; containsDate;
  
              if (containsBoth) {
                  System.out.println("Returning containsBoth");
                  return bothMapper;
              }
  
              if (containsDate) {
                  System.out.println("Returning containsDate");
                  return dateToUtcMapper;
              }
  
              if (containsPretty) {
                  System.out.println("Returning pretty");
                  return prettyPrintObjectMapper;
              }
  
          } catch(Exception e) {
              // protect from invalid access to uriInfoContext.getQueryParameters()
          }
  
          System.out.println("Returning null");
          return null; // use default mapper
      }
  }
  </code></pre>
  
  <p>And the following Main Application:</p>
  
  <pre><code> private Server configureServer() {
          ObjectMapper mapper = new ObjectMapper();
  
          ResourceConfig resourceConfig = new ResourceConfig();
          resourceConfig.packages(Calculator.class.getPackage().getName());
          resourceConfig.property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
          // @ValidateOnExecution annotations on subclasses won't cause errors.
          resourceConfig.property(ServerProperties.BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK, true);
          resourceConfig.register(JacksonFeature.class);
          resourceConfig.register(JsonMapper.class);
          resourceConfig.register(AuthFilter.class);
          ServletContainer servletContainer = new ServletContainer(resourceConfig);
          ServletHolder sh = new ServletHolder(servletContainer);
          Server server = new Server(serverPort);
          ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
          context.setContextPath("/");
          context.addServlet(sh, "/*");
          server.setHandler(context);
          return server;
      }
  </code></pre>
  
  <p>However, <code>getContext()</code> function is only called once for the entire server lifetime, only on the first request. The whole idea of this class is to determine on runtime what is the mapper based on the url parameters. </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p><code>getContext()</code> is called once for each uri path. For example, <a href="http://server/path1?pretty=true" rel="nofollow">http://server/path1?pretty=true</a> will yield pretty output for all request to /path1, regardless of thier future pretty <code>queryParam</code>. A call to path2 will call getContext again, but not to future path2 calls. </p>
  
  <p><strong>UPDATE2</strong></p>
  
  <p>Well, it seems like the <code>GetContext</code> is called for each class once, and caches it for that specific class. This is why it expects a class as parameter. So it seems like @LouisF is right, and the objectMapper isn't suited for conditional serialization. However, the <code>ContainerResponseFilter</code> alternative is partially working, but not exposing ObjectMapper features, such as converting dates to UTC. So I'm quite puzzled right now on what is the most appropriate solution for conditional serialization.</p>
  
  <p><strong>SOLVED</strong></p>
  
  <p>With the help of @LoisF, I've managed to have conditional serialization, using <code>ContainerResponseFilter</code>. I havn't use <code>ContextResolver</code>. Below is the working example:</p>
  
  <pre><code>import java.io.IOException;
  
  import javax.ws.rs.container.ContainerRequestContext;
  import javax.ws.rs.container.ContainerResponseContext;
  import javax.ws.rs.container.ContainerResponseFilter;
  import javax.ws.rs.core.MultivaluedMap;
  import javax.ws.rs.ext.Provider;
  
  import com.fasterxml.jackson.annotation.JsonProperty;
  import com.fasterxml.jackson.core.JsonGenerator;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.ObjectWriter;
  import com.fasterxml.jackson.databind.SerializationFeature;
  import com.fasterxml.jackson.jaxrs.cfg.EndpointConfigBase;
  import com.fasterxml.jackson.jaxrs.cfg.ObjectWriterInjector;
  import com.fasterxml.jackson.jaxrs.cfg.ObjectWriterModifier;
  
  /**
   * Created by matt on 17/01/2016.
   */
  @Provider
  public class ResultTransformer implements ContainerResponseFilter {
  
  
      public static final String OUTPUT_FORMAT_HEADER = "X-Output-Format";
      public static final ObjectMapper MAPPER         = new ObjectMapper();
  
      public static class OutputFormat {
          Boolean pretty              = true;
          Boolean dateAsTimestamp     = false;
  
          public Boolean getPretty() {
              return pretty;
          }
  
          public void setPretty(Boolean pretty) {
              this.pretty = pretty;
          }
  
          @JsonProperty("date_as_timestamp")
          public Boolean getDateAsTimestamp() {
              return dateAsTimestamp;
          }
  
          public void setDateAsTimestamp(Boolean dateAsTimestamp) {
              this.dateAsTimestamp = dateAsTimestamp;
          }
      }
  
      @Override
      public void filter(ContainerRequestContext reqCtx, ContainerResponseContext respCtx) throws IOException {
  
          String outputFormatStr = reqCtx.getHeaderString(OUTPUT_FORMAT_HEADER);
          OutputFormat outputFormat;
          if (outputFormatStr == null) {
              outputFormat = new OutputFormat();
          } else {
              try {
                  outputFormat = MAPPER.readValue(outputFormatStr, OutputFormat.class);
                  ObjectWriterInjector.set(new IndentingModifier(outputFormat));
              } catch (Exception e) {
                  e.printStackTrace();
                  ObjectWriterInjector.set(new IndentingModifier(new OutputFormat()));
              }
          }
      }
  
      public static class IndentingModifier extends ObjectWriterModifier {
  
         private OutputFormat outputFormat;
  
          public IndentingModifier(OutputFormat outputFormat) {
              this.outputFormat = outputFormat;
  
          }
  
  
          @Override
          public ObjectWriter modify(EndpointConfigBase&lt;?&gt; endpointConfigBase, MultivaluedMap&lt;String, Object&gt; multivaluedMap, Object o, ObjectWriter objectWriter, JsonGenerator jsonGenerator) throws IOException {
              if(outputFormat.getPretty())      jsonGenerator.useDefaultPrettyPrinter();
              if (outputFormat.dateAsTimestamp)  {
                  objectWriter = objectWriter.with(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
              } else {
                  objectWriter = objectWriter.without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
              }
              return objectWriter;
          }
      }
  
  }
  </code></pre>