2014-01-08 1 views
4

다음 액션 클래스를 가정합니다.Struts2의 prepare() 메소드와 함께 액션 클래스에서 CRUD 연산 수행

@Namespace("/admin_side") 
@ResultPath("/WEB-INF/content") 
@ParentPackage(value="struts-default") 
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, Preparable 
{ 
    private Long currentPage=1L; 

    //This method is called on page load. 
    //Validation is skipped, location is set to a valid action, not "redirectAction", the request is dispatched. 
    //It is mapped to an action of <s:form>. 
    public String load() throws Exception 
    { 
     //Nothing to see here. Leave it empty. 
     return ActionSupport.SUCCESS; 
    } 

    //Assuming necessary validators and action whose result type is set to "redirectAction". 
    //It is mapped to an action of <s:submit>. 
    public String insert() 
    { 
     //Do something to either add or update data in a model based on a conditional check. 
     return ActionSupport.SUCCESS; 
    } 

    //Assuming necessary validators and action whose loction is set to a valid action. not "redirectAction". 
    //The request is dispatched/forwarded. 
    //It is mapped to an action of <s:a>. 
    public String edit() 
    { 
     //Nothing to see here. Leave it empty. 
     return ActionSupport.SUCCESS; 
    } 

    //Assuming necessary validators and action whose result type is set to "redirectAction". 
    //It is mapped to an action of <s:submit>. 
    public String delete() 
    { 
     //Do something to delete data from a model. 
     return ActionSupport.SUCCESS; 
    } 

    @Override 
    public void prepare() throws Exception 
    { 
     list= service.getList((int)(currentPage-1)*pageSize, pageSize); 
    } 
} 

나는 코드 노이즈를 피하기 위해 주석 및 기타 사항을 찾았다. 이 메소드에 매핑 된 작업은 paramsPrepareParamsStack 인터셉터를 사용합니다.

예를 들어 과 관련된 작업이 실행되면 (예 : <s:submit>) 완료되면 작업이 리디렉션됩니다. 따라서, 액션 클래스의 새로운 인스턴스가 생성되어 load() 메서드가 실행되어 다시 prepare() 메서드가 다시 실행됩니다. 업데이트 및 삭제 중에도 동일한 문제가 발생합니다.

