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 不需要积分
完