2008/04/14からのアクセス回数 25482 mvc-conventionのサンプルプログラムは、とてもシンプルで素晴らしいのですが、 規約をどのように使用したかを解説していないので、ソースを見ただけでは理解 しにくいので、ここで説明します。 設定ファイルの説明 †サンプルの設定ファイルは、
最後のcoverc-servlet.xmlは、「サーブレット名-servlet.xml」がサーブレット関連Bean定義ファイルの デフォルトファイル名です。DsipatcherServletの初期化で使用されます。 web.xmlの設定 †web.xmlでSpring-MVC特有の定義は、 <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>coverc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>coverc</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
サーブレット名称は、Servlet関連Bean定義ファイルを読み込むために使用されますので、適宜変更してください。 サーブレット関連のBean定義ファイルを細分して定義する場合には、web.xmlの contextConfigLocationに以下のように定義ファイルを列記します。 <servlet> <servlet-name>cart</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/servlet-def.xml,/WEB-INF/servlet-stub.xml</param-value> </init-param> </servlet> applicationContext.xml †applicationContext.xmlの定義は至って簡単です。 webアプリケーションで共通に利用されるrecipeManagerの定義をしています。 <bean id="recipeManager" class="org.springframework.showcase.coverc.service.StubRecipeManager"/> coverc-servlet.xml †coverc-servlet.xmlでは、
をしています。 ControllerClassNameHandlerMappingは、コントローラのクラス名でHTTP要求を振り分けるHandlerMapppingです。 <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> DefaultRequestToViewNameTranslatorは、ModelAndViewオブジェクトにビューの名前が定義 されていない場合に、デフォルトのview名称を返してくれるクラスです。 詳しくは、Spring-MVC/ステップ・バイ・ステップ/Convention over configurationを参照してください。 <bean id="viewNameTranslator" class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator"/> InternalResourceViewResolverは、論理ビュー名称から、実際のビューファイル名にマッピングしています。 ここでは、xxxという論理ビュー名に対するビューファイルとして、/WEB-INF/jsp/xxx.jspを返すように
しています。 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> Spring2.0からBean定義ファイルで継承が使えるようになりました。 baseRecipeControllerは、SwitchBoardController、EditRecipeControllerの親Bean定義で この定義で、共通に使用する属性recipeManagerの定義をしています。 親Bean定義では、クラスを指定する必要がなく、abstract="true"とすることで、 必要な属性のみを定義することができます。 <bean id="baseRecipeController" abstract="true"> <property name="recipeManager" ref="recipeManager"/> </bean> SwitchBoardControllerの定義は、 <bean class="org.springframework.showcase.coverc.web.SwitchBoardController" parent="baseRecipeController"/> EditRecipeControllerは、SimpleFormControllerのサブクラスなので、ちょっと多くの設定 が必要です。
<bean class="org.springframework.showcase.coverc.web.EditRecipeController" parent="baseRecipeController"> <property name="commandName" value="recipe"/> <property name="commandClass" value="org.springframework.showcase.coverc.domain.Recipe"/> <property name="formView" value="editRecipe"/> <property name="successView" value="redirect:switchboard/listRecipes.htm"/> </bean> javaソースファイルの説明 †モデルクラス †ドメインモデルクラスは、Recipe.java1個のみです。 属性にid, nameを持ち、それぞれのgetter/setterを定義し、cloneを追加した きわめて簡素なものです。 public class Recipe implements Cloneable { private Long id; private String name; // getter/setterは省略 public Object clone() throws CloneNotSupportedException { return super.clone(); } } サービスクラス †サービスクラスは、RecipeManagerインタフェースとその実装例としてStubRecipeMangerが あります。 RecipeManagerインタフェースは、
を定義しています。 public interface RecipeManager { Collection findAll(); Recipe findById(Long id); void save(Recipe user); } StubRecipeManagerでは、TreeMapを使ってRecipeをメモリ上で管理しています。 loadRecipesメソッドでTreeMapに3個のRecipeをセットしています。
従ってfindAllで戻されたオブジェクトの名前は、recipeListになります。 詳しくは、Spring-MVC/ステップ・バイ・ステップ/Convention over configurationを参照してください。 public class StubRecipeManager implements RecipeManager { private Map recipes = new TreeMap(); public StubRecipeManager() { loadRecipes(); } public void save(Recipe recipe) { // passed in should be a clone - simply replace putRecipe(recipe); } public Recipe findById(Long id) { Recipe recipe = (Recipe) this.recipes.get(id); if (recipe != null) { return cloneRecipe(recipe); } return null; } public Collection findAll() { List recipeList = new ArrayList(); Iterator itr = this.recipes.values().iterator(); while (itr.hasNext()) { Recipe recipe = (Recipe) itr.next(); recipeList.add(cloneRecipe(recipe)); } return recipeList; } } コントローラクラス †SwitchBoardControllerは、recipeManagerを属性に持ち、
ModelAndView(). addObject(findAllの戻り値); としている部分が、規約の使い方を示すための例です。 findAllの戻り値はRecipeを要素に持つArrayListですので、そのオブジェクトは、recipeListとしてモデルに追加されます。 詳しくは、Spring-MVC/ステップ・バイ・ステップ/Convention over configurationを参照してください。 public class SwitchBoardController extends MultiActionController { private RecipeManager recipeManager; // setRecipeManagerは省略 public ModelAndView listRecipes(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView().addObject(this.recipeManager.findAll()); } } EditRecipeControllerも、recipeManagerを属性に持ち、
public class EditRecipeController extends SimpleFormController { private RecipeManager recipeManager; // setRecipeManagerは省略 protected Object formBackingObject(HttpServletRequest request) throws Exception { long id = ServletRequestUtils.getRequiredLongParameter(request, "id"); Recipe recipe = this.recipeManager.findById(new Long(id)); return recipe; } protected void doSubmitAction(Object object) throws Exception { Recipe recipe = (Recipe) object; this.recipeManager.save(recipe); } } 本当にこれだけで、よいのかと思うくらい少ない量のソースで、mvc-conventionの例題が 作られています。 コメント †この記事は、 皆様のご意見、ご希望をお待ちしております。 Tweet |