prepare() 방법 제 <s:submit> (또는 <s:link>)와 연관된 동작하자마자 실행 트리거되고 요청이 재 때 다시 (이는 이해할 수

때문에 새로운 인스턴스를 만드는 요청 결과 리디렉션 load() 메서드와 관련된 동작을 실행시키는 동작 클래스이며 prepare()은 모든 동작마다 한 번 실행됩니다.

prepare() 메서드 내의 유일한 행에는 값 비싼 연산이 있습니다. getList() 메서드가 두 번 실행되는 것을 방지하기 위해 다음과 같은 조건부 검사를 수행합니다.

@Override 
public void prepare() throws Exception 
{ 
    String actionName = ActionContext.getContext().getName(); 
    if(actionName.equals("load")||actionName.equals("edit")) 
    { 
     list= service.getList((int)(currentPage-1)*pageSize, pageSize); 
    } 
} 

이 방법에는 더 많은 조건부 검사와 복잡한 코드가있을 수 있습니다.

그래도 여전히 충분하지 않습니다. 조건으로 인해 유효성 검사/변환 오류가 발생하면 목록이 초기화되지 않습니다. 오류가 발생한 후 hasErrors(), hasActionErrors()hasFieldErrors() 중 하나는 prepare() 메서드에서 true로 평가됩니다. 이렇게하려면 목록을 다음과 같이 validate() 메서드 안에로드해야합니다.

@Override 
public void validate() 
{ 
    if(hasErrors()) 
    { 
     list= service.getList((int)(currentPage-1)*pageSize, pageSize); 
    } 
} 

이것은 이제 요구 사항을 충족 시키지만 이러한 조건부 검사를하기에는 매우 추해 보입니다. 좋은 접근 방식으로 간주 될 수 없습니다.

삽입, 업데이트, 삭제와 같은 작업을 수행하라는 요청이 한 번만 발생하면 데이터베이스에서 목록 검색을 수행하는 더 나은 방법이 있습니까?

요청 당 장면 뒤에서 실행되는 작업 수와는 무관해야합니다. 일부 변환/유효성 검사 오류가 있지만 목록은 요청 완료 직전에 한 번만 검색해야합니다.

아무 것도 @Before, @BeforeResult, @After 중 아무 것도이 상황을 피하기 위해 작동하지 않는 것 같습니다. 좋은 방법이 될 것 같지 않습니다 목록을 초기화/검색을 의미하는 validate() 방법과 같은 코드를 사용


.

CRUD 작업 후이 목록을 가져 오는 방법이 있습니다. .데이터베이스에서이 목록을 가져 오는 것이 값 비싸기 때문에이 작업 목록은 이후에 한 번만 으로 초기화해야합니다 (삽입, 편집, 업데이트, 삭제)가 완료되었습니다.

+2

나는 잘 모르겠다. 리디렉션을 수행하면 새로운 작업을 수행하고 새로운 데이터가 필요합니다. 유효성 검사 오류가 있으면'input()'메서드가 실행됩니다. 'prepare()'의 체크를 하드 코딩하거나'prepareXxx()'메소드를 만들 수 있습니다. 여기서'xxx'는리스트가 필요한 메소드의 이름으로 대체됩니다. 모든 것을 제외하고 캐싱을 고려하십시오. –

+0

모든 작업마다'prepare'가 호출되고, 유효성 검사 당'validate'가 호출되며, 둘 다 다른 작업을합니다. 당신이 제공되는 방법을 고집했다. 자신 만의 메서드를 만들거나 자신의 클래스를 만들고 필요한 경우 해당 메서드 나 클래스를 호출합니다. –

답변

3

모든 동작에 대해 실행되는 prepare 방법을 사용하는 경우 목록을 채우는 것과 같이 무거운 작업은 좋은 방법이 아닙니다. 모든 작업이 이러한 작업을 수행 할 필요는 없기 때문입니다. 그러나 유효성 검사와 함께 사용하면 아무 작업도 전혀 실행되지 않습니다. 유효성 검증 오류가 _ 생하면 INPUT 결과가 리턴됩니다. 이 결과는 사용 결과에 dispatcher 결과이며이 결과를 실행하기 전에 목록을 채워야합니다. validate 메서드가 끝나고 INPUT 결과가 반환되기 전에 유효성 검사 오류에 대해 validate 메서드에서 수동 검사를 수행 한 다음 목록을 다시 채 웁니다. 이 논리는 workflow 인터셉터 (defaultStack의 구성원)에 의해 이미 구현됩니다. 유효성 검사 오류가 발생했을 때이 인터셉터가 메소드를 호출하도록 설정할 수 있습니다. 이 방법에서는 목록을 다시 채울 수 있습니다.

public String input() throws Exception { 
    list = service.getList((int)(currentPage-1)*pageSize, pageSize); 
    return INPUT; 
} 

지금 당신은 당신의 침전물 방법 insert(), delete()에 주석을 배치를 통해 workflow 인터셉터와 함께 사용하려면이 방법을 구성해야합니다. 작업이 INPUT 결과로, 아마도 같은 위치를 디스패처 결과를 반환하는 경우

@InputConfig(methodName="input") 

edit()load() 방법에서 당신은 수동으로 input()를 호출 할 수 있습니다.

+0

나는이 방법을 시도했다. 'input()'메서드는 예상대로 호출됩니다. 'prepare()'메소드에서리스트를 초기화하는 코드를 피할 수 있습니까? 대부분의 경우,'input()'과'prepare()'두 메소드는 똑같은 중복 코드를 가지고리스트를 초기화 할 것입니다. 필자의 경우 현재 유효성 검사/변환 오류가 발생하면 목록은'input()'메서드로 초기화되고 성공하면 목록은'prepare()'메서드에 채워집니다 (이후 추악한 조건부 검사). 이 목록을 초기화하는 일반적인 방법을 사용할 수 있습니까 (둘 다 동일한 중복 코드가 있음)? – Tiny

+0

'prepare' 메소드를 제거하십시오. 리스트를 초기화하는 코드는'input' 메소드에 있습니다. –

+0

신중하게 살펴보고 나면 실제로 갈 수있는 올바른 방법 인 것 같습니다! – Tiny