Valores de @PathVariable e @ModelAttribute sobrepostos

9

Eu tenho um objeto User armazenado na sessão com @SessionAttributes . E um método direto decorado com @ModelAttribute para inicializá-lo sempre que o valor da sessão for nulo.

Classe de usuário:

@Entity
@Table( name="USER")
public class User implements java.io.Serializable {

    private Long id;
    private String username;
    private String password;
    ....

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name ="ID")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    ...

Controlador:

@RequestMapping("/item")
@Controller
@SessionAttributes({"user"})
public class MyController {

Método @ModelAttribute:

@ModelAttribute("user")
    public User createUser(Principal principal) {
        return userService.findByUsername(principal.getName());
    }

Tudo parece funcionar como esperado, exceto neste método específico:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String showItem(@PathVariable("id") Long id, @ModelAttribute("user") User user,
            Model uiModel) {
   ...    
}

O problema é que User.id está sendo definido com @PathVariable("id") . Eu acredito que eu corri para isso com @RequestParam também. Estou assumindo que é porque ambos têm o mesmo nome e tipo. Depois de ler a documentação do Spring (veja abaixo) Estou assumindo que este é o comportamento esperado:

  

O próximo passo é a vinculação de dados. A classe WebDataBinder corresponde nomes de parâmetros de solicitação - incluindo parâmetros de string de consulta e campos de formulário - para modelar campos de atributos por nome. Os campos correspondentes são preenchidos após a conversão de tipo (de String para o tipo de campo de destino) ter sido aplicada quando necessário.

No entanto, eu acho que esse cenário é bastante comum, como outras pessoas lidam com isso? Se minhas descobertas estiverem corretas e isso for um comportamento esperado (ou bug), isso parece ser muito propenso a erros.

Soluções possíveis:

  1. Altere @PathVariable("id") para @PathVariable("somethingElse") . Funciona, mas não é tão simples com @RequestParam (por exemplo, não sei como alterar o id do parâmetro de solicitação do jqgrid para outra coisa, mas esse é outro problema).
  2. Altere o tipo @PathVariable("id") de Long para Int. Isso fará com que User.id e id tipos sejam diferentes, mas o lançamento para Long parece feio:)
  3. Não use @ModelAttribute aqui e consulte o banco de dados por User novamente. Não é consistente com outros métodos e envolve chamadas DB redundantes.

Alguma sugestão?

    
por Ulises 23.07.2012 в 21:09
fonte

2 respostas

5

Como sobre essa abordagem -

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String showItem(@PathVariable("id") Long id,
            Model uiModel) {
       User user = (User)uiModel.asMap().get("user");
   ...    
}
    
por Biju Kunjummen 24.07.2012 / 02:04
fonte
0

use @SessionAttribute

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String showItem(@PathVariable("id") Long id, @SessionAttribute("user") User user,
            Model uiModel) {
   ...    
}
    
por psy 10.01.2018 / 12:49
fonte