2012-12-22 7 views
5

Spring MVC 모델 Bean의 일부만을 표시 할 때 모델에서 브라우저에서 되돌아 오는 것을 업데이트하는 방법이 있습니까?Spring MVC + Hibernate : 브라우저에서 부분 모델 업데이트

의 우리가 (물론, 단지이 예에서는 공용 속성)를 사용자 클래스가 있다고 가정 해 봅시다 :

public class User { 
    public String firstName; 
    public String lastName; 
    public String email; 
    public Date subscriptionExpiration; 
} 

지금 나는 JSP에서 입력 필드로 처음 세 속성을 표시하고있는 개체를 업데이트 할 그에 따라 데이터베이스. 이 세 매개 변수 만 업데이트해야하며 네 번째 매개 변수는 업데이트하지 않아야합니다. 한 가지 방법은이

@RequestMapping("/user/{userId}", method=RequestMethod.POST) 
public String saveChanges(@PathVariable userId, User user, Model model) { 
    User oldUser = User.loadFromDB(userId); 
    oldUser.firstName = user.firstName; 
    oldUser.lastName = user.lastName; 
    oldUser.email = user.email; 
    oldUser.saveToDB(); 

    model.addAttribute("user", oldUser); 
} 

될 것이다 달성하기 그러나 이것은 너무 많이 좋아하지 않아 변경할 수있는 모든 속성을 하드 코딩하는 것을 의미한다.

사용자가 변경할 수있는 항목에 따라 업데이트 할 필드를 결정하는 방법이 있습니까? 이 메커니즘은 요청 매개 변수에있는 모든 것이 변경 될 수 있다고 가정하는 것보다 더 똑똑해야합니다. 그렇지 않으면 정통한 사용자가 수동으로 추가 필드를 요청에 삽입 할 수 있습니다.

@Entity (dynamicUpdate = true)를 사용하면 내 사용자의 모든 객체가 요청으로 돌아 오지 않아 문제가 해결되지 않으며 많은 보안 구멍이 열리게됩니다.

봄에 멋진 기능이 없거나 개념적으로이 문제를 해결할 다른 방법이 있습니까? 어떤 힌트도 대단히 감사하겠습니다!

답변

3

@InitBinder를 사용하여 일부 모델 필드가 Spring에서 매개 변수를 요청하도록 허용/금지하는 방법을 알고 싶다면 this question을 참조하십시오. 이를 통해 요청 매개 변수를 주입하여 subscriptionExpiration을 수정할 수 없도록 할 수 있습니다.

메소드 및 메소드 인수에서 @ModelAttribute 주석을 사용하여 @RequestMapping 메소드가 호출되기 전에 데이터베이스에서 사용자를로드하여 모델에 추가하고 요청 매개 변수로이 사용자를 채우는 방법은 the documentation을 참조하십시오. @RequestMapping 메서드가 호출 될 때. 이것은 DB로부터 사용자를 얻는 것을 허락하고 Spring이 요청으로부터 오는 값으로 그것을 채우도록한다. 사용자의 새로운 상태를 확인하고 데이터베이스에 저장하기 만하면됩니다.

2

나는

BeanUtils.copyProperties(Object source, Object target, String[] ignoreProperties) 

당신이 원하는 것을 수행하는 방법을 생각한다. String[] ignoreProperties에 정의 된 속성을 건드리지 않고 한 개체에서 다른 개체로 모든 속성을 복사합니다.

주어진 소스 bean의 특성 값을 지정된 "ignoreProperties"를 무시하고 주어진 대상 bean에 복사하십시오.

참고 : 소스와 대상 클래스는 속성이 일치하는 한 서로 일치하거나 심지어 파생되지 않아도됩니다. 소스 bean이 노출하지만 대상 bean이 노출하지 않는 bean 특성은 자동으로 무시됩니다.

이것은 단지 편리한 방법 일뿐입니다. 좀 더 복잡한 전송 요구를 위해서는 전체 BeanWrapper 사용을 고려하십시오.

API Documentation

+0

당분간 나는 이와 같은 작업을 수행했습니다. 필자는 필드에 사용자 정의 주석을 사용하여 업데이트할지 여부를 결정한 다음 ignoreProperties 목록을 제공하도록 파싱합니다. 잘 작동하지만 수동으로 정의하는 것을 피하고 싶습니다. 입력에 감사드립니다! – usimon

0

먼저 데이터베이스에서 개체를 읽은 다음 요청을 바인딩 할 수 있습니다. 예제는 FuWeSta-Sample에서 찾을 수 있습니다.

스프링으로 초기화해야하는 helper-bean을 사용합니다.

0

한 가지 옵션은 양식에서 숨겨진 필드를 사용하는 것입니다. draw backs 옵션이 있지만 경우에 따라 작동합니다.

0

찾고있는 멋진 기능은 @ModelAttribute입니다. 양식에 사용자 ID도 게시한다고 가정합니다.

public class UserController { 

    @ModelAttribute 
    public User getUser(@RequestParam(value = "id", required = false) Long id) { 
     return User.loadFromDB(id); 
    } 

    @RequestMapping("/user/{id}", method=RequestMethod.POST) 
    public String saveChanges(@ModelAttribute User user, BindingResult bindingResult, Model model) { 

     if (bindingResult.hasErrors()) { 
      // return ... 
     } 

     // model.asMap().clear(); 

     user.saveToDB(); 
     // return ... 
    } 
} 
관련 문제