2010-08-07 6 views
46

Как установить кодировку с помощью JAX-RS? Я пробовал @Produces("text/html; charset=UTF-8"), но это было проигнорировано, и только text/html был отправлен с HTTP-заголовком. Я хочу установить кодировку в MessageBodyWriter, но не хочу извлекать тип носителя, анализируя аннотацию @Produces посредством отражения от себя.Как установить кодировку с помощью JAX-RS?

+11

'@Produces (" text/html; charset = UTF-8 ")' работает с текущими версиями эталонной реализации Jersey. – deamon

+1

Вы также можете убедиться, что это происходит повсюду для всех аннотаций @Produces («text/html»), используя технику [описанную здесь по аналогичному вопросу SO] (http://stackoverflow.com/a/23479647/26510). –

ответ

60

Как Daemon отметил в комментарии, последние версии JAX-RS (в том числе стабильной версии по состоянию на сентябрь 2012 года) в настоящее время сделать поддерживает синтаксис @Produces. Таким образом, вы можете просто использовать:

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

@Drewch Поддерживает ли JAX-RS 1.1 это? Кажется, не может показаться, когда вышел JAX-RS. Я попробовал '@Produces (MediaType.APPLICATION_JSON +"; charset = UTF-16 ")', но это не сработало. – Luke

+3

@Produces ("text/html; charset = UTF-8") не работает для меня в Джерси 2.13. Была та же проблема, что и @deamon. –

+1

это не работает для любой версии Джерси, используемой Dropwizard 0.9.2 –

9

Если вы хотите сделать это в нейтральном режиме реализации JAX-RS, вы можете сбросить Content-Type в MessageBodyWriter. Что-то вроде:

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

Если у вас есть различные наборы символов, кроме UTF-8 в методе ресурса вы можете создать пользовательские аннотации и добавить его к каждому методу ресурсов. Затем попробуйте использовать параметр аннотации в методе writeTo().

Just FYI, Apache Wink поддерживает использование кодировки и других атрибутов на носителях. Надеюсь, что будущие спецификации спецификации JAX-RS облегчат это.

+0

Это сработало для меня, принятый ответ не сработал для меня. –

15

Также можно использовать метод ResponseBuilder.header (...) для установки типа содержимого с помощью кодировки. Ниже приведен пример кода (с использованием 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

вам не нужно устанавливать его через заголовок, также существует метод '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

Просто чтобы он не обновлялся. Не уверен, поддерживалось ли это в более старых версиях Джерси, но определенно, если вы решите использовать метод ResponseBuilder.header (...), вы можете использовать метод MediaType withCharset(). Как это:

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

Даже короче (и с лучшей безопасностью типа): используйте 'javax.ws.rs.core.Response.ResponseBuilder.type (MediaType)' вместо 'javax.ws.rs.core.Response.ResponseBuilder.header (HttpHeaders.CONTENT_TYPE , Object) ' – slartidan

0

Первых установка @Produces аннотацию на ваших методах класса ресурсов.

Тогда в MessageBodyWriter вашего возвращенного типа, вы можете сделать это в writeTo() метод:

response.setContentType(mediaType.toString); 

Примечание: Вы можете вводить response в вашем writer по:

@Context 
protected HttpServletResponse response; 
1

Что я делаю, получить экземпляр объекта ответа сервлета:

protected @Context HttpServletResponse response; 

А затем установить кодировку на UTF-8:

response.setCharacterEncoding("utf-8"); 

Это работает для меня.

+0

Это тот же ответ, что и [К кра] (http://stackoverflow.com/a/39097649/1314743). Пожалуйста, добавьте только ответ, если у вас есть что-то новое, чтобы внести свой вклад. –

+0

Нет, это не то же самое. Giannis использует 'setCharacterEncoding', тогда как для Kra используется метод круговой обмотки - writoTo() MessageBodyWriter. Джаннис намного проще. –

0

При использовании Resteasy вы можете зарегистрировать 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; 
    } 
} 

Примечания: Если вы вручную настроить @Produces он перекрывает ContentType установленного перехватчика.Если вы это сделаете, установите кодировку в @Produces