Hoe stel ik de tekenset in met JAX-RS?

Hoe kan ik de tekenset instellen met JAX-RS? Ik heb @Produces("text/html; charset=UTF-8")geprobeerd, maar dat werd genegeerd en alleen text/htmlwerd verzonden met de HTTP-header. Ik wil de tekenset binnen een MessageBodyWriter instellen, maar ik wil het mediatype niet extraheren door de @Produces-annotatie zelf te analyseren via reflectie.


Antwoord 1, autoriteit 100%

Zoals Daemon in een opmerking aangaf, ondersteunen de nieuwste versies van JAX-RS (inclusief de stabiele versie van september 2012) nu doende @Producessyntaxis. U kunt dus gewoon het volgende gebruiken:

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

Antwoord 2, autoriteit 24%

Gewoon om het up-to-date te houden. Ik weet niet zeker of dit in oudere versies van Jersey werd ondersteund, maar als je beslist om de ResponseBuilder.header(…)-methode te gebruiken, kun je de MediaType-methode withCharset()gebruiken. Zoals dit:

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

Antwoord 3, autoriteit 21%

Het is ook mogelijk om de methode ResponseBuilder.header(…) te gebruiken om het inhoudstype met de tekenset in te stellen. Zie hieronder voor een codevoorbeeld (met 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();

Antwoord 4, autoriteit 14%

Als u dit op een JAX-RS-implementatieneutrale manier wilt doen, kunt u wellicht het Content-Type in de MessageBodyWriter resetten. Iets als:

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

Als je naast UTF-8 per bronmethode verschillende tekensets hebt, wil je misschien een aangepaste annotatie maken en deze aan elke bronmethode toevoegen. Probeer dan de annotaties parameter te gebruiken in de writeTo() methode.

Ter info: Apache Winkondersteunt het gebruik van charset en andere attributen op mediatypes. Ik hoop dat toekomstige JAX-RS-specificaties dit gemakkelijker maken.


Antwoord 5

Eerste instelling @Producesannotatie op uw resource class-methoden.

Vervolgens in MessageBodyWritervan uw geretourneerde type, kunt u dit doen in de writeTo()methode:

response.setContentType(mediaType.toString);

Opmerking: u kunt responsein uw writerinjecteren door:

@Context
protected HttpServletResponse response;

Antwoord 6

Wat ik doe is om een ​​instantie van het servlet-responsobject te krijgen:

protected @Context HttpServletResponse response;

En stel vervolgens de tekencodering in op utf-8:

response.setCharacterEncoding("utf-8");

Dat werkt voor mij.


Antwoord 7

Als u RESTEasy gebruikt, kunt u een Inteceptor registreren:

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

Opmerking: als u handmatig een @Produces instelt, overschrijft deze het ContentType dat door deze interceptor is ingesteld. Als u dat doet, stelt u de tekenset in @Produces

Other episodes