O que é o @ModelAttribute no Spring MVC?

372

Qual é o objetivo e o uso do @ModelAttributeSpring MVC?

Mohammad Adnan
fonte
40
Penso que é uma pergunta útil, porque permite que os leitores obtenham mais informações (incluindo exemplos) do que a documentação oficial do Spring fornece.
precisa saber é o seguinte
3
Verifique este artigo aqui. thespringthing.blogspot.com/2010/11/…
praveenj

Respostas:

399

@ModelAttributerefere-se a uma propriedade do objeto Model (o M no MVC;), digamos que tenhamos um formulário com um objeto de suporte de formulário chamado "Person". Em seguida, o Spring MVC fornece esse objeto a um método Controller usando a @ModelAttributeanotação :

public String processForm(@ModelAttribute("person") Person person){
    person.getStuff();
}

Por outro lado, a anotação é usada para definir objetos que devem fazer parte de um modelo. Portanto, se você quiser ter um objeto Pessoa referenciado no Modelo, poderá usar o seguinte método:

@ModelAttribute("person")
public Person getPerson(){
    return new Person();
}

Esse método anotado permitirá o acesso ao objeto Pessoa na sua Visualização, pois ele é adicionado automaticamente aos Modelos no Spring.

Consulte "Usando @ModelAttribute" .

fasseg
fonte
8
@assasseg Na verdade, você não precisa @ModelAttributeno seu primeiro caso.
Neil McGuigan
@ Neil Quando você precisa usar @ModelAttributenos atributos do método?
22915 Ryan
4
@ Ryan ver stackoverflow.com/questions/8688135/...
Neil McGuigan
11
você deve incluir como a pessoa é preenchida e como esse método é chamado.
Philip Rego
134

Sei que esse é um fio antigo, mas pensei em jogar meu chapéu no ringue e ver se consigo enlamear a água um pouco mais :)

Descobri que minha luta inicial para entender @ModelAttributeera o resultado da decisão de Spring de combinar várias anotações em uma. Tornou-se mais claro depois que o dividi em várias anotações menores:

Para anotações de parâmetro, pense @ModelAttributecomo o equivalente a, @Autowired + @Qualifierou seja, ele tenta recuperar um bean com o nome fornecido no modelo gerenciado do Spring. Se o bean nomeado não for encontrado, em vez de gerar um erro ou retornar null, ele implicitamente assume o papel de, @Beanpor exemplo, criar uma nova instância usando o construtor padrão e adicionar o bean ao modelo.

Para anotações de método, pense @ModelAttributecomo o equivalente a @Bean + @Before, ou seja, coloca o bean construído pelo código do usuário no modelo e é sempre chamado antes de um método de manipulação de solicitação.

Figurativamente, vejo @ModelAttributeo seguinte (por favor, não leve isso literalmente !!):

@Bean("person")
@Before
public Person createPerson(){
  return new Person();
}

@RequestMapping(...)
public xxx handlePersonRequest( (@Autowired @Qualifier("person") | @Bean("person")) Person person, xxx){
  ...
}

Como você pode ver, o Spring tomou a decisão certa de fazer @ModelAttributeuma anotação abrangente; ninguém quer ver uma anotação smorgasbord.

Christopher Yang
fonte
2
Hum, @Bean é singleton por padrão. Não sei se os mesmos conceitos se aplicam aqui.
Zombies
10
Absolutamente não. Estou apenas usando anotações mais simples para explicar essa anotação complexa. Por favor, tome minha explicação conceitualmente, não literalmente.
Christopher Yang
4
@Zombies add @Scope("request")then :)
OrangeDog
28

No meu estilo, eu sempre uso @ModelAttribute para capturar objetos do spring form jsp. por exemplo, eu desenho o formulário na página jsp, que existe com commandName

<form:form commandName="Book" action="" methon="post">
      <form:input type="text" path="title"></form:input>
</form:form>

e eu pego o objeto no controlador com o código a seguir

