[置顶] mystruts简易MVC框架实现

mvc架构模式的简单实现,希望对大家有所帮助,全部代码如下

主要有如下几个类和接口组成:

[置顶] mystruts简易MVC框架实现_第1张图片

 

具体代码如下:

 

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>


 

 

 

测试效果:

 

[置顶] mystruts简易MVC框架实现_第2张图片[置顶] mystruts简易MVC框架实现_第3张图片

 

 

 

 

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

 

 

你可能感兴趣的:([置顶] mystruts简易MVC框架实现)