2010-08-07 21 views
46

Come posso impostare il set di caratteri con JAX-RS? Ho provato @Produces("text/html; charset=UTF-8") ma quello è stato ignorato e solo text/html è stato inviato con l'intestazione HTTP. Voglio impostare il set di caratteri all'interno di un MessageBodyWriter, ma non voglio estrarre il tipo di supporto analizzando l'annotazione @Produces tramite riflessione da solo.Come impostare il set di caratteri con JAX-RS?

+11

'@Produces (" text/html; charset = UTF-8 ")' funziona con le versioni correnti della maglia di implementazione di riferimento. – deamon

+1

Puoi anche assicurarti che ciò avvenga ovunque per tutte le annotazioni @Produces ("text/html") utilizzando la tecnica [descritta qui in una domanda SO simile] (http://stackoverflow.com/a/23479647/26510). –

risposta

60

come demone ha sottolineato in un commento, le ultime versioni di JAX-RS (compresa la versione stabile di Settembre 2012) ora fanno supporto alla sintassi @Produces. Quindi puoi semplicemente usare:

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

@Drewch JAX-RS 1.1 supporta questo? Non riesco a trovare quando JAX-RS è uscito. Ho provato '@Produces (MediaType.APPLICATION_JSON +"; charset = UTF-16 ")', ma non ha funzionato. – Luke

+3

@Produces ("text/html; charset = UTF-8") non ha funzionato per me in Jersey 2.13. Aveva lo stesso problema descritto da @deamon. –

+1

questo non funziona per qualsiasi versione di Jersey è utilizzato da Dropwizard 0.9.2 –

9

Se si vuole fare questo in modo neutrale JAX-RS realizzazione, si può essere in grado di ripristinare il Content-Type nel MessageBodyWriter. Qualcosa di simile:

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

Se si dispone di diversi set di caratteri UTF-8, oltre al metodo di risorse, è possibile creare un'annotazione personalizzato e aggiungerlo a ciascun metodo risorsa. Quindi, provare a utilizzare il parametro annotazioni nel metodo writeTo().

Just FYI, Apache Wink supporta l'utilizzo di charset e altri attributi sui tipi di media. Spero che le future revisioni delle specifiche JAX-RS lo rendano più semplice.

+0

Questo ha funzionato per me, la risposta accettata non ha funzionato per me. –

15

È anche possibile utilizzare il metodo ResponseBuilder.header (...) per impostare il tipo di contenuto con il set di caratteri. Vedi sotto per un esempio di codice (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

non è necessario impostarlo tramite intestazione, esiste anche il metodo '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 per tenerlo aggiornato. Non so se questo è stato sostenuto in vecchie versioni di Jersey, ma sicuramente se si decide di utilizzare il metodo ResponseBuilder.header (...) si possono usare MediaType metodo withCharset(). In questo modo:

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

ancora più breve (e con una migliore sicurezza di tipo): usare 'javax.ws.rs.core.Response.ResponseBuilder.type (MediaType)' invece di 'javax.ws.rs.core.Response.ResponseBuilder.header (HttpHeaders.CONTENT_TYPE , Object) – slartidan

0

Prima annotazione @Produces nei metodi della classe di risorsa.

Poi, nel MessageBodyWriter del tipo restituito, è possibile farlo in writeTo() metodo:

response.setContentType(mediaType.toString); 

Nota: È possibile iniettare response nel vostro writer da:

@Context 
protected HttpServletResponse response; 
1

Quello che faccio è per ottenere un'istanza dell'oggetto risposta della servlet:

protected @Context HttpServletResponse response; 

e quindi impostare la codifica dei caratteri UTF-8:

response.setCharacterEncoding("utf-8"); 

che funziona per me.

+0

Questa è la stessa risposta di [To Kra's] (http://stackoverflow.com/a/39097649/1314743). Per favore aggiungi una risposta solo se hai qualcosa di nuovo da contribuire. –

+0

No, non è lo stesso. Giannis usa 'setCharacterEncoding', mentre To Kra usa un metodo roundabout è writoTo() di MessageBodyWriter. Giannis è molto più semplice. –

0

Se si utilizza RESTEasy è possibile registrare 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; 
    } 
} 

Nota: Se si imposta manualmente un @Produces prevale il ContentType impostati dal intercettore.Se lo fai, imposta il set di caratteri in @Produces

Problemi correlati