Spring Mvc ModelAttribute with referencing name is

2019-08-29 03:15发布

问题:

I want to to create different @Entity entities within the same Controller.

@RequestMapping(value="create", method=RequestMethod.GET)
public String  GET(Model model) throws InstantiationException, IllegalAccessException
{
    Class<?> clazz = ????; // a Random POJO is chosen, i want to use POJOs!!

    Object object = clazz.newInstance();
    model.addAttribute("object", object);
    return "create";        
}

@RequestMapping(value="create", method=RequestMethod.POST)
public @ResponseBody Object POST(@ModelAttribute(value="object") Object object)
{
    System.out.println("POST! got type: " + object.getClass().getName());
    return object;
}

In the Post Method I get NULL for @ModelAttribute(value="object") Object object

If I change it to @ModelAttribute(value="object") realType object it is working perfectly fine. But I don't know the type yet.

I thought the @ModelAttribute can achieve this anyway with the name "object" but apparently not. What am I missing?

回答1:

There is no actual model object named object when you submit, spring constructs it based on the parameter type and will bind the properties accordingly.

You have 2 choices to make it work

  1. Store the object in the session
  2. Use a @ModelAttribute annotated method

If neither of these are there spring will simply look at the method argument and use reflection to construct an instance of that class. So in your case it will only be Object and after that binding will fail.

Store object in the session

@Controller
@SessionAttributes("object")
public class MyController { ... }

Make sure that when you are finished that you call the setComplete() method on a SessionStatus object.

Use a @ModelAttribute annotated method

Instead of creating and adding the object in a request handling method create a speficic method for it.

@ModelAttribute("object")
public Object formBackingObject() {
    Class<?> clazz = ????; // a Random POJO is chosen, i want to use POJOs!!

    Object object = clazz.newInstance();
    return object;
}

This method will be called before each request handling method, so that a newly fresh object is constructed which will be used for binding.