首页 / 操作系统 / Linux / 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应用程序 http://www.linuxidc.com/Linux/2013-09/89780.htmSpring2.5.6+Hibernate3+RMI整合 http://www.linuxidc.com/Linux/2013-08/89161.htmStruts2与Spring整合步骤 http://www.linuxidc.com/Linux/2013-08/88248.htmStruts2的入门实例 http://www.linuxidc.com/Linux/2013-05/84618.htm
收藏该网址