Vraptor: Recuperar uma mensagem do message.properties

17 respostas
gporpino

Como faço para pegar a mensagem que está no properties?

esse código acima dá este erro:

You must set the bundle before using the I18nMessage

tem alguma forma prática de fazer isso?

17 Respostas

Lucas_Cavalcanti

vc pode setar assim:

I18nMessage message = new I18nMessage("success","enrollment.success");
message.setBundle(localization.getBundle()); //receba no construtor a Localization
//resto do código
gporpino

Criei essa classe para recuperar minhas mensagens
mas gostaria que fosse static mas não consegui por conta do Localization.

@Component
public class Resources {

	private Localization localization;

	public Resources(Localization localization) {
		this.localization = localization;
	}
	
	public I18nMessage getMessage(String key) {
		I18nMessage message = new I18nMessage("default",key);  
		message.setBundle(localization.getBundle());
		return message;
	} 
	
	public I18nMessage getMessage(String key, String category) {
		I18nMessage message = new I18nMessage(category,key);  
		message.setBundle(localization.getBundle());
		return message;
	} 
	
	public String getString(String key) {
		I18nMessage message = new I18nMessage("default",key);  
		message.setBundle(localization.getBundle());
		return message.getMessage();
	}  
	
	public String getString(String key, String category) {
		I18nMessage message = new I18nMessage(category,key);  
		message.setBundle(localization.getBundle());
		return message.getMessage();
	} 
	
}
Lucas_Cavalcanti

se vc usar o validator vc não precisa dessa classe :wink:

gporpino

mas eu quero pegar a mensagem no retorno da mensagem de sucesso e não no erro.

Lucas_Cavalcanti

entendi, vc tá aproveitando as mensagem de validação pra dar mensagens de sucesso…

se vc pensar em um jeito legal, dá pra gente incluir isso no result, que acha?

gporpino

Seria perfeito!!

acredito que se a chamada fosse

ou

Algo assim, seria muito útil.

Eu não tenho o código fonte por isso não sei se é possível.
Por falar nisso, como poderia ajudar com issues e implementações?
É complicado de entrar?

Lucas_Cavalcanti

o código fonte está aqui:

se quiser ajudar, basta escolher (ou criar) uma das issues:

pra implementar algo, vc pode criar um fork do repositório, mandar as alterações pra lá e mandar um pull request.

a sua idéia é só pra serializar via json as mensagens?

gporpino

Isso mesmo.

Meu jQuery:

$.post($(this).parent().attr("action"), $(this).parent().serialize(),function(){},"json")
		.success(function(data) { 
			$(elem).success(data);
		})
		.error(function(data){
			
			var response = jQuery.parseJSON(data.responseText);
			
			Messages.showErrors(response.errors);
		});

Mas era interessante poder recuperar essas mensagens para colocar no result.include para requisicao normais (não ajax).

gporpino

Cheguei nessa solução:

Minha classe:
@Component
public class Resources {

	private static Localization localization;

	public Resources(Localization localization) {
		Resources.localization = localization;
	}
	
	public static I18nMessage getMessage(String key) {
		I18nMessage message = new I18nMessage("default",key);  
		message.setBundle(localization.getBundle());
		return message;
	} 
	
	public static I18nMessage getMessage(String key, String category) {
		I18nMessage message = new I18nMessage(category,key);  
		message.setBundle(localization.getBundle());
		return message;
	} 
	
	public static String getString(String key) {
		I18nMessage message = new I18nMessage("default",key);  
		message.setBundle(localization.getBundle());
		return message.getMessage();
	}  
	
	public static String getString(String key, String category) {
		I18nMessage message = new I18nMessage(category,key);  
		message.setBundle(localization.getBundle());
		return message.getMessage();
	} 
	
}
Minha chamada:
result.use(Results.json()).withoutRoot().from(Resources.getMessage("enrollment.success")).serialize();
Para mim, esta resolvendo, mas se colocar isso como um result novo seria melhor ainda. Ficaria mais limpo o código. Além de não precisar implementar uma classe para usar este recurso.
gporpino