public String controllerPost(@ModelAttribute("Book") Book book)

e todo nome de campo do livro deve corresponder ao caminho no subelemento do formulário

Leang Socheat
fonte
4
O catchverbo descreve exatamente o trabalho que @ModelAttributefoi feito. Agradável.
Eddy
3
Melhor resposta do ano.
Jupiter Cls
4
Mas isso é necessário? Isso ainda está funcionando sem o uso da anotação @ModelAttribute.
23

Então, tentarei explicar de maneira mais simples. Vamos ter:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}

Conforme descrito na documentação do Spring MVC - a anotação @ModelAttribute pode ser usada em métodos ou em argumentos de método . E, é claro, podemos usar os dois ao mesmo tempo em um controlador.

Anotação 1.Method

@ModelAttribute(“cities”)
 public List<String> checkOptions(){
 return new Arrays.asList(new[]{“Sofia”,”Pleven","Ruse”});//and so on
}

O objetivo desse método é adicionar atributo no modelo. Portanto, em nosso caso, a chave das cidades terá a lista new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})como valor no modelo (você pode pensar em modelo como mapa (chave: valor)). Os métodos @ModelAttribute em um controlador são chamados antes dos métodos @RequestMapping , dentro do mesmo controlador.

Aqui, queremos adicionar ao modelo informações comuns que serão usadas no formulário para exibir ao usuário. Por exemplo, ele pode ser usado para preencher uma seleção de HTML:

insira a descrição da imagem aqui

Argumento 2.Method

public String findPerson(@ModelAttriute(value="person") Person person) {
    //..Some logic with person
    return "person.jsp";
}

Um @ModelAttribute em um argumento de método indica que o argumento deve ser recuperado do modelo. Portanto, nesse caso, esperamos que tenhamos no objeto person Model como chave e queremos obter seu valor e colocá-lo no argumento do método Person person . Se isso não existir ou (às vezes você digitar incorretamente o (valor = "persson")), o Spring não o encontrará no modelo e criará o objeto Person vazio usando seus padrões. Em seguida, pegará os parâmetros de solicitação e tentará vinculá-los aos dados no objeto Pessoa usando seus nomes.

name="Dmitrij"&countries=Lesoto&sponsor.organization="SilkRoad"&authorizedFunds=&authorizedHours=&

Portanto, temos nome e ele será vinculado a Person.name usando setName (String name). Então em

//..Some logic with person

temos acesso a esse nome preenchido com o valor "Dimitrij".

É claro que o Spring pode vincular objetos mais complexos, como Listas, Mapas, Lista de Conjuntos de Mapas e assim por diante, mas nos bastidores, isso torna mágica a ligação de dados.

  1. Podemos, ao mesmo tempo, modelar o método anotado e solicitar o manipulador do método com @ModelAttribute nos argumentos. Então temos que unir as regras.

  2. É claro que temos inúmeras situações diferentes - os métodos @ModelAttribute também podem ser definidos em um @ControllerAdvice e assim por diante ...

Xelian
fonte
13

Eu sei que estou atrasado para a festa, mas vou citar como eles dizem: "É melhor chegar atrasado do que nunca". Então, vamos em frente. Todo mundo tem suas próprias maneiras de explicar as coisas, deixe-me tentar resumir e simplificar para você em algumas etapas com um exemplo; Suponha que você tenha um formulário simples, form.jsp

<form:form action="processForm" modelAttribute="student">
First Name : <form:input path="firstName" /> 
<br><br>
Last Name : <form:input path="lastName" />
<br><br>
<input type="submit" value="submit"/>
</form:form>

path = "firstName" path = "lastName" Estes são os campos / propriedades na StudentClass quando o formulário é chamado, seus getters são chamados, mas, uma vez enviados, seus setters são chamados e seus valores são definidos no bean que foi indicado no modelAttribute = "aluno" na tag de formulário.

Temos o StudentController que inclui os seguintes métodos;

