[Resolvido] Charset em result.use(json()) - VRaptor 3

Salve galera,

Tenho um formulário que servirá para envio de mensagem de contato que eu estou enviando via ajax.
No controler o método envia o e-mail e devolve a resposta de sucesso ou não via json.

Em caso de não sucesso de envio da mensagem eu seto status de resposta como 500 e devolvo junto a mensagem de erro.

result.use(Results.http()).setStatusCode(500);
result.use(Results.json()).from("Sua mensagem não pode ser enviada, desculpe-nos o transtorno.").serialize();

Acontece que a resposta não está setando o charset no Content-Type da resposta e o “não” está aparecendo com a codificação errada.
Teria algum modo de eu setar o charset?

Já tentei utilizar:

result.use(Results.http()).setStatusCode(500);
result.use(Results.http()).addHeader("Content-Type", "charset=ISO-8859-1");
result.use(Results.json()).from("Sua mensagem não pode ser enviada, desculpe-nos o transtorno.").serialize();

Mas não funciona, o Content-Type da resposta vem apenas com o application/json setado pelo VRaptor.

crie a classe:

@Component
public class CharsetJSONSerialization extends XStreamJSONSerialization {

       public CharsetJSONSerialization(HttpServletResponse response, TypeNameExtractor extractor) {
                super(response, extractor);
		this.response = response;
	}

   public <T> Serializer from(T object) {
		response.setContentType("application/json; charset=ISO-8859-1");
		return getSerializer().from(object);
	}
}

e remova o result…addHeader do código

isso deve funcionar
[]'s

Opa, valeu Lucas, funcionou perfeitamente.
Muito obrigado.

Não seria interessante que o método from pudesse ter um terceiro parâmetro para receber o charset?
Algo como:

result.use(json()).from("Dado", "alias", "ISO-8859-1").serialize();

Abraços

isso ou tentar descobrir qual é o charset da requisição… abre uma issue no github com isso por favor? (em inglês, se for possível) http://github.com/caelum/vraptor/issues

Pra não criar uma classe só pra fazer essa adapção e perder o padrão nos results,
poque desse modo todos os results estariam de acordo com o framework
e todas as que eu quero usar json eu teria que usar a classe criada.

result.use(CharsetJSONSerialization.class)..........

Eu acabei baixando os fontes do VRaptor e criei o método com o terceiro parâmetro na interface Serialization e implementei os métodos nas classes XStreamJSONSerialization e XStreamXMLSerialization.

Nenhum segredo na implementação. Só adicionei o método exatamente como você me passou no XStreamJSONSerialization e com application/xml no XStreamXMLSerialization obviamente.

Não mechi na interfaze Serializer pois apenas o que eu fiz já satisfez a minha necessidade e por não ter certeza da implementação a usar nas classes que implementam Serializer.

No final das contas o seu uso não foge do padrão do framework e ficou assim:

result.use(json).from("Minha mensagem", "mensagem", "ISO-8859-1").serialize();

Estou anexando as classes pra se alguém quiser usar também.
É só abrir o jar, jogar no pacote correto e fechar o jar novamente.

E também já abri a Issue no github.

Abraços

se vc não for usar os métodos extras vc nem precisa chamar a classe direto… result.use(json()) funcionaria

Só não entendo por que fazer manual algo que você pode fazer “automagico”.

Quando vocẽ envia uma requisição json, nos headers é enviado qual o charset usado. Basta pega-lo e usar no response. Simples e sem precisar passar parametro manual.

Garcia-jj,

foi exatamente o que o Lucas disse no segundo post dele.
Identificar qual o charset da requisição.

Poque mesmo que eu pegue o charset que veio da requisição, ainda não tem um modo de eu mandar esse charset para o response.

response.setCharacterEncoding =)

Puts, verdade.

Considerei pegar o charset pelo HttpServletRequest, e esqueci do HttpServletResponse.
=P

Na verdade você pega pelo request e retorna pelo response.

String encoding = request.getCharacterEncoding(); if (encoding != null) { response.setCharacterEncoding(encoding); }

Gostaria de adicionar algumas informações no tópico.
Por algum motivo bizarro meu IE8 não enviava o charcode, então ao invés de pegar do request sugiro fazerem isso na mão mesmo.
Exemplo:

servletResponse.setCharacterEncoding("ISO-8859-1");

Pra quem tiver com mesmo problema, consegui resolver bem deixando todos os arquivos envolvidos no formato UTF-8.

Depois, o pulo do gato é adicionar no web.xml

&lt;context-param&gt;
    &lt;param-name&gt;br.com.caelum.vraptor.encoding&lt;/param-name&gt;
    &lt;param-value&gt;UTF-8&lt;/param-value&gt;
&lt;/context-param&gt;

abs