2010-08-07 15 views
46

Jak ustawić zestaw znaków za pomocą JAX-RS? Próbowałem już @Produces("text/html; charset=UTF-8"), ale zostało to zignorowane i wysłano tylko text/html z nagłówkiem HTTP. Chcę ustawić zestaw znaków w MessageBodyWriter, ale nie chcę wyodrębniać typ mediów przez analizowanie adnotacji @Produces przez odbicie przez siebie.Jak ustawić zestaw znaków za pomocą JAX-RS?

+11

'@Produces ("text/html; charset = UTF-8")' współpracuje z aktualnymi wersjami implementacji referencyjnej Jersey. – deamon

+1

Można również zapewnić to się dzieje wszędzie dla wszystkich @Produces („text/html”) adnotacji wykorzystujące technikę opisaną tutaj [na podobne pytanie SO] (http://stackoverflow.com/a/23479647/26510). –

Odpowiedz

60

jako demon wskazał w komentarzu, najnowsze wersje JAX-RS (w tym stabilnej wersji z września 2012) teraz zrobić wsparcie składni @Produces. Możesz więc użyć:

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

@Drewch Czy JAX-RS 1.1 obsługuje to? Nie można znaleźć, kiedy JAX-RS wyszedł. Próbowałem '@Produces (MediaType.APPLICATION_JSON +", charset = UTF-16 ")', ale to nie zadziałało. – Luke

+3

@Produces ("text/html; charset = UTF-8") nie działa dla mnie w Jersey 2.13. Miał ten sam problem opisany przez @ devon. –

+1

to nie działa dla jakiejkolwiek wersji Jersey jest używana przez Dropwizard 0.9.2 –

9

Jeśli chcesz to zrobić w sposób neutralny w implementacji JAX-RS, możesz być w stanie zresetować Content-Type w MessageBodyWriter. Coś jak:

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

Jeśli masz różne zestawy znaków oprócz UTF-8 za metody zasobów, może chcesz utworzyć niestandardową adnotacji i dodać go do każdej metody zasobów. Następnie spróbuj użyć parametru adnotacji w metodzie writeTo().

Po prostu FYI, Apache Wink obsługuje użycie zestawu znaków i innych atrybutów na typach mediów. Mam nadzieję, że przyszłe wersje specyfikacji JAX-RS ułatwią to.

+0

To zadziałało dla mnie, przyjęta odpowiedź nie zadziałała dla mnie. –

15

Istnieje również możliwość użycia metody ResponseBuilder.header (...) do ustawienia typu zawartości za pomocą zestawu znaków. Zobacz poniżej przykład kodu (używając 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

nie musisz ustawiać go za pomocą nagłówka, istnieje również metoda '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

Tylko po to, aby być na bieżąco. Nie wiem, czy było to obsługiwane w starszych wersjach Jersey, ale zdecydowanie jeśli zdecydujesz się użyć metody ResponseBuilder.header (...), możesz użyć metody MediaType zCharset(). W ten sposób:

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

Nawet krótszy (i lepszego bezpieczeństwa typ): użyj 'javax.ws.rs.core.Response.ResponseBuilder.type (MediaType)' zamiast 'javax.ws.rs.core.Response.ResponseBuilder.header (HttpHeaders.CONTENT_TYPE , Object) ' – slartidan

0

Pierwsza instalacja @Produces adnotacja na temat metod klasy zasobów.

Następnie w MessageBodyWriter swojej zwracanego typu, można to zrobić w writeTo() metody:

response.setContentType(mediaType.toString); 

uwaga: można wstrzykiwać response w swojej writer przez:

@Context 
protected HttpServletResponse response; 
1

Co mogę zrobić, to uzyskać wystąpienie obiektu odpowiedzi serwletu:

protected @Context HttpServletResponse response; 

a następnie ustawić kodowanie znaków UTF-8

response.setCharacterEncoding("utf-8"); 

który pracuje dla mnie.

+0

To jest ta sama odpowiedź co [To Kra's] (http://stackoverflow.com/a/39097649/1314743). Dodaj tylko odpowiedź, jeśli masz coś nowego do dodania. –

+0

Nie, to nie to samo. Giannis używa "setCharacterEncoding", podczas gdy To Kra używa metody ronda to writoTo() z MessageBodyWriter. Giannis jest znacznie prostszy. –

0

przypadku korzystania RESTEasy można zarejestrować 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; 
    } 
} 

Uwaga: Jeśli ręcznie ustawić do @Produces to nadpisuje ContentType utworzone przez to przechwytujących.Jeśli to zrobisz, ustawić kodowanie znaków w @Produces

Powiązane problemy