📄 设计模式:设计自己的mvc框架(转) - 陋室铭 - 博客园.htm
字号:
color=#0000ff>new</FONT></STRONG> ActionForward(<FONT
color=#ff33ff>"fail"</FONT>);
<LI>
<LI> <STRONG><FONT
color=#0000ff>public</FONT></STRONG> ActionForward(<STRONG><U>String</U></STRONG> name){
<LI> <STRONG><FONT color=#0000ff>this</FONT></STRONG>.name=name;
<LI> }
<LI>
<LI> <STRONG><FONT
color=#0000ff>public</FONT></STRONG> ActionForward(<STRONG><U>String</U></STRONG> name, <STRONG><U>String</U></STRONG> viewUrl) {
<LI> <STRONG><FONT color=#0000ff>super</FONT></STRONG>();
<LI> <STRONG><FONT
color=#0000ff>this</FONT></STRONG>.name = name;
<LI> <STRONG><FONT
color=#0000ff>this</FONT></STRONG>.viewUrl = viewUrl;
<LI> }
<LI>
<LI> <EM><FONT
color=#339900>//...name和viewUrl的getter和setter方法</FONT></EM>
<LI>
<LI>}
<LI></LI></OL></DIV>
<P><BR>我们看到ActionForward预先封装了SUCCESS和FAIL对象。<BR></P>
<DIV class=codeStyle twffan="done">
<OL>
<LI>
<LI><STRONG><FONT color=#0000ff>public</FONT></STRONG> <STRONG><FONT
color=#0000ff>class</FONT></STRONG> ActionModel {
<LI> <STRONG><FONT
color=#0000ff>private</FONT></STRONG> <STRONG><U>String</U></STRONG> path; <EM><FONT
color=#339900>// action的path</FONT></EM>
<LI>
<LI> <STRONG><FONT
color=#0000ff>private</FONT></STRONG> <STRONG><U>String</U></STRONG> className; <EM><FONT
color=#339900>// action的class</FONT></EM>
<LI>
<LI> <STRONG><FONT color=#0000ff>private</FONT></STRONG> <FONT
color=#ff0000>Map</FONT><<STRONG><U>String</U></STRONG>, ActionForward> forwards; <EM><FONT
color=#339900>// action的forward</FONT></EM>
<LI>
<LI> <STRONG><FONT
color=#0000ff>public</FONT></STRONG> ActionModel(){}
<LI>
<LI> <STRONG><FONT
color=#0000ff>public</FONT></STRONG> ActionModel(<STRONG><U>String</U></STRONG> path, <STRONG><U>String</U></STRONG> className,
<LI> <FONT
color=#ff0000>Map</FONT><<STRONG><U>String</U></STRONG>, ActionForward> forwards) {
<LI> <STRONG><FONT color=#0000ff>super</FONT></STRONG>();
<LI> <STRONG><FONT
color=#0000ff>this</FONT></STRONG>.path = path;
<LI> <STRONG><FONT
color=#0000ff>this</FONT></STRONG>.className = className;
<LI> <STRONG><FONT
color=#0000ff>this</FONT></STRONG>.forwards = forwards;
<LI> }
<LI>
<LI>
<LI> <EM><FONT
color=#339900>//...相应的getter和setter方法 </FONT></EM>
<LI>
<LI>}
<LI></LI></OL></DIV>
<P><BR><BR>3。知道了两个模型是什么样,也应该可以猜到我们的配置文件大概是什么样的了,与<A
href="http://www.qqread.com/z/soft/struts/" target=_blank><FONT
color=#002c99>struts</FONT></A>的配置<A
href="http://www.qqread.com/keywords/file-format.html" target=_blank><FONT
color=#002c99>文件格式</FONT></A>类似:<BR></P>
<DIV class=codeStyle twffan="done">
<OL>
<LI>
<LI><?xml version=<FONT color=#ff33ff>"1.0"</FONT> encoding=<FONT
color=#ff33ff>"UTF-8"</FONT>?>
<LI><actions>
<LI> <action path=<FONT color=#ff33ff>"/login"</FONT>
<LI> <STRONG><FONT
color=#0000ff>class</FONT></STRONG>=<FONT
color=#ff33ff>"com.strutslet.demo.LoginAction"</FONT>>
<LI> <forward name=<FONT
color=#ff33ff>"success"</FONT> url=<FONT
color=#ff33ff>"hello.jsp"</FONT>/>
<LI> <forward name=<FONT
color=#ff33ff>"fail"</FONT> url=<FONT
color=#ff33ff>"fail.jsp"</FONT>/>
<LI> </action>
<LI></actions> </LI></OL></DIV>
<P><BR>path是在应用中将被调用的路径,class指定了调用的哪个action,forward元素指定了转向,比如我们这里如果是success就转向hello.jsp,失败的话转向fail.jsp,这里配置了demo用到的LoginAction。<BR><BR>4。Dispacher接口,主要是getNextPage方法,此方法负责获得下一个页面将导向哪里,提供给前端控制器转发。<BR></P>
<DIV class=codeStyle twffan="done">
<OL>
<LI>
<LI><STRONG><FONT color=#0000ff>public</FONT></STRONG> <STRONG><FONT
color=#0000ff>interface</FONT></STRONG> Dispatcher {
<LI> <STRONG><FONT
color=#0000ff>public</FONT></STRONG> <STRONG><FONT
color=#0000ff>void</FONT></STRONG> setServletContext(ServletContext context);
<LI> <STRONG><FONT
color=#0000ff>public</FONT></STRONG> <STRONG><U>String</U></STRONG> getNextPage(HttpServletRequest request,ServletContext context);
<LI>} </LI></OL></DIV>
<P><BR><BR>5。5。原先书中实现了一个WorkFlow的Dispatcher,按照顺序调用action,实现工作流调用。而我们所需要的是根据请求的path调用相应的action,执行action的execute方法返回一个ActionForward,然后得到ActionForward的viewUrl,将此viewUrl提供给前端控制器转发,看看它的getNextPage方法:<BR><BR></P>
<DIV class=codeStyle twffan="done">
<OL>
<LI>
<LI><STRONG><FONT
color=#0000ff>public</FONT></STRONG> <STRONG><U>String</U></STRONG> getNextPage(HttpServletRequest request, ServletContext context) {
<LI> setServletContext(context);
<LI>
<LI> <FONT
color=#ff0000>Map</FONT><<STRONG><U>String</U></STRONG>, ActionModel> actions = (<FONT
color=#ff0000>Map</FONT><<STRONG><U>String</U></STRONG>, ActionModel>) context
<LI> .getAttribute(Constant.ACTIONS_ATTR); <EM><FONT
color=#339900>//从ServletContext得到所有action信息</FONT></EM>
<LI> <STRONG><U>String</U></STRONG> reqPath = (<STRONG><U>String</U></STRONG>) request.getAttribute(Constant.REQUEST_ATTR);<EM><FONT
color=#339900>//发起请求的path</FONT></EM>
<LI> ActionModel actionModel = actions.get(reqPath); <EM><FONT
color=#339900>//根据path得到相应的action</FONT></EM>
<LI> <STRONG><U>String</U></STRONG> forward_name = <FONT
color=#ff33ff>""</FONT>;
<LI> ActionForward actionForward;
<LI> <STRONG><FONT color=#0000ff>try</FONT></STRONG> {
<LI> <STRONG><U>Class</U></STRONG> c = <STRONG><U>Class</U></STRONG>.forName(actionModel.getClassName()); <EM><FONT
color=#339900>//每个请求对应一个action实例</FONT></EM>
<LI>
<LI> <FONT
color=#ff0000>Action</FONT> action = (<FONT
color=#ff0000>Action</FONT>) c.newInstance();
<LI> actionForward = action.execute(request, context); <EM><FONT
color=#339900>//执行action的execute方法</FONT></EM>
<LI> forward_name = actionForward.getName();
<LI>
<LI> } <STRONG><FONT
color=#0000ff>catch</FONT></STRONG> (<STRONG><U>Exception</U></STRONG> e) {
<LI> log.error(<FONT
color=#ff33ff>"can not find action "</FONT>+actionModel.getClassName());
<LI> e.printStackTrace();
<LI> }
<LI>
<LI> actionForward = actionModel.getForwards().get(forward_name);
<LI> <STRONG><FONT
color=#0000ff>if</FONT></STRONG> (actionForward == <STRONG><FONT
color=#0000ff>null</FONT></STRONG>) {
<LI> log.error(<FONT
color=#ff33ff>"can not find page for forward "</FONT>+forward_name);
<LI> <STRONG><FONT
color=#0000ff>return</FONT></STRONG> <STRONG><FONT
color=#0000ff>null</FONT></STRONG>;
<LI> } <STRONG><FONT color=#0000ff>else</FONT></STRONG>
<LI> <STRONG><FONT
color=#0000ff>return</FONT></STRONG> actionForward.getViewUrl(); <EM><FONT
color=#339900>//返回ActionForward的viewUrl</FONT></EM>
<LI> } </LI></OL></DIV>
<P><BR><BR> </P>
<P>6。前端控制器(FrontController),它的任务我们已经很清楚,初始化配置文件;<A
href="http://www.qqread.com/z/server/storage/" target=_blank><FONT
color=#002c99>存储</FONT></A>所有action到ServletContext供整个框架使用;得到发起请求的path,提供给Dispachter查找相应的action;调用Dispatcher,执行getNextPage方法得到下一个页面的url并转发:<BR><BR></P>
<P> </P>
<DIV class=codeStyle twffan="done">
<OL>
<LI>
<LI><STRONG><FONT color=#0000ff>public</FONT></STRONG> <STRONG><FONT
color=#0000ff>void</FONT></STRONG> init() <STRONG><FONT
color=#0000ff>throws</FONT></STRONG> ServletException {
<LI>
<LI> <EM><FONT color=#339900>//初始化配置文件</FONT></EM>
<LI>
<LI> ServletContext context=getServletContext();
<LI> <STRONG><U>String</U></STRONG> config_file =getServletConfig().getInitParameter(<FONT
color=#ff33ff>"config"</FONT>);
<LI> <STRONG><U>String</U></STRONG> dispatcher_name=getServletConfig().getInitParameter(<FONT
color=#ff33ff>"dispatcher"</FONT>);
<LI> <STRONG><FONT
color=#0000ff>if</FONT></STRONG> (config_file == <STRONG><FONT
color=#0000ff>null</FONT></STRONG> || config_file.equals(<FONT
color=#ff33ff>""</FONT>))
<LI> config_file = <FONT
color=#ff33ff>"/WEB-INF/strutslet-config.xml"</FONT>; <EM><FONT
color=#339900>//默认是/WEB-INF/下面的strutslet-config</FONT></EM>
<LI> <STRONG><FONT
color=#0000ff>if</FONT></STRONG>(dispatcher_name==<STRONG><FONT
color=#0000ff>null</FONT></STRONG>||dispatcher_name.equals(<FONT
color=#ff33ff>""</FONT>))
<LI> dispatcher_name=Constant.DEFAULT_DISPATCHER;
<LI>
<LI> <STRONG><FONT color=#0000ff>try</FONT></STRONG> {
<LI> <FONT
color=#ff0000>Map</FONT><<STRONG><U>String</U></STRONG>, ActionModel> resources = ConfigUtil.newInstance() <EM><FONT
color=#339900>//工具类解析配置文件</FONT></EM>
<LI> .parse(config_file, context);
<LI> context.setAttribute(Constant.ACTIONS_ATTR, resources); <EM><FONT
color=#339900>//存储在ServletContext中</FONT></EM>
<LI> log.info(<FONT
color=#ff33ff>"初始化strutslet配置文件成功"</FONT>);
<LI> } <STRONG><FONT
color=#0000ff>catch</FONT></STRONG> (<STRONG><U>Exception</U></STRONG> e) {
<LI> log.error(<FONT
color=#ff33ff>"初始化strutslet配置文件失败"</FONT>);
<LI> e.printStackTrace();
<LI> }
<LI>
<LI> <EM><FONT color=#339900>//实例化Dispacher</FONT></EM>
<LI>
<LI> <STRONG><FONT color=#0000ff>try</FONT></STRONG>{
<LI> <STRONG><U>Class</U></STRONG> c = <STRONG><U>Class</U></STRONG>.forName(dispatcher_name);
<LI>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -