serlvet的mvc架构最简版
写了个最简单的最粗糙的mvc的架构。
在web的xml中配置过滤器以及在页面上显示的标签。
<filter> <filter-name>bushyou</filter-name> <filter-class>com.bushyou.servlet.dispatcher.FilterDispatcher</filter-class> </filter> <!-- Extension --> <filter-mapping> <filter-name>bushyou</filter-name> <url-pattern>*.html</url-pattern> </filter-mapping> <jsp-config> <taglib> <taglib-uri>/bushyou</taglib-uri> <taglib-location>/WEB-INF/bushyou.tld</taglib-location> </taglib> </jsp-config>
将web的含有.html的请求都经过FilterDispatcher这个过滤器。
在FilterDispatcher中。/** * 拦截请求 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.servlet.dispatcher; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.bushyou.action.IAction; import com.bushyou.servlet.context.ActionMapper; import com.bushyou.servlet.context.ListBushyouActionMapper; import com.bushyou.servlet.context.ValueContext; public class FilterDispatcher implements Filter { private FilterConfig filterConfig; @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; ServletContext servletContext = getServletContext(); //将request,response,servletContext放入值域中。 ValueContext valueContext = new ValueContext(request, response, servletContext); //将值域放入request对象中。 request.setAttribute("bushyou_value_context", valueContext); //返回的jsp页面。mvc中的 v String pa = ""; if (ListBushyouActionMapper.map.containsKey(valueContext.getPath())) { ActionMapper actionMapper = ListBushyouActionMapper.map.get(valueContext.getPath()); valueContext.setActionMapper(actionMapper); IAction action = null; String returnStr = null; try { //反射出acion对象。 Class classType = Class.forName(valueContext.getActionMapper().getClassPath()); //执行构造函数。 Constructor constructor = classType.getConstructor(); action = (IAction) constructor.newInstance(); //执行excuse方法。得到返回值。 returnStr = action.excute(); } catch (ClassNotFoundException e) { } catch (SecurityException e) { } catch (NoSuchMethodException e) { } catch (IllegalArgumentException e) { } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } //将action对象放入值域中。 valueContext.setAction(action); pa = valueContext.getActionMapper().getReturnUrl(); } //forward RequestDispatcher requestDispatcher = request .getRequestDispatcher(pa); requestDispatcher.forward(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } protected ServletContext getServletContext() { return filterConfig.getServletContext(); } }
在上面的代码中。我们已经将整个mvc的过程走完了。
当请求经过这个过滤器的时候,过滤器想将值域放入request对象,然后反射出action对象。执行提供出去的excuse方法。
/** * 值栈 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.servlet.context; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.bushyou.action.IAction; public class ValueContext { ValueMap valueMap; //值域,放入的request,response,servletContext,action执行后 对象 ActionMapper actionMapper ; //action对象 List extensions = new ArrayList() {{ add("html");}}; IAction action; String path; public ValueContext(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) { valueMap = new ValueMap(); valueMap.setRequest(request); valueMap.setResponse(response); valueMap.setServletContext(servletContext); String path = getServletPath(request); this.path = path; path = dropExtension(path); parseNameAndNamespace(path); } /** * 拿到请求的url * @param request * @return */ public static String getServletPath(HttpServletRequest request) { String servletPath = request.getServletPath(); if (null != servletPath && !"".equals(servletPath)) { return servletPath; } String requestUri = request.getRequestURI(); int startIndex = request.getContextPath().equals("") ? 0 : request.getContextPath().length(); int endIndex = request.getPathInfo() == null ? requestUri.length() : requestUri.lastIndexOf(request.getPathInfo()); if (startIndex > endIndex) { // this should not happen endIndex = startIndex; } return requestUri.substring(startIndex, endIndex); } String dropExtension(String name) { if (extensions == null) { return name; } Iterator it = extensions.iterator(); while (it.hasNext()) { String extension = "." + (String) it.next(); if (name.endsWith(extension)) { name = name.substring(0, name.length() - extension.length()); return name; } } return name; } /** * 解析成 actionMapper对象。 * @param uri */ void parseNameAndNamespace(String uri) { String namespace, name; int lastSlash = uri.lastIndexOf("/"); if (lastSlash == -1) { namespace = ""; name = uri; } else if (lastSlash == 0) { // ww-1046, assume it is the root namespace, it will fallback to // default // namespace anyway if not found in root namespace. namespace = "/"; name = uri.substring(lastSlash + 1); }else { namespace = uri.substring(0, lastSlash); name = uri.substring(lastSlash + 1); } if (name != null) { int pos = name.lastIndexOf('/'); if (pos > -1 && pos < name.length() - 1) { name = name.substring(pos + 1); } } actionMapper = new ActionMapper(); actionMapper.setActionName(name); actionMapper.setNamespace(namespace); } public Map getValueMap() { return valueMap; } public IAction getAction() { return action; } public void setAction(IAction action) { this.valueMap.setAction(action); this.action = action; } public ActionMapper getActionMapper() { return actionMapper; } public void setActionMapper(ActionMapper actionMapper) { this.actionMapper = actionMapper; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } }上面是放入的值域。主要是用在前台的jsp标签使用。
/** * property 标签,用于显示属性。 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.servlet.tag; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; import com.bushyou.servlet.context.ValueContext; public class PropertyTag extends BodyTagSupport { @Override public int doEndTag() throws JspException { HttpServletRequest request = (HttpServletRequest) pageContext .getRequest(); ValueContext valueContext = (ValueContext) request .getAttribute("bushyou_value_context"); Object o = valueContext.getValueMap().get(value); // 取得标签体对象 try { pageContext.getOut().write((String)o); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return super.doAfterBody(); } private String value; private boolean escape; private static final long serialVersionUID = 8921307524633290358L; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public boolean isEscape() { return escape; } public void setEscape(boolean escape) { this.escape = escape; } }
上面是jsp的自定义标签的方法。
/** * 继承hashmap * * 在页面上用于展现的时候,所有的值域都在这个容器内。 * * 复写他的get方法 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.servlet.context; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.bushyou.action.IAction; public class ValueMap<K, V> extends HashMap<K, V> { /** * */ private static final long serialVersionUID = 4023788960770640801L; HttpServletRequest request; HttpServletResponse response; ServletContext servletContext; IAction action; public void setRequest(HttpServletRequest request) { this.request = request; } public void setResponse(HttpServletResponse response) { this.response = response; } public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } @Override public V get(Object key) { V v = null; Class classType = action.getClass(); try { Field field = classType.getDeclaredField((String) key); if (!Modifier.isPublic(field.getModifiers())) { field.setAccessible(true); } v = (V) field.get(action); } catch (SecurityException e) { } catch (NoSuchFieldException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } if (v != null) { return v; } v = super.get(key); if (v != null) { return v; } v = (V) request.getAttribute(key + ""); if (v != null) { return v; } return v; } public void setAction(IAction action) { this.action = action; } }
从标签中取值的相应的类。
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>b</short-name> <uri>http://www.koubei.com</uri> <tag> <name>property</name> <tag-class>com.bushyou.servlet.tag.PropertyTag</tag-class> <body-content>JSP</body-content> <attribute> <name>value</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description><![CDATA[Value to be displayed]]></description> </attribute> <attribute> <name>escape</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description><![CDATA[ Whether to escape HTML]]></description> </attribute> </tag> </taglib>
tld文件。
现在写点测试的例子:
/** * mvc的m的入口 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.action; import java.io.Serializable; public interface IAction extends Serializable{ String excute(); }
/** * hello的例子 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.action; public class YeXiaoGangHelloAction implements IAction{ /** * */ private static final long serialVersionUID = -5712396283469842107L; private String str1; private String str2; @Override public String excute() { str1 = "hello str1"; str2 = "hello str2"; return "success"; } public String getStr1() { return str1; } public void setStr1(String str1) { this.str1 = str1; } public String getStr2() { return str2; } public void setStr2(String str2) { this.str2 = str2; } }
/** * test的例子 * * @author shanzhu * @version 1.0 2011-9-29 */ package com.bushyou.action; public class YeXiaoGangTestAction implements IAction{ /** * */ private static final long serialVersionUID = -5712396283469842107L; private String str1; private String str2; @Override public String excute() { str1 = "test str1"; str2 = "test str2"; return "success"; } public String getStr1() { return str1; } public void setStr1(String str1) { this.str1 = str1; } public String getStr2() { return str2; } public void setStr2(String str2) { this.str2 = str2; } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@taglib prefix="b" uri="/bushyou" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>First HelloWorldServlet</title> </head> <body> 11 <br /> <b:property value="str1"></b:property> <br /> 22222 <br /> <b:property value="str2"></b:property> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@taglib prefix="b" uri="/bushyou" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>test</title> </head> <body> <b:property value="str1"></b:property> || <b:property value="str2"></b:property> </body> </html>
在浏览器上输入http://localhost/testweb/yexiaogang/hello.html
http://localhost/testweb/yexiaogang/test.html
就可以看到效果了。
相关推荐
cywhoyi 2020-11-23
rise 2020-11-22
sssdssxss 2020-11-20
xuedabao 2020-11-19
alien 2020-11-15
JLow 2020-11-12
ruancw 2020-11-10
地平线 2020-11-02
yinren 2020-11-02
evolone 2020-10-29
liupengqwert 2020-10-28
acaoye 2020-10-27
jyj0 2020-10-27
ruancw 2020-10-27
JAVA飘香 2020-10-26
withjeffrey 2020-10-23
litefish 2020-10-16
richermen 2020-10-15
kjyiyi 2020-10-10