単純なプログラムを書換えよう(WebWork2編)−observer-command-singleton
はじめに
引数のあるコンストラクタをCommandに定義をWebWork2を使って書換えてみた.異なるのはControllerとModelである.Controllerにはjspからアクセスするアクセッサを追加し,ModelからはObserverへ変化を知らせるメソッド(setChanged()/notifyObserver())がなくなった.
ファイル/ディレクトリ構成
プログラムを動かすために,以下のファイルを用意する.
- counter03-1.jsp/counter03-2.jsp
- ブラウザに表示するためのjsp.counter03-1.jspは最初に表示する画面,counter03-2.jspはプログラム起動後に遷移する画面.
- Command.class/DecCommand.class/IncCommamd.class/CommandDispatcher.class/Controller.class/Model.class
- javaのクラス
- xwork.xml
- WebWork2の画面遷移等を指定するファイル
ディレクトリ構成は以下のようになる.各ファイルの内容はそれぞれ後述する.
${TOMCAT_HOME}/webapps/counter/counter03-1.jsp /counter03-2.jsp /WEB-INF/classes/counter03/Command.class /DecCommand.class /IncCommand.class /CommandDispatcher.class /Controller.class /Model.class /xwork.xml /lib/commons-logging.jar /ognl-2.6.3-modified.jar /oscore-2.2.1.jar /velocity-dep-1.3.1.jar /webwork-2.0.jar /xwork-1.0.jar /web.xml
URL
アクセスするためのURLは以下の通りとなる.
http://localhost:[ポート番号]/counter/counter03-1.jsp
ポート番号が8080の場合は,
http://localhost:8080/counter/counter03-1.jsp
となる.
counter03-1.jsp/counter03-2.jsp
counter02-1.jsp/counter02-2.jspを一部修正する.
<%-- counter03-1.jsp --%> <html> <head> <title>counter03-1</title> </head> <body> value:0<br/> <form action="Counter03.action"> <%-- xwork.xmlの記述にあわせてaction属性にはCounter03を指定 --%> <input type="hidden" name="value" value="0""/> <input type="submit" name="action" value="inc"/> <input type="submit" name="action" value="dec"/> </form> </body> </html> <%-- end --%> <%-- counter03-2.jsp --%> <%@ taglib prefix="ww" uri="webwork" %> <%-- WebWorkのカスタムタグを使うのでtaglibを宣言 --%> <html> <head> <title>counter03-2</title> </head> <body> value:<ww:property value="value"/><br/> <%-- Controller.getValue()メソッドを使って結果を取出す.propertyはWebWorkのカスタムタグ --%> <form action="Counter03.action"> <%-- xwork.xmlの記述にあわせてaction属性にはCounter03を指定 --%> <input type="hidden" name="value" value="<ww:property value="value"/>"/> <input type="submit" name="action" value="inc"/> <input type="submit" name="action" value="dec"/> </form> </body> </html> <%-- end --%>
Command.java/IncCommand.java/DecCommand.java
//Command.java package counter03; public interface Command{ void execute(); } //end //IncCommand.java package counter03; public class IncCommand implements Command{ private Model model; public IncCommand(Model model){ this.model=model; } public void execute(){ model.inc(); } } //end //DecCommand.java package counter03; public class DecCommand implements Command{ private Model model; public DecCommand(Model model){ this.model=model; } public void execute(){ model.dec(); } } //end
CommandDispatcher.java
//CommandDispatcher.java package counter03; import java.util.Map; import java.util.HashMap; import java.lang.reflect.*; public class CommandDispatcher{ private static Map commands=new HashMap(); private static CommandDispatcher commandDispatcher=new CommandDispatcher(); private static Model model; static{ commands.put("inc" ,"counter03.IncCommand"); commands.put("dec" ,"counter03.DecCommand"); } private CommandDispatcher(){ } public static CommandDispatcher getInstance(Model model){ commandDispatcher.model=model; return commandDispatcher; } public Command getCommand(String command){ Command executeCommand=null; try{ executeCommand= (Command)Class.forName(commands.get(command).toString()) .getConstructor(new Class[]{this.model.getClass()}) .newInstance(new Object[]{this.model}); } catch(ClassNotFoundException e){ e.printStackTrace(); } catch(NoSuchMethodException e){ e.printStackTrace(); } catch(InstantiationException e){ e.printStackTrace(); } catch(IllegalAccessException e){ e.printStackTrace(); } catch(InvocationTargetException e){ e.printStackTrace(); } return executeCommand; } } //end
Controller.java
//Controller.java package counter03; import com.opensymphony.xwork.*; public class Controller extends ActionSupport{ private Model model=new Model(); private CommandDispatcher commandDispatcher=CommandDispatcher.getInstance(model); private String action; public void setValue(String value){ model.setValue(Integer.parseInt(value)); } public String getValue(){ return Integer.toString(model.getValue()); } public void setAction(String action){ this.action=action; } public String getAction(){ return action; } public String execute(){ commandDispatcher.getCommand(this.getAction()).execute(); return SUCCESS; } } //end
Model.java
//Model.java package counter03; public class Model{ private int value; public Model(){ this(0); } public Model(int value){ setValue(value); } public int getValue(){ return value; } public void setValue(int value){ this.value=value; } public int inc(){ return inc(1); } public int inc(int value){ setValue(getValue()+value); return getValue(); } public int dec(){ return dec(1); } public int dec(int value){ setValue(getValue()-value); return getValue(); } } //end
xwork.xml
xwork.xmlも修正する.
<!-- xwork.xml --> <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <include file="webwork-default.xml"/> <package name="default" extends="webwork-default"> <default-interceptor-ref name="defaultStack"/> <!-- Counter03を追加 --> <action name="Counter03" class="counter03.Controller"> <result name="success" type="dispatcher"> <param name="location">counter03-2.jsp</param> </result> </action> </package> </xwork> <!-- end -->