2010-08-07 12 views
46

¿Cómo puedo configurar el juego de caracteres con JAX-RS? Intenté @Produces("text/html; charset=UTF-8") pero se ignoró y solo se envió text/html con el encabezado HTTP. Quiero configurar el juego de caracteres dentro de MessageBodyWriter, pero no quiero extraer el tipo de medio analizando la anotación @Produces a través de la reflexión por mí mismo.¿Cómo configurar el juego de caracteres con JAX-RS?

+11

'@Produces (" text/html; charset = UTF-8 ")' funciona con las versiones actuales de la implementación de referencia Jersey. – deamon

+1

También puede asegurarse de que esto ocurra en todas partes para todas las anotaciones @Produces ("text/html") utilizando la técnica [descrita aquí en una pregunta SO similar] (http://stackoverflow.com/a/23479647/26510). –

Respuesta

60

Como Daemon señaló en un comentario, las últimas versiones de JAX-RS (incluyendo la versión estable de septiembre de 2012) ahora hacen soporte la sintaxis @Produces. De modo que puede usar:

@Produces("text/html; charset=UTF-8") 
+4

@Drewch ¿Lo admite JAX-RS 1.1? Parece que no puede encontrar cuándo salió JAX-RS. Intenté '@Produces (MediaType.APPLICATION_JSON +"; charset = UTF-16 ")', pero eso no funcionó. – Luke

+3

@Produces ("text/html; charset = UTF-8") no funcionó en Jersey 2.13. Tenía el mismo problema descrito por @deamon. –

+1

esto no funciona por alguna versión de Jersey es utilizado por Dropwizard 0.9.2 –

9

Si desea hacer esto en una implementación de JAX-RS de forma neutral, es posible que pueda restablecer Content-Type en MessageBodyWriter. Algo así como:

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"); 
} 

Si tiene diferentes conjuntos de caracteres UTF-8, además de por el método de los recursos, es posible que desee crear una anotación personalizado y añadirlo a cada método de recursos. Luego, intente usar el parámetro de anotaciones en el método writeTo().

Just FYI, Apache Wink admite el uso de juego de caracteres y otros atributos en tipos de medios. Espero que las futuras revisiones de las especificaciones de JAX-RS lo hagan más fácil.

+0

Esto funcionó para mí, la respuesta aceptada no funcionó para mí. –

15

También es posible utilizar el método ResponseBuilder.header (...) para establecer el tipo de contenido con el juego de caracteres. Vea a continuación un ejemplo de código (usando 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(); 
+3

no es necesario configurarlo a través del encabezado, también existe el método 'type()': 'Response.status (Response.Status.BAR_REQUEST) .entity (" La requête n'est pas correcte. \ N ... ") .type (MediaType.TEXT_PLAIN + "; charset = ISO-8859-15"). build(); ' –

9

Solo para mantenerlo actualizado. No estoy seguro de si esto era compatible con las versiones anteriores de Jersey, pero definitivamente si decide utilizar el método ResponseBuilder.header (...) puede usar el método MediaType con Charset(). De esta manera:

return Response.status(Status.OK) 
     .entity(result) 
     .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_TYPE.withCharset("utf-8")) 
     .build()); 
+2

Aún más corto (y con un mejor tipo de seguridad): use 'javax.ws.rs.core.Response.ResponseBuilder.type (MediaType)' en lugar de 'javax.ws.rs.core.Response.ResponseBuilder.header (HttpHeaders.CONTENT_TYPE , Object) ' – slartidan

0

Primera configuración @Produces anotación en sus métodos de clase de recursos.

Luego, en MessageBodyWriter de su tipo devuelto, se puede hacer esto en writeTo() método:

response.setContentType(mediaType.toString); 

Observación: Usted puede inyectar response en su writer por:

@Context 
protected HttpServletResponse response; 
1

Lo que hago es a obtener una instancia del objeto de respuesta servlet:

protected @Context HttpServletResponse response; 

y después fijar la codificación de caracteres UTF-8:

response.setCharacterEncoding("utf-8"); 

que funciona para mí.

+0

Esa es la misma respuesta que [A Kra's] (http://stackoverflow.com/a/39097649/1314743). Por favor, solo agregue una respuesta si tiene algo nuevo para contribuir. –

+0

No, no es lo mismo. Giannis usa 'setCharacterEncoding', mientras que To Kra usa un método indirecto es writoTo() de MessageBodyWriter. Giannis es mucho más simple. –

0

Si se utiliza RESTEasy se puede registrar una 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; 
    } 
} 

Nota: Si establece manualmente una @Produces anula las ContentType creados por este interceptor.Si lo hace, configure el juego de caracteres en @Produces

Cuestiones relacionadas