简体   繁体   中英

Jersey - Set REST response encoding at runtime

I am wondering if it's possible, using Jersey API, to set the response charset at runtime.

If I set it like this:

public class MyRESTClass
{
   private static final String encoding  = "UTF-8";

   @GET
   @Produces(MediaType.APPLICATION_JSON + ";charset=" + enconding)
   public String Call(@Context final HttpServletRequest servletReq, @QueryParam("somePar") String somePar)
   {
      ...
   }
}

...it's OK

But if I try and set it like this:

public class MyRESTClass
{
   private static final String encoding  = getEncoding();

   public static final String getEncoding()
   {
      final String encoding = "UTF-8";
      return encoding;
   }

   @GET
   @Produces(MediaType.APPLICATION_JSON + ";charset=" + enconding)
   public String Call(@Context final HttpServletRequest servletReq, @QueryParam("somePar") String somePar)
   {
      ...
   }
}

I get compile error:

The value for annotation attribute Produces.value must be a constant expression

I need this so I can set my application's REST encoding using a configuration file.

Is there another way?

Thanks

I think the way to do this is by extending Jersey's ResourceConfig and do a programmatic resource configuration.

String encoding = Config.get("encoding"); // get encoding from config file
String mediaType = MediaType.APPLICATION_JSON + ";charset=" + encoding;
final Resource.Builder getRes = Resource.builder().path("resourcePath");

final ResourceMethod.Builder get = getRes.addMethod("GET");
get.produces(mediaType).handledBy(new Inflector<ContainerRequestContext, String>() {
    public final String apply(ContainerRequestContext ctx) {
       // implement that Call method here
    }
});
registerResources(getRes.build());

Then you should register that custom resource in your web.xml by setting an initParameter for your Jersey servlet:

<filter>
    <filter-name>MyApplication</servlet-name>
    <filter-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>org.foo.MyApplication</param-value>
    </init-param>
<filter>

See: https://jersey.java.net/documentation/latest/user-guide.html

Haven't tried it but you could probably put in a response filter that added the specific encoding.

The class would look something like this (hand-typed so could be errors):

public class ContentTypeEncodingFilter implements ContainerResponseFilter
{
  private static final String CONTENTTYPEHEADER = "Content-Type";
  private final String encoding;

  public ContentTypeEncodingFilter(final String encoding)
  {
    this.encoding = encoding;
  }

  @Override
  public ContainerResponse filter(final ContainerRequest request, final ContainerResponse response)
  {
    final MultivaluedMap<String, Object> headers = response.getHttpHeaders();
    final String type = (String)headers.getFirst(CONTENTTYPEHEADER);
    if (type != null)
    {
      headers.remove(CONTENTTYPEHEADER);
      headers.add(CONTENTTYPEHEADER, type + ";charset=" + this.encoding);
    }
    return response;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM