Salesforceでセッション管理する方法を考えてみた | 俺の夢ってなんだったけorz…  的な

俺の夢ってなんだったけorz…  的な

タダの日記なんだからね!!

Apexというクソ言語とvisualforceっていうクソカスタムタグを色々と調べてみた。

このSalesforceってのはやっかいで、セッション管理がありません。
買い物かごみたいに情報をメモリに保持しとくやつです。


調べてみるとページに同一のコントローラクラスを設定しておけば、セッション管理が実現できるとあります。
コントローラクラスのステートでセッションを表現してしまおうということのようです。


でも、この方法で実装してしまうと膨大なコード量とすさまじい依存関係のコントローラクラスが作成されてしまいます。
さしずめ、Strutsのアクションクラスを1つで全画面を実装するというような感じでしょう。

そこで、コントローラクラスを各画面単位で作成できないか考えてみました。

苦し紛れだが、まぁ1個のコントローラで全実装よりはマシ。
間違ってたらスンマソン。


■説明

○メインコントローラクラスは当然1つ。クラスのステートで管理する為。
コントローラにDTOを設定します。

public class MainController{
public final MainDTO dto{set;get;}
public MainController(){
dto = new MainDTO();
}
}

○このDTOがセッションをあらわします。
public class MainDTO{
//セッションに格納したい情報
public 何かしらのBean{set;get;}
public 何かしらのBean{set;get;}
public 何かしらのBean{set;get;}
}

○コンポーネントのクラスにDTOを引き受ける為の定義
public abstract class BaseComponentController{
public MainDTO dto{set;get;}
}

○各画面をコンポーネントで表現します。
外枠のページでセッションを管理して、中のコンポーネントでビジネスロジックを定義
します。
public class Component01Controller extends BaseComponentController{

public PageReference moveNext(){
PageReference nextPage = Page.Page2;
return nextPage;
}
public PageReference movePrevious(){
PageReference nextPage = Page.Page1;
return nextPage;
}

}

○DTOへは参照が渡っているので、好き勝手値をいじるなり取得するなりすればよい。
public class Component02Controller extends BaseComponentController{

public PageReference moveNext(){
PageReference nextPage = Page.Page2;
return nextPage;
}
public PageReference movePrevious(){
dto.pref = '山梨県';
PageReference nextPage = Page.Page1;
return nextPage;
}

}

○ページはheadタグとコンポーネントを実装して、DTOを渡すだけ
<!-- Page1 -->
<apex:page controller="MainController" showHeader="false" standardStylesheets="false" >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ページ1</title>
</head>
<c:Component01 dto="{!dto}" />
</html>
</apex:page>

<!-- Page2 -->
<apex:page controller="MainController" showHeader="false" standardStylesheets="false" >
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>ページ2</title>
</head>
<c:Component02 dto="{!dto}" />
</apex:page>

○コンポーネントではassignToで受け取ったDTOをコンポーネントのコントローラーに設定してやる。
<!-- Component01 -->
<apex:component controller="Component01Controller">
<apex:attribute name="dto" description="required" assignTo="{!dto}" type="MainDTO" required="true"/>
<body>
Component01<br/>
<apex:form >
ユーザ名:<apex:inputText value="{!dto.userName}"/><br/>
住所:<apex:inputText value="{!dto.pref}"/><br/>
<apex:commandButton action="{!moveNext}" value="進む"/>
</apex:form>
</body>
<c:Component05 ></c:Component05>
</apex:component>

<!-- Component02 -->
<apex:component controller="Component02Controller">
<apex:attribute name="dto" description="required" assignTo="{!dto}" type="MainDTO" required="true"/>
Component02<br/>
<apex:form >
ユーザ名:<apex:inputText value="{!dto.userName}"/><br/>
住所:<apex:inputText value="{!dto.pref}"/><br/>
<apex:commandButton action="{!movePrevious}" value="戻る"/>
</apex:form>
</apex:component>


きたないやり方だが、コントローラクラスを各画面単位実装できる。