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 servlet public 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的path private String className; // action的class private String parameter; // action的parameter private Map<String, ActionForward> forwards; // action的forward public 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 servlet public 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 不需要积分
完