struts2의 세 가지 방식으로 요청 매개 변수를 받아들인다

12964 단어 struts2
ModelDriven
 
ModelDriven이 필요한 이유
 
ModelDriven이란 실체 클래스를 페이지 데이터의 수집 대상으로 직접 간주한다는 뜻이다.예를 들어, 다음과 같은 솔리드 클래스 User가 있습니다.

package cn.com.leadfar.struts2.actions; 

  

public class User { 

    private int id ; 

    private String username ; 

    private String password ; 

    private int age ; 

    private String address ; 

    public String getUsername() { 

       return username ; 

    } 

    public void setUsername(String username) { 

       this . username = username; 

    } 

    public String getPassword() { 

       return password ; 

    } 

    public void setPassword(String password) { 

       this . password = password; 

    } 

    public int getAge() { 

       return age ; 

    } 

    public void setAge( int age) { 

       this . age = age; 

    } 

    public String getAddress() { 

       return address ; 

    } 

    public void setAddress(String address) { 

       this . address = address; 

    } 

    public int getId() { 

       return id ; 

    } 

    public void setId( int id) { 

       this . id = id; 

    } 

    

    

} 

 

Action을 작성하려면 User를 추가합니다.
첫 번째 방법은 Action에서 필요한 모든 속성을 직접 정의한 다음 JSP에서 직접 속성 이름으로 데이터를 제출하는 것입니다.


UserAction: 

public class UserAction { 

    private int id ; 

    private String username ; 

    private String password ; 

    private int age ; 

    private String address ; 

  

    public String add(){ 

       

       User user = new User(); 

       user.setId( id ); 

       user.setUsername( username ); 

       user.setPassword( password ); 

       user.setAge( age ); 

       user.setAddress( address ); 

       

       new UserManager().addUser(user); 

       

       return "success" ; 

    } 

    

    public int getId() { 

       return id ; 

    } 

    public void setId( int id) { 

       this . id = id; 

    } 

    public String getUsername() { 

       return username ; 

    } 

    public void setUsername(String username) { 

       this . username = username; 

    } 

    public String getPassword() { 

       return password ; 

    } 

    public void setPassword(String password) { 

       this . password = password; 

    } 

    public int getAge() { 

       return age ; 

    } 

    public void setAge( int age) { 

       this . age = age; 

    } 

    public String getAddress() { 

       return address ; 

    } 

    public void setAddress(String address) { 

       this . address = address; 

    } 

    

} 
 

 

add_input.jsp: 

     < form action = "test/user.action" method = "post" > 

        < input type = "hidden" name = "method:add" > 

        username: < input type = "text" name = "username" > < br /> 

        password: < input type = "text" name = "password" > < br /> 

        age: < input type = "text" name = "age" > < br /> 

        address: < input type = "text" name = "address" > < br /> 

        < input type = "submit" name = "submit" value = "      " > 

     </ form > < br /> 
 

솔리드 클래스의 속성이 매우 많으면 Action에서도 동일한 속성을 정의해야 합니다.
 
 
두 번째 방법은 User 객체를 UserAction에 정의한 다음 JSP에서 사용자 속성으로 사용자 값을 지정하는 것입니다.

UserAction: 

public class UserAction { 

    

    private User user ; 

    

    public String add(){ 

  

       new UserManager().addUser( user ); 

       

       return "success" ; 

    } 

  

    public User getUser() { 

       return user ; 

    } 

  

    public void setUser(User user) { 

       this . user = user; 

    } 

    

    

} 
 

 

add_input.jsp: 

     < form action = "test/user.action" method = "post" > 

        < input type = "hidden" name = "method:add" > 

        username: < input type = "text" name = "user.username" > < br /> 

        password: < input type = "text" name = "user.password" > < br /> 

        age: < input type = "text" name = "user.age" > < br /> 

        address: < input type = "text" name = "user.address" > < br /> 

        < input type = "submit" name = "submit" value = "      " > 

     </ form > < br /> 

이런 방법이 좋지 않은 점은 JSP 페이지의 폼 필드의 이름이 너무 길어졌다는 것이다
 
세 번째 방법은 ModelDriven 메커니즘을 이용하여 Useraction이 ModelDriven 인터페이스를 실현하고 인터페이스의 방법인 getModel()을 실현하는 것이다.다음과 같습니다.

public class UserAction implements ModelDriven{ 

    

    private User user ; 

    

    @Override 

    public Object getModel() { 

       if ( user == null ){ 

           user = new User(); 

       } 

       return user ; 

    } 

  

    public String add(){ 

  

       new UserManager().addUser( user ); 

       

       return "success" ; 

    } 

  

    public User getUser() { 

       return user ; 

    } 

  

    public void setUser(User user) { 

       this . user = user; 

    } 

} 

JSP 코드는 다음과 같습니다.


     < form action = "test/user.action" method = "post" > 

        < input type = "hidden" name = "method:add" > 

        username: < input type = "text" name = "username" > < br /> 

        password: < input type = "text" name = "password" > < br /> 

        age: < input type = "text" name = "age" > < br /> 

        < input type = "submit" name = "submit" value = "      " > 

     </ form > < br /> 
 

 
이를 통해 알 수 있듯이 세 번째 방법은 비교적 좋다. Action과 JSP는 쓰기가 비교적 간단하다.
 
 
ModelDriven 배후의 메커니즘은?
 
