BT
x A sua opinião é importante! Por favor preencha a pesquisa do InfoQ sobre os seus hábitos de leitura!

Java na Web com VRaptor 4

Postado por Rodrigo Turini em 13 Mai 2014 |

Trabalhar com Java na web apresenta diversas possibilidades com frameworks MVC baseados em ações. O VRaptor é um desses frameworks, e em sua versão 4 utiliza o CDI 1.1 como base. Veremos neste artigo alguns dos princípios do framework e uma seleção de novidades da nova versão.

Controllers e Convenções

Tudo que se precisa fazer para criar um controller do VRaptor é adicionar a anotação @Controller. A partir daí o framework já utiliza suas convenções de URLs e JSPs, exigindo o mínimo de configurações. Veja um exemplo:

@Controller
public class UsuarioController {
 	public void lista() {
... 
}
}

A convenção de URLs do VRaptor é nomeDoController/nomeDoMetodo; portanto o método lista() seria mapeado para a URL /usuario/lista. Repare que o sufixo Controller não é considerado na rota.

Outra convenção importante é da página JSP pra a qual o VRaptor vai fazer o dispatch. Ela é bem parecida com a convenção de URLs.O VRaptor procura a JSP no diretório:

WEB-INF/jsp/nomeDoController/nomeDoMetodo.jsp, 

que neste caso será:

WEB-INF/jsp/usuario/lista.jsp.

Todos os métodos públicos dos controllers serão mapeados seguindo essas convenções, e passam a atender requests independente do verbo HTTP utilizado.

Pode-se explicitamente declarar qual tipo de requisição cada método vai atender, por exemplo utilizando a anotação @Get. Há ainda as anotações @Post, @Put e @Delete. Se preferir não utilizar a convenção de URLs, você pode passar a URL como value dessas anotações de verbo, ou utilizar a anotação @Path se o verbo for indiferente:

@Get("alguma/outra/url")
public void lista(){ ... }

Recebimento de parâmetros

Pode-se receber parâmetros nos métodos do seu controller. De acordo com os parâmetros da requisição o VRaptor tenta popular esses valores. Isso pode ser feito com valores simples, como um long no caso do seguinte método:

@Get
public void busca(long id){
…
}

Se o request tiver algum parâmetro cujo nome seja id, ou seja, igual ao do parâmetro do método, o VRaptor tenta converter esse valor para o tipo esperado.

O método busca(), na primeira forma que foi escrito, pode ser acessado pela URL /usuario/busca?id=1, por exemplo. Há ainda como fazer isso utilizando uma URL parametrizada:

@Get("usuario/busca/{id}")
public void busca(long id){ 
…
}

Neste caso um exemplo de URL seria /usuario/busca/1.

Também podemos receber objetos mais complexos, como no caso do método adiciona() que recebe um objeto Usuario:

@Post
public void adiciona(Usuario usuario){ ... }

Na view teríamos o formulario.jsp parecido com:

<form action=”/usuario/adiciona” method=”post”>
	<input type=”text” name=”usuario.nome”/>
	<input type=”text” name=”usuario.email”/>
<input type=”submit”  value=”Adicionar”>
</form>

 

Exemplos de parâmetros do request para este formulário seriam:

usuario.nome = Rodrigo Turini
usuario.email = rodrigoatturini@caelum.com.br
...

Manipulação do resultado

Para deixar os objetos dos métodos acessíveis pela página JSP podemos simplesmente retorná-los - da seguinte forma:

@Get
public List<Usuario> lista(){
	return usuarioDao.lista();
}

Como estamos retornando um List<Usuario>, o nome da variável acessada em sua view será ${usuarioList}. Se o retorno fosse um único objeto, a variável seria apenas ${usuario}.

Há outra forma de retornar objetos para a view: utilizando a interface especialista Result. Podemos pedir esse bean injetado em nosso controller e utilizar seu método include():

@Controller
public class UsuarioController {
	@Inject private Result result;
	@Inject private UsuarioDao usuarioDao;
	@Get
	public void lista(){
		List<Usuario> lista = usuarioDao.lista();
		result.include(lista);
		result.include("usuarios", lista);
	}
}

Na primeira chamada a include(), a variável incluída será ${usuarioList}, assim como no retorno do método. Porém repare que no segundo include() demos um nome para o objeto incluído; portanto será este o utilizado.

Existem diversos outros métodos no Result para nos auxiliar com o trabalho com a view. Por exemplo, veja como se pode devolver essa lista de objetos serializada em JSON:

@Get
public void listaEmJSON(){
	List<Usuario> usuarios = usuarioDao.lista();
	result.use(json()).from(usuarios).serialize();
}

O método json() vem da classe Results, que possui outros métodos para resultados comuns - como xml(), html() e jsonp(). Há ainda o método representation(), que retorna de acordo com o accept format do request.

Facilmente configurável

Tudo isso que vimos é facilmente configurável. Como suas classes são gerenciadas pelo CDI (managed beans) podemos especializar qualquer componente do VRaptor.

Por exemplo, para mudar a view renderizada por padrão, ou mudar o local em que é procurada, especializamos o DefaultPathResolver:

@Specializes
public class CustomPathResolver extends DefaultPathResolver {
    @Override
    protected String getPrefix() {
        return "/pasta/raiz/";
    }
}

Da mesma forma, pode-se mudar a convenção de URLs sobrescrevendo o PathAnnotationRoutesParser.

Integrando VRaptor com JPA

A integração com CDI também facilita o gerenciamento das classes que não são de nosso projeto. Integrar o VRaptor com JPA, por exemplo, é um processo simples. Pode-se escrever um producer para o EntityManager parecido com esse:

public class EntityManagerCreator {
	@Inject private EntityManagerFactory factory;
	@Produces @RequestScoped
	public EntityManager getEntityManager() {
		return factory.createEntityManager();
	}

	public void destroy(@Disposes EntityManager em) {
		if (em.isOpen()) {
			em.close();
		}
	}
}

Com isso, em qualquer bean da sua aplicação, é possível injetar esse objeto. Por exemplo:

public class UsuarioDao {
	@Inject private EntityManager em;
	public void adiciona(Usuario usuario) {
		em.getTransaction().begin();
		em.persist(usuario);
		em.getTransaction().commit();
	}
	...
}

Pode-se criar um interceptor simples para fazer o open transaction in view, mas isso e diferentes outros recursos já foram implementados nos diversos plugins para o VRaptor 4. Veja alguns desses plugins nessa página da documentação.

Mais sobre o Vraptor

Mais informações sobre o framework podem ser obtidas em sua documentação, que conta com guias de 1 e 10 minutos, cookbooks enviados por usuários e um guia rápido para auxiliar na migração de versões anteriores. Pode ser útil também ler mais sobre a especificação do CDI 1.1 e todos seus recursos, que se integram ao núcleo do Vraptor.

 

Sobre o autor

Rodrigo Turini é bacharel em Ciência da Computação, desenvolvedor e instrutor pela Caelum. Desenvolve sistemas em Java para web e atualmente foca seus estudos em programação funcional e Java 8, assuntos coberto no livro que escreveu com Paulo SIlveira.

Olá visitante

Você precisa cadastrar-se no InfoQ Brasil ou para enviar comentários. Há muitas vantagens em se cadastrar.

Obtenha o máximo da experiência do InfoQ Brasil.

Dê sua opinião

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão
Comentários da comunidade

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

Dê sua opinião

Conteúdo educacional

Feedback geral
Bugs
Publicidade
Editorial
InfoQ Brasil e todo o seu conteúdo: todos os direitos reservados. © 2006-2014 C4Media Inc.
Política de privacidade
BT