web-dev-qa-db-fra.com

Comment régler le jeu de caractères avec JAX-RS?

Comment puis-je régler le jeu de caractères avec JAX-RS? J'ai essayé @Produces("text/html; charset=UTF-8") mais cela a été ignoré et seulement text/html a été envoyé avec l'en-tête HTTP. Je veux définir le jeu de caractères dans un MessageBodyWriter, mais je ne veux pas extraire le type de média en analysant l'annotation @Produces via la réflexion par moi-même.

50
deamon

Comme Daemon l'a souligné dans un commentaire, les dernières versions de JAX-RS (y compris la version stable en septembre 2012) --- font supporte le @Produces syntaxe. Vous pouvez donc simplement utiliser:

@Produces("text/html; charset=UTF-8")
67
Adrian Petrescu

Il est également possible d'utiliser la méthode ResponseBuilder.header (...) pour définir le type de contenu avec le jeu de caractères. Voir ci-dessous pour un exemple de code (en utilisant 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();
15
SMougenot

Juste pour le garder à jour. Je ne sais pas si cela était pris en charge dans les anciennes versions de Jersey, mais certainement si vous décidez d'utiliser la méthode ResponseBuilder.header (...), vous pouvez utiliser la méthode MediaType withCharset (). Comme ça:

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

Si vous souhaitez le faire de manière neutre pour l'implémentation JAX-RS, vous pourrez peut-être réinitialiser le Content-Type dans MessageBodyWriter. Quelque chose comme:

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 vous disposez de jeux de caractères différents en plus de UTF-8 par méthode de ressource, vous souhaiterez peut-être créer une annotation personnalisée et l'ajouter à chaque méthode de ressource. Ensuite, essayez d'utiliser le paramètre annotations dans la méthode writeTo ().

Juste pour info, Apache Wink prend en charge l'utilisation de charset et d'autres attributs sur les types de supports. J'espère que les futures révisions des spécifications JAX-RS rendront cela plus facile.

10
Bryant Luk

Configurez d'abord l'annotation @Produces Sur vos méthodes de classe de ressources.

Ensuite, dans MessageBodyWriter de votre type retourné, vous pouvez le faire dans la méthode writeTo():

response.setContentType(mediaType.toString);

Remarque: Vous pouvez injecter response dans votre writer en:

@Context
protected HttpServletResponse response;
1
To Kra

Ce que je fais est d'obtenir une instance de l'objet de réponse de servlet:

protected @Context HttpServletResponse response;

Et puis définissez le codage des caractères sur utf-8:

response.setCharacterEncoding("utf-8");

Ça marche pour moi.

1
Giannis

Si vous utilisez RESTEasy, vous pouvez enregistrer un 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;
    }
}

Remarque: Si vous définissez manuellement un @Produces, il remplace le ContentType défini par cet intercepteur. Si vous faites cela, définissez le jeu de caractères dans @Produces

1
lujop