Spring MVC e a anotação @ModelAttribute

Spring MVC e a anotação @ModelAttribute

1. Visão geral

Uma das anotações deSpring-MVC mais importantes é a anotação de@ModelAttribute.

O@ModelAttribute é uma anotação que vincula um parâmetro de método ou valor de retorno de método a um atributo de modelo nomeado e, em seguida, o expõe a uma visualização da web.

No exemplo a seguir, vamos demonstrar a usabilidade e funcionalidade da anotação, por meio de um conceito comum: um formulário enviado por um funcionário de uma empresa.

Leitura adicional:

Model, ModelMap e ModelView no Spring MVC

Aprenda sobre as interfacesModel,ModelMapeModelView fornecidas pelo Spring MVC.

Read more

Anotação Spring @RequestParam

Um guia detalhado para a anotação @RequestParam de Spring

Read more

2. O@ModelAttribute em profundidade

Como o parágrafo introdutório revelou,@ModelAttribute pode ser usado como um parâmetro do método ou no nível do método.

2.1 At the Method Level

Quando a anotação é usada no nível do método, indica que o objetivo desse método é adicionar um ou mais atributos de modelo. Esses métodos suportam os mesmos tipos de argumento dos métodos@RequestMapping, mas não podem ser mapeados diretamente para solicitações.

Vamos dar uma olhada em um exemplo rápido aqui para começar a entender como isso funciona:

@ModelAttribute
public void addAttributes(Model model) {
    model.addAttribute("msg", "Welcome to the Netherlands!");
}

No exemplo, mostramos um método que adiciona um atributo denominadomsg a todos osmodels definidos na classe do controlador.

É claro que veremos isso em ação mais adiante neste artigo.

Em geral, o Spring-MVC sempre faz uma chamada primeiro para esse método, antes de chamar qualquer método do manipulador de solicitações. That is, @ModelAttribute methods are invoked before the controller methods annotated with @RequestMapping are invoked. A lógica por trás da sequência é que, o objeto de modelo deve ser criado antes que qualquer processamento seja iniciado dentro dos métodos do controlador.

Também é importante que você anote a respectiva classe como@ControllerAdvice. Assim, você pode adicionar valores emModel que serão identificados como globais. Na verdade, isso significa que, para cada solicitação, existe um valor padrão, para cada método na parte da resposta.

2.2 As a Method Argument

Quando usado como argumento de método, indica que o argumento deve ser recuperado do modelo. Quando não estiver presente, ele deve ser instanciado primeiro e, em seguida, adicionado ao modelo e, uma vez presentes no modelo, os campos de argumentos devem ser preenchidos de todos os parâmetros de solicitação que possuem nomes correspondentes.

No fragmento de código que segue, o atributo de modeloemployee é preenchido com dados de um formulário enviado ao terminaladdEmployee. O Spring MVC faz isso nos bastidores antes de chamar o método de envio:

@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public String submit(@ModelAttribute("employee") Employee employee) {
    // Code that uses the employee object

    return "employeeView";
}

Mais adiante neste artigo, veremos um exemplo completo de como usar o objetoemployee para preencher o modeloemployeeView.

Portanto, vincula os dados do formulário a um bean. The controller annotated with @RequestMapping can have custom class argument(s) annotated with @ModelAttribute.

Isso é conhecido como ligação de dados no Spring-MVC, um mecanismo comum que evita que você precise analisar cada campo de formulário individualmente.

3. Exemplo de formulário

Nesta seção, forneceremos o exemplo referido na seção de visão geral: um formulário muito básico que solicita a um usuário (funcionário de uma empresa, em nosso exemplo específico), para inserir algumas informações pessoais (especificamentenameeid). Após o envio ser concluído e sem erros, o usuário espera ver os dados enviados anteriormente, exibidos em outra tela.

3.1 The View

Vamos primeiro criar um formulário simples com campos de id e nome:


    Name
    

    Id
    

    

3.2 The Controller

Aqui está a classe do controlador, onde a lógica da visão mencionada acima está sendo implementada:

@Controller
@ControllerAdvice
public class EmployeeController {

    private Map employeeMap = new HashMap<>();

    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public String submit(
      @ModelAttribute("employee") Employee employee,
      BindingResult result, ModelMap model) {
        if (result.hasErrors()) {
            return "error";
        }
        model.addAttribute("name", employee.getName());
        model.addAttribute("id", employee.getId());

        employeeMap.put(employee.getId(), employee);

        return "employeeView";
    }

    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("msg", "Welcome to the Netherlands!");
    }
}

No métodosubmit(), temos um objetoEmployee ligado ao nossoView. Você consegue ver o poder desta anotação? Você pode mapear seus campos de formulário para um modelo de objeto de maneira simples. No método, estamos obtendo valores do formulário e definindo-os comoModelMap.

No final, retornamosemployeeView, o que significa que o respectivo arquivo JSP será chamado como um representanteView.

Além disso, existe também um métodoaddAttributes(). Seu objetivo é adicionar valores emModel que serão identificados globalmente. Ou seja, um valor padrão será retornado como uma resposta para cada solicitação para cada método do controlador. Também temos que anotar a classe específica como@ControllerAdvice.

3.3 The Model

Como mencionado antes, o objetoModel é muito simplista e contém tudo o que é exigido pelos atributos de “front-end”. Agora, vamos dar uma olhada em um exemplo:

@XmlRootElement
public class Employee {

    private long id;
    private String name;

    public Employee(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // standard getters and setters removed
}

3.4 Wrap Up

O@ControllerAdvice auxilia um controlador e, em particular, os métodos@ModelAttribute que se aplicam a todos os métodos@RequestMapping. Obviamente, nosso métodoaddAttributes() será o primeiro a ser executado, antes do restante dos métodos@RequestMapping.

Tendo isso em mente e depois quesubmit() eaddAttributes() forem executados, poderíamos apenas nos referir a eles noView retornado da classeController, mencionando seu nome de batismo dentro de uma dupla de chaves dolarizadas, como por exemplo${name}.

3.5 Results View

Vamos agora imprimir o que recebemos do formulário:

${msg}

Name : ${name} ID : ${id}

4. Conclusão

Neste tutorial, investigamos o uso da anotação@ModelAttribute, para ambos os argumentos de método e casos de uso de nível de método.

A implementação deste tutorial simples pode ser encontrada no projetogithub - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.