@RequestMapping("/showForm")
public String showForm(Model theModel){ //Model is used to pass data between 
//controllers and views
    theModel.addAttribute("student", new Student()); //attribute name, value
return "form";
}

@RequestMapping("/processForm")
public String processForm(@ModelAttribute("student") Student theStudent){
    System.out.println("theStudent :"+ theStudent.getLastName());
return "form-details";
}

//@ModelAttribute("student") Student theStudent
//Spring automatically populates the object data with form data all behind the 
//scenes 

agora finalmente temos um form-details.jsp

<b>Student Information</b>
${student.firstName}
${student.lastName}

Então, voltando à pergunta O que é o @ModelAttribute no Spring MVC? Uma definição de amostra da fonte para você, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation O @ModelAttribute é uma anotação que liga um parâmetro de método ou valor de retorno de método a um atributo de modelo nomeado e, em seguida, expõe-o a uma visualização da web.

O que realmente acontece é que obtém todos os valores do formulário que foram enviados por ele e os mantém para que você os vincule ou atribua ao objeto. Funciona da mesma forma que o @RequestParameter, onde apenas obtemos um parâmetro e atribuímos o valor a algum campo. A única diferença é que @ModelAttribute mantém todos os dados do formulário em vez de um único parâmetro. Ele cria um bean para você que mantém os dados enviados pelo formulário para serem usados ​​pelo desenvolvedor posteriormente.

Para recapitular a coisa toda. Etapa 1: Uma solicitação é enviada e nosso método showForm é executado e um modelo, um bean temporário é definido com o nome de student e é encaminhado para o formulário. theModel.addAttribute ("student", new Student ());

Etapa 2: modelAttribute = "aluno" no modelo de envio de formulário altera o aluno e agora mantém todos os parâmetros do formulário

Etapa 3: @ModelAttribute ("student") Student theStudent Buscamos os valores retidos por @ModelAttribute e atribuímos o bean / objeto inteiro ao Student.

Etapa 4: e depois a usamos conforme o lance, assim como mostrá-la na página etc., como eu fiz

Espero que ajude você a entender o conceito. obrigado

Majid Ali Khan
fonte
9

Adquira qualquer aplicativo da Web, seja Gmail, Facebook, Instagram ou qualquer outro aplicativo da Web, trata-se de trocar dados ou informações entre o usuário final e o aplicativo ou a interface do usuário e o aplicativo de back-end. Mesmo no mundo do Spring MVC, existem duas maneiras de trocar dados:

  1. do controlador para a interface do usuário e
  2. da interface do usuário para o controlador.

O que estamos interessados ​​aqui é como os dados são comunicados da interface do usuário ao Controller. Isso também pode ser feito de duas maneiras:

  1. Usando um formulário HTML
  2. Usando parâmetros de consulta.

Usando um formulário HTML: considere o cenário abaixo,

Representação de envio de formulário

Quando enviamos os dados do formulário a partir do navegador da web, podemos acessar esses dados em nossa classe Controller como um objeto. Quando enviamos um formulário HTML, o Spring Container faz quatro coisas. Será,

  1. leia primeiro todos os dados que são enviados na solicitação usando o método request.getParameter .
  2. depois de lê-los, os converterá no tipo Java apropriado usando integer.parseInt , double.parseDouble e todos os outros métodos de análise disponíveis com base no tipo de dados.
  3. uma vez analisado, ele criará um objeto da classe de modelo que criamos. Por exemplo, nesse cenário, são as informações do usuário que estão sendo enviadas e criamos uma classe chamada Usuário, da qual o Container criará um objeto e definirá todos os valores que entram automaticamente nesse objeto.
  4. então, entregará esse objeto definindo os valores para o Controlador.

Para que tudo funcione, teremos que seguir algumas etapas.

Trabalho interno

