How to set the charset with JAX-RS?

后端 未结 7 1083
时光说笑
时光说笑 2020-12-08 09:30

How can I set the charset with JAX-RS? I\'ve tried @Produces(\"text/html; charset=UTF-8\") but that was ignored and only text/html was send with th

相关标签:
7条回答
  • 2020-12-08 09:46

    First setup @Produces annotation on your resource class methods.

    Then in MessageBodyWriter of your returned type, you can do this in writeTo() method:

    response.setContentType(mediaType.toString);
    

    Remark: You can inject response in your writer by:

    @Context
    protected HttpServletResponse response;
    
    0 讨论(0)
  • 2020-12-08 09:52

    If you want to do this in a JAX-RS implementation neutral way, you may be able to reset the Content-Type in the MessageBodyWriter. Something like:

    public void writeTo(Object obj,
                        Class<?> cls,
                        Type type,
                        Annotation[] annotations,
                        MediaType mt,
                        MultivaluedMap<String, Object> responseHttpHeaders,
                        OutputStream stream) throws IOException {
        responseHttpHeaders.putSingle(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE, mt.toString() + ";charset=UTF-8");
    }
    

    If you have different character sets besides UTF-8 per resource method, you may want to create a custom annotation and add it to each resource method. Then, try to use the annotations parameter in the writeTo() method.

    Just FYI, Apache Wink supports the usage of charset and other attributes on media types. I hope that future JAX-RS spec revisions makes this easier.

    0 讨论(0)
  • 2020-12-08 09:52

    If using RESTEasy you can register an Inteceptor:

    import org.jboss.resteasy.annotations.interception.ServerInterceptor;
    import org.jboss.resteasy.core.ResourceMethodInvoker;
    import org.jboss.resteasy.core.ServerResponse;
    import org.jboss.resteasy.spi.Failure;
    import org.jboss.resteasy.spi.HttpRequest;
    import org.jboss.resteasy.spi.interception.PreProcessInterceptor;
    import org.jboss.resteasy.plugins.providers.multipart.InputPart;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    @ServerInterceptor
    public class ContentTypeSetter implements PreProcessInterceptor {
        @Override
        public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker resourceMethodInvoker) throws Failure, WebApplicationException {
            request.setAttribute(InputPart.DEFAULT_CONTENT_TYPE_PROPERTY, "*/*; charset=UTF-8");
            return null;
        }
    }
    

    Note: If you manually set a @Produces it overrides the ContentType set by this interceptor. If you do that, set the charset in @Produces

    0 讨论(0)
  • 2020-12-08 10:00

    It is also possible to use ResponseBuilder.header(...) method to set the content type with the charset. See below for a code sample (using JAX-RS 1.1.1, CXF 2.3.1).

    final Response myResponse = Response.status(Response.Status.BAD_REQUEST)
        .entity("La requête n'est pas correcte.\n ...")
        .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN+"; charset=ISO-8859-15" )
        .build();
    
    0 讨论(0)
  • 2020-12-08 10:02

    As Daemon pointed out in a comment, the latest versions of JAX-RS (including the stable version as of September 2012) now do support the @Produces syntax. So you can just use:

    @Produces("text/html; charset=UTF-8")
    
    0 讨论(0)
  • 2020-12-08 10:04

    What I do is to get an instance of the servlet response object:

    protected @Context HttpServletResponse response;
    

    And then set the character encoding to utf-8:

    response.setCharacterEncoding("utf-8");
    

    That works for me.

    0 讨论(0)
提交回复
热议问题