Struts2 框架的简单实现——轻松理解Struts原理

来源:互联网 发布:光电效应 知乎 编辑:程序博客网 时间:2024/06/07 22:43

        Struts2因该算是目前JavaWeb中MVC框架中最火的一个了,我第一次接触框架是在大学时期,那时候第一次学的还是Struts1框架,当时想的是:既然有1和2那就从低版本的开始学吧!当时自己想当然的将Struts2当成了Struts1的升级版本。可直到后来才发现自己大错特错,Struts2和Struts1虽然只有一字之差,但从实现原理到编程风格都是天壤之别。以至于我在很长一段时间都不能适应Struts2的编码风格。关于Struts2和Struts1的区别我就不再多说,本文的重点是用相对简单的代码模拟Struts2的底层实现。

    首先,Struts2的Controler这个角色是由Filter完成的。Filter通过拦截浏览器的请求,通过不同的请求选择执行不同Action的excute()方法,最终决定该如何跳转。

    先看一下如果我们平时不用Struts2框架时,用Filter如何实现以上功能。

    我们想写一个JSP页面,页面上有两个超链接

  

<a href = "/primer/userAction.action">userAction</a><a href = "/primer/helloWorldAction.action">helloWorldAction</a></span>
 

当我们点击页面上的超练接时,浏览器就会想服务器发送请求,Filter就会拦截这个请求

我们的Filter就会这样写:

public class Struts2Filter implements Filter {public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {//强转HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse res = (HttpServletResponse)response;String path = req.getServletPath();                if(path.equals("/primer/userAction.action")){                    Action a = new UserAction();                    String result = a.excute();                  req.getRequestDispatcher("/success.jsp").forward(req, res);                      }else if(path.equals("/primer/helloWorldAction.action")){                         Action a = new HelloWorldAction();                         String result = a.excute();                         req.getRequestDispatcher("/success.jsp").forward(req, res);                           }  }}

以上代码乍一看并没有什么问题,但是我们假设这样一种情况,如果浏览器页面上有10个超练接,那不是要判断十次,这显然是不合理的,所以我们希望每次都能动态根据获得的请求判断该使用哪个Action。所以这就需要用到反射原理构建对象。那应该如何实现呢?首先我们新建一个HashMap,以链接地址为Key,以Action的全名为Value.

于是代码可以这样修改。

public class Struts2Filter implements Filter {Map<String, String> map = new HashMap<String, String>();public void init(FilterConfig config) throws ServletException {map.put("/primer/userAction.action", "cn.itcast.action.UserAction");map.put("/primer/helloWorldAction.action", "cn.itcast.action.HelloWorldAction");</span>}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {//强转HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse res = (HttpServletResponse)response;String path = req.getServletPath();System.out.println("path = "+path);if(path.equals("/test.jsp")){chain.doFilter(req, res);//如果.jsp则放行}else{try {Action action;//利用反射,通过newInstance()得到实例化action = (Action)Class.forName(map.get(path)).newInstance();action.execute();req.getRequestDispatcher("/success.jsp").forward(req, res);} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void destroy() {// TODO Auto-generated method stub}}
    这样看起来似乎好了很多,但仍然有问题,如果我们增加页面上的超练接,就需要不断往Map中增加元素,每次修改都需要重新加载Struts2Filter,这显然比较浪费资源。为了解决这个问题我们可以创建一个XML文件,然后把Action配置进去,之后我们只需要解析XML文件,就能将元素放入Map中了,这个XML文件就是Struts2中的Struts.xml文件。

配置文件如下:

<package name="packsge" namespace="/primer/" extends="struts-default">                <action name="</span><span style="font-family:SimSun;font-size:14px;">userAction</span><span style="font-size:18px;">" class="cn.itcast.action.UserAction" method="excute">            <result name="success">/success.jsp</result>        </action>             <action name="helloWorldAction" class="cn.itcast.action.HelloWorldAction" method="excute">            <result name="success">/success.jsp</result>        </action>
</package>

   然后,我们把Strust2Filter中红色的硬性注入,改成解析XML文件赋值就可以啦,这样一个简单的Struts2框架就搭建好了,在使用Struts2是,核心的Filter不需要我们修改,我们只需要配置struts2.xml文件,和编写Action类就OK啦,是不是很简单!!!!当然,Struts2肯定不止这些东西,在struts-default.xml中还有无数的拦截器等着我们。这里只是简单的实现Struts2的一些基本功能。

  以上只是本人对于Struts2的一些粗浅理解,如有错误请各大高手批评指正!!!!!!


0 0
原创粉丝点击