Spring MVC 3.0: как связать с постоянным объектом - PullRequest
5 голосов
/ 09 сентября 2010

Я работаю с Spring MVC, и мне бы хотелось, чтобы он связывал постоянный объект из базы данных, но я не могу понять, как я могу настроить свой код для вызова БД перед привязкой. Например, я пытаюсь обновить объект «BenefitType» в базе данных, однако я хочу, чтобы он получал объект из базы данных, а не создавал новый, поэтому мне не нужно обновлять все поля.

    @RequestMapping("/save")
public String save(@ModelAttribute("item") BenefitType benefitType, BindingResult result)
{
    ...check for errors
    ...save, etc.
}

Ответы [ 4 ]

4 голосов
/ 09 сентября 2011

Таким образом, я решил эту проблему, добавив к методу метод @ModelAttribute с тем же именем в классе.Spring сначала строит модель перед выполнением отображения запроса:

@ModelAttribute("item")
BenefitType getBenefitType(@RequestParam("id") String id) {
    // return benefit type
}
4 голосов
/ 09 сентября 2010

Существует несколько вариантов:

  • В простейшем случае, когда ваш объект имеет только простые свойства, вы можете привязать все его свойства к полям формы (hidden при необходимости) иполучить полностью связанный объект после отправки.Сложные свойства также можно привязать к полям формы с помощью PropertyEditor s.

  • Вы также можете использовать сеанс для хранения вашего объекта между GET и POST запросами.Spring 3 облегчает этот подход аннотацией @SessionAttributes (из образца Petclinic ):

    @Controller
    @RequestMapping("/owners/*/pets/{petId}/edit")
    @SessionAttributes("pet") // Specify attributes to be stored in the session       
    public class EditPetForm {    
        ...
        @InitBinder
        public void setAllowedFields(WebDataBinder dataBinder) {
            // Disallow binding of sensitive fields - user can't override 
            // values from the session
            dataBinder.setDisallowedFields("id");
        }
        @RequestMapping(method = RequestMethod.GET)
        public String setupForm(@PathVariable("petId") int petId, Model model) {
            Pet pet = this.clinic.loadPet(petId);
            model.addAttribute("pet", pet); // Put attribute into session
            return "pets/form";
        }
        @RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST })
        public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
            new PetValidator().validate(pet, result);
            if (result.hasErrors()) {
                return "pets/form";
            } else {
                this.clinic.storePet(pet);
                // Clean the session attribute after successful submit
                status.setComplete();
                return "redirect:/owners/" + pet.getOwner().getId();
            }
        }
    }
    

    Однако этот подход может вызвать проблемы, если несколько экземпляров формы открыты одновременно в одном и том жесеанс.

  • Итак, наиболее надежный подход для сложных случаев - создать отдельный объект для хранения полей формы и вручную объединить изменения из этого объекта в постоянный объект.

0 голосов
/ 09 сентября 2010

Я немного растерялся. Я думаю, что вы на самом деле говорите о процессе обновления?

Вам нужно два @RequestMappings, одно для GET и одно для POST:

@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
public String getSave(ModelMap model, @PathVariable Long id)
{
    model.putAttribute("item", benefitDao.findById(id));
    return "view";
}

тогда на POST фактически обновите поле.

В приведенном выше примере ваш @ModelAttribute уже должен быть заполнен методом, подобным описанному выше, и свойства должны быть связаны с использованием чего-то вроде JSTL или Spring tabglibs вместе с объектом поддержки формы.

Вы также можете посмотреть InitBinder в зависимости от вашего варианта использования.

0 голосов
/ 09 сентября 2010

Хотя модель вашего домена настолько проста, что вы можете привязать объекты пользовательского интерфейса непосредственно к объектам модели данных, более вероятно, что это не так, и в этом случае я настоятельно рекомендую вам разработать класс специально для формы. связывание, а затем переводить между ним и объектами домена в вашем контроллере.

...