かとじゅんの技術日誌

技術の話をするところ

PRGパターンに対応したActionクラスの作り方

id:dewaさんのS2Conでの講演内容を踏まえてPRGパターンに対応したActionクラスの作り方について考えてみる.

public class EmployeeAction {

	@Resource
	protected JdbcManager jdbcManager;

	@ActionForm
	@Resource
	public EmployeeForm employeeForm;

	@Resource
	public EmployeeViewDto employeeViewDto;

	// 出力系のメソッド名はjspのファイル名に合わせる.
	public String index(){
		employeeForm.initialize();
		employeeViewDto.initialize();
		return "index.jsp";
	}

	// 入力系処理はメソッド名をdoから始める.
	// 遷移先は出力系のアクションメソッドをリダイレクトで呼び出す.
	public String doSearch(){
		employeeViewDto.initialize();
		List<Employee> employeeList = jdbcManager.from(Employee.class).where(new SimpleWhere().eq("prefId", employeeForm.prefId)).getResultList();
		for(Employee employee : employeeList){
			employeeViewDto.employeeItems.add(Beans.createAndCopy(BeanMap.class, employee).execute());
		}
		return "result?redirect=true";
	}

	public String result(){
		return "result.jsp";
	}
}

// PRGではリクエストをリダイレクトするので,元のリクエストパラメータが残りません.
// なのでセッションでDTOを管理させてビューまで届くようにしてあげないといけません.
@SuppressWarnings("serial")
@Component(instance = InstanceType.SESSION)
public class EmployeeViewDto implements Serializable {
	
	public void initialize(){
		employeeItems.clear();
	}
	
	public List<BeanMap> employeeItems = CollectionsUtil.newArrayList();
	
}

// こちらもビューに渡す場合があるのでセッションで管理する
@SuppressWarnings("serial")
@Component(instance = InstanceType.SESSION)
public class EmployeeForm implements Serializable {
	
	public void initialize(){
		prefId = null;
	}
	
	public Integer prefId;
	
}

このようにすれば,PRGパターンになるはず.POST後の画面で更新ボタンを押しても再度POSTしますかと聞かれないですむ.

プロパティ名が長くて冗長な気がするので,以下のようにできるかも.これは試してない.

	@ActionForm
	@Resource(name="employeeForm")
	public EmployeeForm form;

	@Resource(name="employeeViewDto")
	public EmployeeViewDto view;