ModelDriven의 배후 메커니즘은 바로ValueStack이다.인터페이스는:username/age/address와 같은 이름을 통해user 대상에게 직접 값을 부여할 수 있습니다. 이것은user 대상이 바로Value Stack의 루트 대상임을 증명합니다!
 
그렇다면 사용자 객체가 ValueStack에 있는 이유는 무엇입니까?얘는 밸러스트에 언제 눌렸을까요?답은: ModelDrivenInterceptor(Interceptor의 개념에 대해서는 다음 장의 설명을 참조하십시오).ModelDrivenInterceptor는 부족한 차단기 체인의 일부입니다. 요청이 ModelDrivenInterceptor를 통과할 때, 이 차단기에서 현재 호출하려는 Action 대상이 ModelDriven 인터페이스를 실현했는지 판단하고, 이 인터페이스를 실현하면 getModel () 방법을 호출하고, 되돌아오는 값 (이 예는user 대상으로 되돌아오는 것) 을Value Stack에 눌러 넣습니다.
ModelDrivenInterceptor 코드를 보십시오.


public class ModelDrivenInterceptor extends AbstractInterceptor { 

  

    protected boolean refreshModelBeforeResult = false ; 

  

    public void setRefreshModelBeforeResult( boolean val) { 

        this . refreshModelBeforeResult = val; 

    } 

  

    @Override 

    public String intercept(ActionInvocation invocation) throws Exception { 

        Object action = invocation.getAction(); 

  

        if (action instanceof ModelDriven) { 

            ModelDriven modelDriven = (ModelDriven) action; 

            ValueStack stack = invocation.getStack(); 

            Object model = modelDriven.getModel(); 

            if (model !=  null ) { 

              stack.push(model); 

            } 

            if ( refreshModelBeforeResult ) { 

                invocation.addPreResultListener( new RefreshModelBeforeResult(modelDriven, model)); 

            } 

        } 

        return invocation.invoke(); 

    } 
 

ModelDrivenInterceptor에서 모델 대상이 Value Stack에 눌려 있는 것을 볼 수 있습니다.
 
그중의refreshModelBeforeResult는 다음에 기술한 문제 하나를 위한 해결 방법입니다.
 
흔히 볼 수 있는 함정과 그 해결 방법을 이해하다
 
솔리드 객체를 업데이트한다고 가정하면 첫 번째 단계는 업데이트 인터페이스를 여는 것입니다. 다음 아날로그에서 업데이트 인터페이스를 여는 코드를 보십시오.

public class UserAction implements ModelDriven{ 

    

    private User user ; 

    

    @Override 

    public Object getModel () { 

       if ( user == null ){ 

           user = new User(); 

           //user.setUsername("       User    "); 

       } 

       return user ; 

    } 

    

    public String updateInput(){ 

       

       //    ID ,     ,   User    

       user = new UserManager().findUserById( user .getId()); 

       

       

       return "update_input" ; 

    } 
 

 
위 코드의 new UserManager().findUserById(user.getId()); 이 행은 데이터베이스에서 해당 레코드를 조회하고 User 객체로 변환하여 반환합니다.return "update input"디스플레이 업데이트 페이지로 이동합니다.
 
업데이트 페이지는 다음과 같습니다.


     < form action = "test/user.action" method = "post" > 

        < input type = "hidden" name = "method:update" > 

        id: < input type = "text" name = "id" value = "< s:property value = "id" /> "> < br /> 

        username: < input type = "text" name = "username" value = "< s:property value = "username" /> "> < br /> 

        password: < input type = "text" name = "password" value = "< s:property value = "password" /> "> < br /> 

        age: < input type = "text" name = "age" value = "< s:property value = "age" /> "> < br /> 

        address: < input type = "text" name = "address" value = "< s:property value = "address" /> "> < br /> 

        < input type = "submit" name = "submit" value = "      " > 

     </ form > < br /> 
 

 
 
상기 코드가 실행된 후, 업데이트 인터페이스에서 데이터를 볼 수 없습니다. (id 속성은 값이 있고, 다른 속성은 표시되지 않습니다.)관건적인 이유는 업데이트 Input을 실행하기 전에user 대상(getMode () 방법에서 만든 대상)이Value Stack에 눌렸기 때문이다. 이때Useraction과Value Stack은 모두 같은user 대상을 가리킨다.그러나 이어서 Useraction의user는 새user 대상에 덮어씌워집니다. 이 때 Useraction과Value Stack은 같은user 대상을 가리키지 않습니다.ValueStack에는 이전 사용자 객체가 있고 Useraction에는 새 사용자 객체가 있습니다!Google은 JSP에서username/address 등을 통해 직접 접근합니다.Value Stack의 구user 대상에 직접 접근해야 하기 때문에 그들의 속성은 모두 비어 있습니다 (id 속성 제외)!
 
상술한 문제를 이해하는 것은 매우 중요하다. 문제를 이해하면 문제의 해결 방법은 매우 많다.
예를 들어, 당신은 새로운 대상의 속성을 옛 대상에 복사할 수 있다.예를 들어, 당신은 먼저 오래된 대상을ValueStack에서 제거한 후에, 다시 새로운 대상을ValueStack에 눌러 넣을 수 있다.
 
최신struts2버전에서ModelDrivenInterceptor는 설정 파라미터를 제공합니다:refreshModelBeforeResult. 이것을true로 정의하면 상술한 문제가 해결됩니다.struts2의 해결 방안은 먼저 낡은 모델 대상을Value Stack에서 제거한 다음에 새로운 모델 대상을Value Stack에 눌러 넣는 것이다!

좋은 웹페이지 즐겨찾기