Primeiro, precisamos definir uma classe de modelo, como Usuário, na qual o número de campos deve corresponder exatamente ao número de campos no formulário HTML. Além disso, os nomes que usamos no formulário HTML devem corresponder aos nomes que temos na classe Java. Esses dois são muito importantes. Os nomes devem corresponder, o número de campos no formulário deve corresponder ao número de campos na classe que criamos. Uma vez feito isso, o Container lerá automaticamente os dados que entram, cria um objeto desse modelo, define os valores e os entrega ao Controlador. Para ler esses valores dentro do Controller, usamos o @ModelAttributeanotação nos parâmetros do método. Quando criamos métodos no Controller, vamos usar o @ModelAttribute e adicionar um parâmetro que automaticamente terá esse objeto fornecido pelo Container.

Aqui está um código de exemplo para registrar um usuário:

@RequestMapping(value = "registerUser", method = RequestMethod.POST)
public String registerUser(@ModelAttribute("user") User user, ModelMap model) {
    model.addAttribute("user", user);
    return "regResult";
}

Espero que esta explicação diagramática tenha ajudado!

Nithin Prasad
fonte
4

Isso é usado para fins de ligação de dados no Spring MVC. Permite que você tenha um jsp com um elemento de formulário, por exemplo

em JSP

<form:form action="test-example" method="POST" commandName="testModelAttribute"> </form:form>

(Método Spring Form, elemento Simple form também pode ser usado)

No lado do controlador

@RequestMapping(value = "/test-example", method = RequestMethod.POST)
public ModelAndView testExample(@ModelAttribute("testModelAttribute") TestModel testModel, Map<String, Object> map,...) {

}

Agora, quando você enviar o formulário, os valores dos campos estarão disponíveis para você.

Awais
fonte
4

Anotação que liga um parâmetro de método ou valor de retorno de método a um atributo de modelo nomeado, exposto a uma visualização da web.

public String add(@ModelAttribute("specified") Model model) {
    ...
}
Byeon0gam
fonte
3

@ModelAttribute pode ser usado como argumento / parâmetro do método ou antes da declaração do método. O objetivo principal desta anotação para vincular os parâmetros de solicitação ou campos de formulário a um objeto de modelo

Ref. http://www.javabeat.net/modelattribute-spring-mvc/

Chethan D
fonte
1

@ModelAttributecriará um atributo com o nome especificado por você (@ModelAttribute("Testing") Test test) as Testing no exemplo dado, Test sendo o teste do bean sendo a referência ao bean e Testing estará disponível no modelo para que você possa usá-lo ainda mais nas páginas jsp para recuperar os valores armazenados em você ModelAttribute.

Gagan
fonte
1

O @ModelAttribute simplesmente vincula o valor dos campos jsp ao Pojo calss para executar nossa lógica na classe do controlador. Se você está familiarizado com struts, é como preencher o objeto formbean após o envio.

Ragu Venkatesan
fonte
0

A anotação ModelAttribute é usada como parte de um aplicativo Web Spring MVC e pode ser usada em dois cenários.

Primeiro de tudo, ele pode ser usado para injetar dados em um modelo de carregamento pré-JSP. Isso é especialmente útil para garantir que um JSP seja necessário para exibir todos os dados em si. Uma injeção é obtida conectando um método ao modelo.

Segundo, ele pode ser usado para ler dados de um modelo existente e atribuí-lo aos parâmetros do método do coach.

refrence https://dzone.com/articles/using-spring-mvc%E2%80%99s

ismael
fonte
0

No nível do método

1. 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

@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("india", "india");
}

No argumento do método 1. Quando usado como argumento do método, indica que o argumento deve ser recuperado do modelo. Quando não está presente e deve ser instanciado primeiro e, em seguida, adicionado ao modelo e, uma vez presentes no modelo, os campos de argumentos devem ser preenchidos a partir de todos os parâmetros de solicitação que tenham nomes correspondentes. Portanto, ele vincula os dados do formulário a um bean.

 @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
  public String submit(@ModelAttribute("employee") Employee employee) {
  return "employeeView";
  }
Vivek Srivastava
fonte