Descobrir que para a solução acima funcionar eu tenho que apontar o Resources no construtor de algum Controller.

Lucas aquela idéia de colocar no result está de pé?

Lucas_Cavalcanti

está de pé sim.

Abre uma issue lá para isso por favor:

gporpino

Lucas, ainda não abrir a issue pois surgiu uma outra necessidade. ai estou amadurecendo para ver se faz sentido.

Bem o detalhe é que necessito retornar um objeto e a mensagem de sucesso (quando ocorre tudo certo.)

Mas ao tentar serializar um objeto, que criei para retornar a mensagem e o objeto.
No client (jquery) o retorno não chega com as propriedades.

EntityResult<Sponsor> entityResult = new EntityResult<Sponsor>(Resources.getMessage("sponsor.save.success"), business.findByName(sponsorToUpdate.getName()));
		
result.use(Results.json()).from(entityResult).serialize();
Classe EntityResult:
public class EntityResult<T extends BaseEntity> implements  java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	
	private I18nMessage message;
	private T entity;
	
	public EntityResult(I18nMessage message, T entity){
		this.entity = entity;
		this.message = message;
	}
	
	public I18nMessage getMessage() {
		return message;
	}
	public void setMessage(I18nMessage message) {
		this.message = message;
	}
	public T getEntity() {
		return entity;
	}
	public void setEntity(T entity) {
		this.entity = entity;
	}
	
}
Detalhe se eu retornar somente o I18nMessage ele vem com as propriedades. :(

O que preciso fazer para aparecer no js as propriedades?

Lucas_Cavalcanti

vc precisa colocar um .recursive() ou .include(“message”, “entity”) antes do .serialize(). Por padrão só são serializados os campos primitivos (Strings, numeros e datas)

gporpino

Como falei acima surgiu uma nova necessidade.

Precisava retornar o objeto salvo, para fazer uns tratamentos na tela.

Com a sua ajuda cheguei nessa solução:
EntityResult<Sponsor> entityResult = new EntityResult<Sponsor>(Resources.getString("sponsor.save.success"), business.findByName(sponsorToUpdate.getName()));
result.use(Results.json()).withoutRoot().from(entityResult).recursive().serialize();
Onde o EntityResult é:
public class EntityResult<T extends BaseEntity>{ 
	
	private String message;
	private T entity;
	
	public EntityResult(String message, T entity){
		this.entity = entity;
		this.message = message;
	}
	
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public T getEntity() {
		return entity;
	}
	public void setEntity(T entity) {
		this.entity = entity;
	}
	
}
Faz sentido colocar isso com result? Seria uma chamada mas ou menos assim.
result.use(Results.entity()).from(sponsor).successMessage("sponsor.save.success").recursive().serialize();

Se não vou abrir a issue para a mensagem apenas.

OBS: Tentei usar o EntityResult como interface e instaciar aninhado. mas o objeto ia sem atributo nenhum.
result.use(Results.json()).withoutRoot().from(new EntityResult<Sponsor>(){
			
			public String getMessage(){
				return Resources.getString("sponsor.save.success");
			}
			
			public Sponsor getEntity(){
				return business.find(sponsor.getId());
			}
			
		}).recursive().serialize();
	}
Lucas_Cavalcanti

o xstream serializa por padrão usando atributos, e não getters, por isso que não aparece nada…

dá pra fazer isso criando um converter de EntityResult. Daí não precisaria nem do recursive().

eu estava pensando em algo mais simples… que só mostra uma mensagem mesmo:

result.message("key");

o seu entity result poderia entrar como um plugin, interessa?

gporpino

Interessa sim!

sou a favor da limpeza de código!!

Abro 2 issues então?

Aproveitando…
Por que no meu código tenho que colocar Results.algumaCoisa(). ja vi vários exemplos sem isso. vc tem idéia?

Lucas_Cavalcanti

vc pode fazer um import static:

import static br.com......Results.json;


//...

result.use(json())

no eclipse vc pode apertar Ctrl+Shift+M em cima do json() que ele faz o import

Criado 27 de setembro de 2011
Ultima resposta 4 de out. de 2011
Respostas 17
Participantes 2