Struts2 MVC底层的简单实现


一直想写Struts2的底层实现,酝酿了两个星期,今天把它实现。
首先,我们在运用的时候都会使用action,实现跳转,下面我们写一个UserAction:
public class UserAction {
    public String toAddUser(){
        return "success";
    }
                                                                                                                                                                                                                                                       
    public String addUser(){
        return "adduser";
    }
}

我们在使用Struts2的时候,一个很重要的配置文件是:struts.xml,因此我们需要读取它,知道他里面的内容,java解析xml我写过了一篇文章,可以去看看。

下面我们写一个配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<struts>
  <package name="user" namespace="/user" >
      <action name="userAction" class="actions.UserAction" >
          <result name="success">/success.jsp</result>
          <result name="adduser">/addUser.jsp</result>
      </action>
  </package>
</struts>

之后我们就需要去读取这个配置文件,但是之前我们需要我们需要建立几个实体类去存储这些元素,由外到内排列:
1.package的实体类

import java.util.List;
public class PackageEntity {
                                                                                                                                                                                                           
    private String name;
    private String namespace;
    private List<ActionEntity> actions;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getNamespace() {
        return namespace;
    }
    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }
    public List<ActionEntity> getActions() {
        return actions;
    }
    public void setActions(List<ActionEntity> actions) {
        this.actions = actions;
    }
}

private List<ActionEntity> actions;是吧action实体类的内容放到package中。
2.action的实体类

import java.util.List;
public class ActionEntity {
    private String name;
    private String classname;
    private List<ResultEntity> results;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getClassname() {
        return classname;
    }
    public void setClassname(String classname) {
        this.classname = classname;
    }
    public List<ResultEntity> getResults() {
        return results;
    }
    public void setResults(List<ResultEntity> results) {
        this.results = results;
    }
}

private List<ResultEntity> results;是把result的实体类放到action中。
3.result的实体类
public class ResultEntity {
    private String name;
    private String page;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPage() {
        return page;
    }
    public void setPage(String page) {
        this.page = page;
    }
}

page是指后面的jsp。
经过两个list就把配置文件中所有的元素集中到package中,便于下面的跳转。
下面写一个配置的工具类:
public class ConfigUtils {
//new一个package的对象,便于调用元素
    public static  PackageEntity pe=new PackageEntity();
                                                                                                                                             
                                                                                                                                           
    public static void config(){
        SAXReader reader=new SAXReader();
        try {
            //读取struts.xml
            Document doc=reader.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("struts.xml"));
            //读取根元素
            Element root=doc.getRootElement();
          //得到根元素下的节点元素
            Element packageElement=root.element("package");
            List<ActionEntity> actions=new ArrayList<ActionEntity>();
            pe.setName(packageElement.attributeValue("name"));
            pe.setNamespace(packageElement.attributeValue("namespace"));
          //得到根元素下的节点元素
            List<Element> listActions=packageElement.elements("action");
            for(Element actionElement:listActions){
                ActionEntity ae=new ActionEntity();
                //得到子节点
                ae.setName(actionElement.attributeValue("name"));
                ae.setClassname(actionElement.attributeValue("class"));
                //得到根元素下的节点元素
                List<Element> resultElements=actionElement.elements("result");
                List<ResultEntity>  results=new ArrayList<ResultEntity>();
                for(Element resultEle:resultElements){
                    ResultEntity re=new ResultEntity();
                    //得到子节点
                    re.setName(resultEle.attributeValue("name"));
                    re.setPage(resultEle.getText());
                    results.add(re);
                }
                ae.setResults(results);
                actions.add(ae);
            }
            pe.setActions(actions);
                                                                                                                                                   
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

写一个index.jsp,为了写跳转链接进行验证:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>首页</title>
  </head>
                                                                                                                                 
  <body>
      <a href="<%=path%>/user/userAction!toAddUser.action">跳转</a>
      <br/>
      <a href="<%=path%>/user/userAction!addUser.action">添加用户</a>
  </body>
</html>

跳转是跳到到success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <title>My JSP 'success.jsp' starting page</title>
  </head>
                                                                                                                             
  <body>
    This is my JSP page. <br>
    成功了
  </body>
</html>

添加用户是跳到adduser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'addUser.jsp' starting page</title>
  </head>
                                                                                                                       
  <body>
    This is my JSP page. <br>
    添加用户了
  </body>
</html>

写好了jsp之后我们就要过滤这些连接,进行跳转,写一个struts2的过滤器:
public class StrutsFilter implements Filter {
    @Override
    public void destroy() {
                                                                                                                   
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest)req;
        String path=request.getServletPath();
        System.out.println(path);
        String[] pathArr=path.split("/");
        String namespace=pathArr[1];
        String actionString=pathArr[2];
        String actionname=actionString.split("!")[0];
        String methodname=actionString.split("!")[1].split("\\.")[0];
        System.out.println(actionname+":"+methodname);
        PackageEntity pe=ConfigUtils.pe;
        List<ActionEntity> actions=pe.getActions();
        ActionEntity doAction=null;
        for(ActionEntity ae:actions){
            if(ae.getName().equals(actionname)){
                doAction=ae;
                break;
            }
        }
                                                                                                                   
        try {
            Class actioncls=Class.forName(doAction.getClassname());
            Object actionObj=actioncls.newInstance();
            Class cls=actionObj.getClass();
            Method actionMethod=cls.getDeclaredMethod(methodname);
    String resultValue=(String)actionMethod.invoke(actionObj,null);
            List<ResultEntity> results=doAction.getResults();
            ResultEntity re=null;
            for(ResultEntity result:results){
                if(resultValue.equals(result.getName())){
                    re=result;
                    break;
                }
            }
    request.getRequestDispatcher(re.getPage()).forward(request, res);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        ConfigUtils.config();   
    }
}

下面建立一个web的过滤器测试一下:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestFilter implements Filter {
    @Override
    public void destroy() {
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest)req;
        HttpServletResponse response=(HttpServletResponse)res;
        request.getRequestDispatcher("/success.jsp").forward(request,response); 
    }
    @Override
public void init(FilterConfig filterConfig) throws ServletException {
    }
}

建立一个web的servlet测试一下:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
request.getRequestDispatcher("/success.jsp").forward(request, response);
    }
}

别忘了把解析xml的包导进去。
希望对你们理解框架有帮助!!!

运用Spring注解实现Netty服务器端UDP应用程序

Spring2.5.6+Hibernate3+RMI整合

Struts2与Spring整合步骤

Struts2的入门实例

相关内容