2012-11-22 3 views
1

설명 :내가이 클래스가이 스프링 MVC 컨트롤러 동작

@Component 
@Scope("session") 
@Entity 
@Table(name = "users") 
public class User { 

    @Id 
    @GeneratedValue 
    @GenericGenerator(name = "incremental", strategy = "increment") 
    private Long userID; 

    @Column(nullable = false) 
    private String username; 

    @Column(nullable = false) 
    private String email; 

    @Column(nullable = false) 
    private String password; 
    // getters and setters 
} 

그리고이 컨트롤러 :

@Controller 
@SessionAttributes("user") 
@Scope("request") 
public class UserCreationWizard { 
    @Autowired 
    private User user; 

    @ModelAttribute("user") 
    private User createUser() { 
     return user; 
    } 

    @RequestMapping(value = "/new/users/page/", method = RequestMethod.GET) 
    public String begin(HttpServletRequest request) { 
     return "wizard"; 
    } 

    @RequestMapping(value = "/new/users/page/{page}", method = RequestMethod.POST) 
    public String step(@ModelAttribute("user") User user, 
         @RequestParam("username") String username, 
         @RequestParam("email") String password, 
         @PathVariable() Integer page) { 

     return "wizard" + page; 
    } 

    @RequestMapping(value = "/new/users/page/end", params = "submit", method = RequestMethod.POST) 
    public String end(@RequestParam("password") String password) { 

     user.setPassword(password); 
     user.setActive(true); 
     user.setLastLoggedIn(Calendar.getInstance()); 

     Session s = HibernateUtils.getSessionFactory().openSession(); 
     Transaction t = s.beginTransaction(); 
     try { 
      s.persist(user); 
      s.flush(); 
      t.commit(); 

      s.close(); 
     } catch (HibernateException e) { 
      t.rollback(); 
     } 
     return "wizard"; 
    } 
} 

begin()

그냥 사용자 생성 마법사의 첫 번째보기 (는 JSP)를로드합니다. usernameemail에 대한 입력란이 있습니다. 보기에서 step()을 트리거하는 POST 양식 제출을 작성합니다. 두 번째보기 (wizard + page.jsp)에는 password 필드와 end()을 트리거하는 제출 입력이 있습니다.

  1. 디버그 모드에서 나는 ModelAttribute 모 데르로 사용자를 통과 한 step()에, 나는 이름과 암호를 해당 필드를 설정할 필요가 없습니다 것으로 나타났습니다. 그들은 RequestParams 속성에서 자동으로 부여받습니다. 그러나 end()에서는 ModelAttribute가없는 곳에서 암호를 수동으로 설정해야합니다. Spring은 이것을 어떻게 관리합니까?
  2. 또한 컨트롤러에서 createUser() 메서드를 제거하면 "user"에 대한 세션 특성을 찾을 수 없다는 메시지가 나타나면서 응용 프로그램이 실패합니다. 이 메서드는 MethodAttribute에 메서드 매개 변수로 어떻게 연결되어 있습니까?
  3. 마지막으로, @SessionAttributes를 꺼내면 응용 프로그램이 실패하지는 않지만 뭔가 잘못 될 것으로 생각됩니다. 사용자 사용자가 이제 모든 httprequests에 대해 글로벌가됩니까?

내 일반적인 질문은 다음과 같습니다. 스프링 콩을 이름에 매핑합니까? 예 : 여기에는 사용자로서 '사용자'와 세션에서 '사용자', 요청 매개 변수로 '암호', 사용자 멤버 변수로 '암호'가 있습니다.

+0

무례한 것은 아니지만 대부분의 사람들은 사람들이 질문을 게시하기 전에 노력했다는 것을 알고 싶어합니다. – madth3

답변

1

좋습니다. 많은 질문이 있습니다. 보자. 모든 참조는 현재 Spring MVC 버전의 문서에있다.

1) 당신이 user 속성에 표시되는 동작이 섹션에 설명되어 있습니다 "Using @ModelAttribute on a method argument는"메소드 인수에

@ModelAttribute는 인수가 모델에서 검색해야 나타냅니다. 모델에없는 경우에는 인수를 먼저 인스턴스화 한 다음 모델에 추가해야합니다. 모델에 이 있으면 모델의 일치하는 이름을 가진 모든 요청 매개 변수의 인수 필드를 채워야합니다. 이것은 스프링 MVC에서 데이터 바인딩으로 알려져 있습니다. 에서 각 폼 필드를 개별적으로 구문 분석해야하는 번거 로움을 덜어줍니다.

스프링은 어떻게합니까? 음, 소스 코드는 궁극적 인 대답이지만, 추측하기가 그리 어렵지 않습니다. 인수가 User의 인스턴스이고 리플렉션을 통해 클래스의 메소드, 특히 설정 자을 읽을 수 있음을 Spring은 알고 있습니다. 이 경우 setUsername()setEmail()이 있고 해당 메소드의 인수는 String이므로 요청의 매개 변수와 호환됩니다.

(BTW : @RequestParam("email") String password은 실수 일 수 있습니다.적어도 혼란 스럽습니다.)

2) 방법 createUser() 앞에는 @ModelAttribute("user")이라는 주석이 붙습니다. 이것은 섹션 "Using @ModelAttribute on a method는"방법에

@ModelAttribute 그 방법의 목적은 하나 개 이상의 모델 속성을 추가 할 수 을 나타냅니다이 적용됩니다.

따라서,이 방법은 모델 이름 "user"와 관련된 대상을두고 다음 step() 같은 다른 방법에 의해 파라미터로서 사용 할 수있다. 어노테이션은 모델의 객체가 사용하는 식별자를 제어합니다. 코드를

으로 변경하면 앱이 중단됩니다. 하지만

public String step(@ModelAttribute("strangeWeirdIdentifier") User user, 
        @RequestParam("username") String username, 
        @RequestParam("email") String password, 
        @PathVariable() Integer page) { 

3) 1에 설명 된 프로세스에 step() 서명을 변경할 경우 다시 작동합니다) 2) 저장 요청시 모델 객체. 클래스 주석 @SessionAttributes("user")을 사용하면 객체의 수명을 현재 Session 또는 이와 동등한 항목으로 추가하여 연장 할 수 있습니다. 예를 들어 step() 메서드와 동일하게 다른 Controller의 개체를 사용할 수 있습니다. 마지막으로

은 명확합니다

    질문 2에서 볼 주석이 질문 질문 3 1.
  • 주석을 볼 사용하기 전에 발생
  • 아마
  • 봄이하는 필요하지 않습니다 Bean을 Java 코드의 이름으로 맵핑하지 않고 주석에 사용 된 이름으로 맵핑하십시오. 명확성을 위해 예제에서와 동일한 이름을 반복하는 것은 드문 일이 아닙니다.

호프는이 문서가 공식 문서보다 더 분명하기를 바라며, 일반적으로 너무 짧습니다.

관련 문제