mystruts简易MVC框架实现
mvc架构模式的简单实现,希望对大家有所帮助,全部代码如下
主要有如下几个类和接口组成:

具体代码如下:
package com.yanek.mvc;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public interface Action {public ActionRouter perform(HttpServlet servlet, HttpServletRequest req,HttpServletResponse res) throws java.io.IOException,javax.servlet.ServletException;}
package com.yanek.mvc;import java.util.Hashtable;public class ActionFactory {private Hashtable actions = new Hashtable();// This method is called by the action servletpublic Action getAction(String classname, ClassLoader loader)throws ClassNotFoundException, IllegalAccessException,InstantiationException {Action action = (Action) actions.get(classname);if (action == null) {Class klass = loader.loadClass(classname);action = (Action) klass.newInstance();actions.put(classname, action);}return action;}}
package com.yanek.mvc;public class ActionForward {private String name; private String viewUrl;public static final ActionForward SUCCESS=new ActionForward("success");public static final ActionForward FAIL=new ActionForward("fail");public ActionForward(String name){this.name=name;}public ActionForward(String name, String viewUrl) {super();this.name = name;this.viewUrl = viewUrl;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getViewUrl() {return viewUrl;}public void setViewUrl(String viewUrl) {this.viewUrl = viewUrl;}}
package com.yanek.mvc;import java.util.Map;public class ActionMapping {private String path; // action的pathprivate String className; // action的classprivate String parameter; // action的parameterprivate Map<String, ActionForward> forwards; // action的forwardpublic ActionMapping() {}public ActionMapping(String path, String className,Map<String, ActionForward> forwards) {super();this.path = path;this.className = className;this.forwards = forwards;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public Map<String, ActionForward> getForwards() {return forwards;}public void setForwards(Map<String, ActionForward> forwards) {this.forwards = forwards;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getParameter() {return parameter;}public void setParameter(String parameter) {this.parameter = parameter;}}
package com.yanek.mvc;import java.util.Map;import javax.servlet.GenericServlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yanek.util.Constant;public class ActionRouter {private final String key;private final boolean isForward;public ActionRouter(String key) {this(key, true); // forward by default}public ActionRouter(String key, boolean isForward) {this.key = key;this.isForward = isForward;}// This method is called by the action servletpublic synchronized void route(GenericServlet servlet,HttpServletRequest req, HttpServletResponse res)throws ServletException, java.io.IOException { Map<String, ActionMapping> actions = (Map<String, ActionMapping>) servlet.getServletContext().getAttribute(Constant.ACTIONS_ATTR); ActionMapping actionModel = actions.get(getActionKey(req)); ActionForward af=actionModel.getForwards().get(key); String url=af.getViewUrl();if (isForward) {servlet.getServletContext().getRequestDispatcher(res.encodeURL(url)).forward(req, res);} else {res.sendRedirect(res.encodeRedirectURL(url));}} private String getActionKey(HttpServletRequest req) { String path = req.getServletPath(); int slash = path.lastIndexOf("/"), period = path.lastIndexOf("."); if(period > 0 && period > slash) path = path.substring(slash+1, period); return path; }}
package com.yanek.mvc;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import com.yanek.util.ConfigUtil;import com.yanek.util.Constant;public class ActionServlet extends HttpServlet {private static final Log log = LogFactory.getLog(ActionServlet.class); private ActionFactory factory = new ActionFactory(); public void init(ServletConfig config) throws ServletException{ super.init(config); String config_file =getServletConfig().getInitParameter("config"); if (config_file == null || config_file.equals("")) {config_file = "/WEB-INF/mystruts-config.xml"; }try {Map<String, ActionMapping> resources = ConfigUtil.newInstance().parse(config_file, getServletContext());getServletContext().setAttribute(Constant.ACTIONS_ATTR, resources);log.info("初始化mystruts配置文件成功");} catch (Exception e) {log.error("初始化mystruts配置文件失败");e.printStackTrace();} } public void service(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException, ServletException { try { String actionClass = getActionClass(req); Action action = factory.getAction(actionClass, getClass().getClassLoader()); Map<String, ActionMapping> actions = (Map<String, ActionMapping>) getServletContext().getAttribute(Constant.ACTIONS_ATTR); ActionMapping actionModel = actions.get(getActionKey(req)); String parameter=actionModel.getParameter(); if (parameter==null) { parameter=""; } String methodName=""; if (!parameter.equals("")) { methodName=req.getParameter(parameter); } System.out.println("parameter=="+parameter); System.out.println("parameter value methodName:=="+methodName); if (methodName!=null) { Method method = null; try { method = getMethod(action.getClass(),methodName); ActionRouter router = null; Object args[] = {this, req, res}; router = (ActionRouter) method.invoke(action, args); router.route(this, req, res); } catch(NoSuchMethodException e) { log.error("no method error!", e); throw e; } } else { ActionRouter router = action.perform(this,req,res); router.route(this, req, res); } } catch(Exception e) { throw new ServletException(e); } } private String getClassname(HttpServletRequest req) { String path = req.getServletPath(); int slash = path.lastIndexOf("/"), period = path.lastIndexOf("."); if(period > 0 && period > slash) path = path.substring(slash+1, period); return path; } private String getActionClass(HttpServletRequest req) { Map<String, ActionMapping> actions = (Map<String, ActionMapping>) getServletContext().getAttribute(Constant.ACTIONS_ATTR); ActionMapping actionModel = actions.get(getActionKey(req)); return actionModel.getClassName(); } private String getActionKey(HttpServletRequest req) { String path = req.getServletPath(); int slash = path.lastIndexOf("/"), period = path.lastIndexOf("."); if(period > 0 && period > slash) path = path.substring(slash+1, period); return path; } protected Method getMethod(Class actionclazz,String name) throws NoSuchMethodException { synchronized(methods) { Method method = (Method) methods.get(name); if (method == null) { method = actionclazz.getMethod(name, types); methods.put(name, method); } return (method);} } protected Class[] types ={HttpServlet.class,HttpServletRequest.class,HttpServletResponse.class}; protected HashMap methods = new HashMap(); }
package com.yanek.util;import java.io.InputStream;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletContext;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;import com.yanek.mvc.ActionForward;import com.yanek.mvc.ActionMapping;/** * xml配置文件解析工具类 */public class ConfigUtil {private static final Log log=LogFactory.getLog(ConfigUtil.class);private String file_path;protected static final ConfigUtil single=new ConfigUtil();private ConfigUtil(){}public static ConfigUtil newInstance(){return single;}public String getFile_path() {return file_path;}public void setFile_path(String file_path) {this.file_path = file_path;} public Map<String, ActionMapping> parse(String file_path,ServletContext context)throws Exception{ this.file_path=file_path; InputStream is=context.getResourceAsStream(file_path); log.info("正在读取配置文件:"+file_path); return parseXML(is); } private Map<String, ActionMapping> parseXML(InputStream is)throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(is); NodeList actions=doc.getElementsByTagName("action"); int size=actions.getLength(); Map<String, ActionMapping> result=new HashMap<String, ActionMapping>(); ActionMapping actionModel=null; Map<String, ActionForward> forwards=null; log.info("正在解析配置文件:"+file_path); for(int i=0;i<size;i++){ Element xml_action=(Element)actions.item(i); actionModel=new ActionMapping(); actionModel.setClassName(xml_action.getAttribute("class")); actionModel.setPath(xml_action.getAttribute("path")); actionModel.setParameter(xml_action.getAttribute("parameter")); NodeList xml_forwards=xml_action.getElementsByTagName("forward"); forwards=new HashMap<String, ActionForward>(); for(int j=0;j<xml_forwards.getLength();j++){ Element forward=(Element)xml_forwards.item(j); forwards.put(forward.getAttribute("name"), new ActionForward(forward.getAttribute("name"),forward.getAttribute("url"))); } actionModel.setForwards(forwards); result.put(actionModel.getPath(), actionModel); } return result; }}
package com.yanek.util;public class Constant {public static final String ACTIONS_ATTR = "Actions";}
package com.yanek.util;import java.io.IOException;import javax.servlet.*;public class CharacterEncodingFilter implements Filter{ protected String encoding; protected FilterConfig filterConfig; protected boolean ignore; public CharacterEncodingFilter() { encoding = null; filterConfig = null; ignore = true; } public void destroy() { encoding = null; filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if(ignore || request.getCharacterEncoding() == null) { String encoding = selectEncoding(request); if(encoding != null) request.setCharacterEncoding(encoding); } chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; encoding = filterConfig.getInitParameter("encoding"); String value = filterConfig.getInitParameter("ignore"); if(value == null) ignore = true; else if(value.equalsIgnoreCase("true")) ignore = true; else if(value.equalsIgnoreCase("yes")) ignore = true; else ignore = false; } protected String selectEncoding(ServletRequest request) { return encoding; }}
测试类:
package com.yanek.test;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yanek.mvc.Action;import com.yanek.mvc.ActionRouter;public class TestAction implements Action {public ActionRouter perform(HttpServlet servlet, HttpServletRequest request,HttpServletResponse res) throws IOException, ServletException {String id=(String)request.getParameter("id");request.setAttribute("id",id);return new ActionRouter("test-page");}public ActionRouter add(HttpServlet servlet, HttpServletRequest request,HttpServletResponse res) throws IOException, ServletException {String id=(String)request.getParameter("id");request.setAttribute("id",id);return new ActionRouter("add");}}
mystruts-config.xml
<?xml version="1.0" encoding="UTF-8"?><action-mappings> <action path="test" class="com.yanek.test.TestAction" parameter="method"> <forward name="test-page" url="/WEB-INF/jsp/test.jsp"/> <forward name="add" url="/WEB-INF/jsp/add.jsp"/> </action> </action-mappings>
web.xml配置
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter><filter-name>SetCharacterEncoding</filter-name><filter-class>com.yanek.util.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>SetCharacterEncoding</filter-name><url-pattern>/*</url-pattern></filter-mapping> <servlet> <servlet-name>action</servlet-name> <servlet-class>com.yanek.mvc.ActionServlet</servlet-class><!-- <init-param><param-name>action-mappings</param-name><param-value>actions</param-value></init-param>--> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/mystruts-config.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>
测试jsp 页面: add.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%><%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> <base href="<%=basePath%>"> <title>This is mvc test JSP page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--> </head> <body> add ! </body></html>
测试jsp 页面: test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%><%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> <base href="<%=basePath%>"> <title>This is mvc test JSP page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--> </head> <body> This is a mvc test JSP page. <br> path: /WEB-INF/jsp/test.jsp <br> id: <%=(String)request.getAttribute("id") %> </body></html>
测试效果:


代码下载地址: http://download.csdn.net/detail/5iasp/5026228 不需要积分
完