Popular parâmetros -> Custom + Request (VRaptor)

5 respostas
P

Estou utilizando o VRaptor em uma aplicação web baseada em Rest.
Meu problema aparece quando recebo o JSON de uma classe para gravar no banco… o mesmo não vem completo.
Digamos que eu possua a seguinte classe:

@Entity
@Table(schema = "sh_sistema")
@SequenceGenerator(name = "SEQUENCE_USUARIO", sequenceName = "sh_sistema.seq_usuario")
@ConstraintUnique(attributes = @ConstraintUniqueAttribute(name = "login", message = "Já existe um usuário com esse login."))
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@ToString(exclude = "grupos")
public class Usuario {

	@Id
	@GeneratedValue(generator = "SEQUENCE_USUARIO")
	@NonNull
	private Long id;

	private boolean ativo = true;

	@Email
	@NotNull
	private String email;

	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "grupo_usuario", schema = "sh_sistema")
	private Set<Grupo> grupos;

	@NotNull
	private String login;

	private String nome;

	private String senha;

	public boolean contains(String chave) {
		if(getGrupos() != null) {
			for (Grupo grupo : getGrupos()) {
				if(grupo.contains(chave)) {
					return true;
				}
			}
		}

		return false;
	}

}

O JSON que é recebido pela aplicação em determinado momento não possui o Set de grupos. Apenas algumas informações como email, nome etc. Nesse caso tenho que buscar o objeto no banco caso o id seja diferente de null e completar os atributos faltantes:

@Component
public class UsuarioBusiness extends Business <Usuario, Long, UsuarioRepository> {

	@Transactional
	@Override
	public Pair<Boolean, String> save(Usuario entity) {
		//Carrega os atributos restantes.
		if(entity.getId() != null) {
			//senha -> Deve ser carregada pois a mesma não é enviada para a view.
			copy(findOne(entity.getId()), entity).set("senha").set("grupos");
		}

		return super.save(entity);
	}

}

Tive a idéia de adaptar o @Load default do VRaptor para resolver o problema de ficar carregando os atributos que não são enviados. Mas no momento que busco a classe no banco os parâmetros restantes que se encontram no request não são atualizados na instância cria por mim.

Como devo proceder nesse caso? Existe uma solução melhor?

5 Respostas

Lucas_Cavalcanti

o vraptor só serializa campos simples por padrão (strings, numeros, enums)… se quer que serialize toda a arvore de objetos vc precisa colocar um .recursive() antes do .serialize()… ou dar include nos campos que vc quer serializar.

P

Não, eu não quero enviar todo meu objeto como JSON.
Quero enviar apenas as informações que serão realmente utilizadas. Isso eu já estou fazendo.
O problema é a volta, como envio a metade dos valores tenho que buscar o objeto no banco para que o resto não se perca.
A questão é como fazer isso? Não quero deixar essa responsabilidade espalhada… Tentei modificar o Interceptor do @Load mas perco as informações do request.

No caso queria que a linha 10 do código não fosse necessária.

Lucas_Cavalcanti

ah tah… isso é comportamento do hibernate…

como eu faço geralmente é carregar o objeto por id no banco e ir setando os campos que eu quero deixar modificável… assim vc ainda aumenta a segurança da operação.

P

Tem como eu deixar isso de uma maneira genérica? Tentei utilizar uma customização do @Load mas não deu certo.

Lucas_Cavalcanti

cuidado com essa maneira genérica…

imagina que eu faço um @Load num usuário e mando junto na requisição um usuario.role=ADMIN

automaticamente qualquer usuario pode virar admin!

a gente não deixou isso assim no VRaptor por esse motivo…

o que dá pra fazer: crie um converter do vraptor pro objeto, que recebe o id e carrega do banco… assim o vraptor chama o converter antes de setar o resto das propriedades.

assim o parametro da requisição ao invés de ser objeto.id tem que ser só objeto

Criado 30 de novembro de 2012
Ultima resposta 30 de nov. de 2012
Respostas 5
Participantes 2