论Servlet的技能重要性

很久没写这样的东西了,我先不说废话了。

我们大家都知道,在javaEE项目中都有一个Web.XML 文件,这是服务器找到我们程序入口的一个配置文件,比如spring 需要配置spring的一个封装的Servlet的,Struts也需要配置Sstruts的一个Servlet文件。

今天我就告诉大家,我们自己封装一个Servlet的一个请求入口。

第一步.您需要新建一个Servlet。如果你的开发工具自动配置了Web.xml那么你就不需要自己去配置这些,如果没有请在Web.xml里面配置上你的Servlet请求。

具体操作如下:

public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String path = request.getServletPath();
		String reqUrl = request.getRequestURL().toString();
		path = reqUrl.split(path)[1];
		System.out.println(path+" \t "+reqUrl + "\t" );
	}

}
接下来配置你的Web.XML

<servlet>
    <servlet-name>IndexServlet</servlet-name>
    <servlet-class>com.Servlet.IndexServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>IndexServlet</servlet-name>
    <url-pattern>/pay/*</url-pattern>
  </servlet-mapping>
没错,就是这样,这样Servlet会将您的所有带"/pay/"的请求连接都进入您的请求连接里面去。

比如: http://localhost:8080/TestWeb/pay/index  http://localhost:8080/TestWeb/pay/xxxx

这样我们就获取了pay 后面带的请求结果。

然后这个有什么作用呢?那么接下来你就懂了。

 Cmd c = CmdDao.getcmd().getpath(path);//获取泛型中类里面的注解
		
		try {
			Class<?> class1 = Class.forName(c.getPath());
			Method method = class1.getDeclaredMethod(c.getExcRun(), HttpServletRequest.class,HttpServletResponse.class);
			method.invoke(class1.newInstance(), request,response);
		} catch (Exception e) {
			System.out.println("处理请求报错错误信息来源:"+c.getPath());
			e.printStackTrace();
			
		}


没错,就是通过后面带的那个连接地址,那就是key,不过我喜欢用cmd来命名,cmd: 命令提示符 

没错就是这个,我封装了一个Cmd的类,这个类我用来存储所有的需要反射的类。也就是带有index这样请求的类。当然,我并不是写死的。我是通过第一次执行的时候进行扫描包文件,将对应的控制器全部扫进去。
这样你执行这个http://localhost:8080/TestWeb/pay/xxxx 那么你的项目里面的
public class index {

	@ServiceMeta(cmd="/xxx",description="这是用来测试的")
	public void xxx(HttpServletRequest request, HttpServletResponse response){
		System.out.println("您好呀,测试通过");
	}
}
这个就执行了。是不是很熟悉,没错这个就是和Spring很像的一个玩意。执行结果:


怎么样。是不是执行了,那么问题来了,怎么通过连接里面的 pay/xxx呢,我想基础好的同学就知道了,因为,在Servlet里面我们已经配置截分割字符串的代码:
String path = request.getServletPath();
		String reqUrl = request.getRequestURL().toString();
		path = reqUrl.split(path)[1];
		System.out.println(path+" \t "+reqUrl + "\t" );

这个里面的代码就可以获取到path = /xxx
所以我们接下来就是通过:
Cmd c = CmdDao.getcmd().getpath(path);//获取泛型中类里面的注解
找到对应的命令路径和命令执行方法,还有命令的注释。 当然我们得通过CmdDao这个方法来获取返回的Cmd对象。
当然啦,接下来我就贴对应的代码:
第一个是Cmd对象:
public class Cmd {

	/**
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:45:26
	 *	@功能  :
	 *	@return :  
	 */
	private String cmd;
	
	private String path;
	
	private String ExcRun;
	
	/**
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:48:00
	 *	@功能  : 通过将
	 *	@return :  
	 */
	public Cmd(){
		
	}
	public Cmd(ServiceMeta meta) {
		super();
		this.cmd = meta.cmd();
		this.path=meta.path();
	}
	public String getCmd() {
		return cmd;
	}
	public void setCmd(String cmd) {
		this.cmd = cmd;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}

	public String getExcRun() {
		return ExcRun;
	}
	public void setExcRun(String excRun) {
		ExcRun = excRun;
	}
}

接下来就是CmdDao的接口

public class CmdDao {

	/**
	 *  @作者  杨英
	 *	@时间  2015年5月19日下午4:36:05
	 *	@功能  :
	 *	@return :  
	 */
	public static CmdDao getcmd(){
		return new CmdDao();
	}
	
	public Cmd getpath(String key){
		Map<String,Object> list = Parent.getParent().init();//获取泛型中类里面的注解
		Cmd c = (Cmd) list.get(key);
		return c;
	}
}

那么接下来就是这个Parent这个类了。
/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:44:06
 *	@功能  :
 *	@return :  
 */
public class Parent {

	//缓存扫描包的数据。
	public static Set<?> e=new HashSet<Object>();
	//缓存扫描包的路径
	public static List<String> pak = new ArrayList<String>();
	/**
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:44:06
	 *	@功能  :
	 *	@return :  
	 */
	public static Parent getParent(){
		return new Parent();
	}
	
	public Map<String,Object> init(){
		//List<Cmd> list = new ArrayList<Cmd>();
		Map<String,Object> list = new HashMap<String,Object>();
		if(pak == null || pak.size()<1){
			pak = Decrypt.getCmd().getInit();
		}
		if(e == null || e.size() < 1){
			e= getClasses(pak);
		}
		for( Iterator<?>   it = e.iterator(); it.hasNext(); )
	    {             
			try {
				String[] a = it.next().toString().split(" ");
				
				Class<?> class1 = Class.forName(a[1]);
				Method[] fields = class1.getMethods();  
				for(Method f : fields){
					//获取字段中包含fieldMeta的注解
					ServiceMeta meta = f.getAnnotation(ServiceMeta.class);
					
					if(meta!=null){
						Cmd sf = new Cmd(meta);
						sf.setPath(a[1]);
						sf.setExcRun(f.getName());
						//list.add(sf);
						list.put(sf.getCmd(), sf);
					}
				}
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
	    }
		return list;
		
	}
	
	/**
	 * 从包package中获取所有的Class
	 * 
	 * @param pack
	 * @return
	 */
	public static Set<Class<?>> getClasses(List<String> pack) {

		// 第一个class类的集合
		Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
		// 是否循环迭代
		boolean recursive = true;
		// 获取包的名字 并进行替换
		for(int i=0;i<pack.size();i++){
			String packageName = pack.get(i);
			String packageDirName = packageName.replace('.', '/');
			// 定义一个枚举的集合 并进行循环来处理这个目录下的things
			Enumeration<URL> dirs;
			try {
				dirs = Thread.currentThread().getContextClassLoader().getResources(
						packageDirName);
				// 循环迭代下去
				while (dirs.hasMoreElements()) {
					// 获取下一个元素
					URL url = dirs.nextElement();
					// 得到协议的名称
					String protocol = url.getProtocol();
					// 如果是以文件的形式保存在服务器上
					if ("file".equals(protocol)) {
						System.err.println("file类型的扫描");
						// 获取包的物理路径
						String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
						// 以文件的方式扫描整个包下的文件 并添加到集合中
						findAndAddClassesInPackageByFile(packageName, filePath,
								recursive, classes);
					
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return classes;
	}
	
	/**
	 * 以文件的形式来获取包下的所有Class
	 * 
	 * @param packageName
	 * @param packagePath
	 * @param recursive
	 * @param classes
	 */
	public static void findAndAddClassesInPackageByFile(String packageName,
			String packagePath, final boolean recursive, Set<Class<?>> classes) {
		// 获取此包的目录 建立一个File
		File dir = new File(packagePath);
		// 如果不存在或者 也不是目录就直接返回
		if (!dir.exists() || !dir.isDirectory()) {
			// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
			return;
		}
		// 如果存在 就获取包下的所有文件 包括目录
		File[] dirfiles = dir.listFiles(new FileFilter() {
			// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
			public boolean accept(File file) {
				return (recursive && file.isDirectory())
						|| (file.getName().endsWith(".class"));
			}
		});
		// 循环所有文件
		for (File file : dirfiles) {
			// 如果是目录 则继续扫描
			if (file.isDirectory()) {
				findAndAddClassesInPackageByFile(packageName + "."
						+ file.getName(), file.getAbsolutePath(), recursive,
						classes);
			} else {
				// 如果是java类文件 去掉后面的.class 只留下类名
				String className = file.getName().substring(0,
						file.getName().length() - 6);
				try {
					// 添加到集合中去
					//classes.add(Class.forName(packageName + '.' + className));
                                         //经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
                                        classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));  
                     } catch (ClassNotFoundException e) {
					// log.error("添加用户自定义视图类错误 找不到此类的.class文件");
					e.printStackTrace();
				}
			}
		}
	}
	
}

接下来就是这个Decrypt类了。
public class Decrypt {

	private static ArrayList<Hashtable<String, String>> li = new ArrayList<Hashtable<String, String>>();
	
	//核心部分的代码
	public ArrayList<Hashtable<String, String>> Cmd(){
		if(li.size()>0){
			System.out.println("Loading I18N file!");
			return li;
		}else{
			li =getCmdLoad();
			return li;
		}
	}
	
	public List<String> getInit(){
		List<String> pack = new ArrayList<String>();
		Decrypt.getCmd().Cmd();  // 加载核心部分内容
		for(int i = 0 ;i<li.size();i++){
			Hashtable<?, ?> a =  (Hashtable<?, ?>) li.get(i);
			pack.add(String.valueOf(a.get("name-path")));
		}
		return pack;
	}

	public ArrayList<Hashtable<String, String>> getCmdLoad(){
		ArrayList<Hashtable<String, String>> a = new ArrayList<Hashtable<String, String>>();
		Element element = null;
		File file = new File(Decrypt.class.getResource("/").getPath()); 
		String FilePath =file.toString(); 
		File f = null;
		try{
			 f = new File(FilePath+"/Cmd.xml");
		}catch(Exception e){
			 f = new File(FilePath+"\\Cmd.xml");
		}
		  DocumentBuilder db = null;
		  DocumentBuilderFactory dbf = null;
		  try {
			   dbf = DocumentBuilderFactory.newInstance();
			   db = dbf.newDocumentBuilder();
			   Document dt = db.parse(f);
			   element = dt.getDocumentElement();
			   NodeList childNodes = element.getChildNodes();
			   for (int i = 0; i < childNodes.getLength(); i++) {
				   Hashtable<String, String> H = new Hashtable<String, String>();
			    // 获得每个对应位置i的结点
			    Node node1 = childNodes.item(i);
			    if ("package".equals(node1.getNodeName())) {

			     NodeList nodeDetail = node1.getChildNodes();
			     for (int j = 0; j < nodeDetail.getLength(); j++) {
			    	 Node detail = nodeDetail.item(j);
				      if("name".equals(detail.getNodeName()) || "#text".equals(detail.getNodeName())){
				      }else{
				    	  H.put(detail.getNodeName(), detail.getTextContent());
				      }
			     }
			     a.add(H);
			    }
			   }
			  }
			  catch (Exception e) {
			   e.printStackTrace();
			  }
		return a;
	}

	public static void main(String[] args){
		System.out.println(getCmd().getInit());
	}
	public static Decrypt getCmd(){
		return new Decrypt();
	}
}

然后这个类了BeanFactory

public class BeanFactory {

	private static Map<String,Object>  li = new HashMap<String,Object>();
	
	//核心部分的代码
	public Map<String,Object>  Cmd(){
		if(li.size()>0){
			System.out.println("Loading I18N file!");
			return li;
		}else{
			li =getCmdLoad();
			return li;
		}
	}
	
	public Map<String,Object> getInit(){
		BeanFactory.getCmd().Cmd();  // 加载核心部分内容
		return li;
	}

	public Map<String,Object> getCmdLoad(){
		Map<String,Object>  a = new HashMap<String,Object>();
		Element element = null;
		File file = new File(Decrypt.class.getResource("/").getPath()); 
		String FilePath =file.toString(); 
		File f = null;
		try{
			 f = new File(FilePath+"/Cmd.xml");
		}catch(Exception e){
			 f = new File(FilePath+"\\Cmd.xml");
		}
		  DocumentBuilder db = null;
		  DocumentBuilderFactory dbf = null;
		  try {
			   dbf = DocumentBuilderFactory.newInstance();
			   db = dbf.newDocumentBuilder();
			   Document dt = db.parse(f);
			   element = dt.getDocumentElement();
			   NodeList childNodes = element.getChildNodes();
			   for (int i = 0; i < childNodes.getLength(); i++) {
				   // 获得每个对应位置i的结点
			    Node node1 = childNodes.item(i);
			    if ("beans".equals(node1.getNodeName())) {
			     NodeList nodeDetail = node1.getChildNodes();
			     for (int j = 0; j < nodeDetail.getLength(); j++) {
			    	 Node detail = nodeDetail.item(j);
				      if("name".equals(detail.getNodeName()) || "#text".equals(detail.getNodeName())){
				      }else{
				    	 String key = detail.getAttributes().getNamedItem("id").getNodeValue();
				    	 String vlaue = detail.getAttributes().getNamedItem("class-path").getNodeValue();
				    	 Class bean = Class.forName(vlaue);
				 		 Object obj = bean.newInstance();
				    	 a.put(key, obj);
				      }
				     
			     }
			    
			    }
			   }
			  }
			  catch (Exception e) {
			   e.printStackTrace();
			  }
		return a;
	}

	public static void main(String[] args){
		/*LoginService  log=  (LoginService) BeanFactory.getCmd().getBean("Login");
		System.out.println(log);
		log.getLogin("", "");*/
	}
	public static BeanFactory getCmd(){
		return new BeanFactory();
	}
	public Object getBean(String key){
		Map<String,Object> beanMap = getCmd().getInit();
		Object obj = beanMap.get(key);
		return obj;
	}
}

然后就是ServiceMeta,注意这是泛型

/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:09:11
 *	@功能  :
 *	@return :  
 */
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface ServiceMeta {

	/**
	 * 所有请求的cmd
	 * @return
	 */                                                                                                                 
	String cmd() default "";
	/**
	 * 
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:26:08
	 *	@功能  :所有请求的路径
	 *	@return :
	 */
	String path() default "";
	/**
	 * 所有请求的备注
	 * @return
	 */
	String description() default "";
}



最关键的就是配置这个文件了,因为我发现如果全盘扫描,那么就会导致一个问题,如果项目庞大的话,就会影响效率,所以我就用了配置文件的方式。配置文件的配置方法:

<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
<!-- 扫描包文件 -->
	<package>
		<name-path>com.Servlet.Service</name-path>
	</package>
<!-- 扫描反转控制,依赖注入 -->	
	<beans>
		<bean id="DBSqlImpl" class-path="com.shop.mvc.DB.Impl.DBSqlImpl"></bean>
	</beans>
	<beans>
		<bean id="LoginServiceImpl" class-path="com.shop.mvc.Servlet.Service.Impl.LoginServiceImpl"></bean>
		<bean id="LoginDaoImpl" class-path="com.shop.mvc.Dao.Impl.LoginDaoImpl"></bean>
		<bean id="User" class-path="com.shop.mvc.Model.User"></bean>
	</beans>

</xml-body>

当然拉,这个里面的package  name-path 里面就是路径:

package com.Servlet.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.shop.mvc.util.SP.ServiceMeta;

public class index {

	@ServiceMeta(cmd="/xxx",description="这是用来测试的")
	public void xxx(HttpServletRequest request, HttpServletResponse response){
		System.out.println("您好呀,测试通过");
	}
}

当然里面也有翻转控制。翻转控制的内容,也很简单。

public static void main(String[] args){
		/*LoginService  log=  (LoginService) BeanFactory.getCmd().getBean("Login");
		System.out.println(log);
		log.getLogin("", "");*/
	}
来来来,如果各位哥哥们觉得这样不好用,那么我教你看看结果。


我接下来就测试下反转控制的作用。

第一步建立一个接口,建立一个实现类



接下来配置Cmd.xml文件


好了我们来测试下这个内容。

public static void main(String[] args){
		DBSql  log=  (DBSql) BeanFactory.getCmd().getBean("Login");
		log.getLogin("傻×", "123");
	}


ok是不是执行了呢,那么我们现在需求发生变化,之前的那个接口实现类不能用了,那么需要重新实现。

只需要从新加一个实现类。


然后修改配置信息

修改完毕后,我们来执行代码


这样就完成了动态实现过程。

有的同学就又疑惑了,这样我每次写一个接口,那样是不是都需要进行配置呢?那我不要疯掉啦?项目多,接口多,实现也多,那样就要崩溃了,不用担心,我也是懒人一个,自然不会这样浪费时间啦,所以我就又依照了Spring的思想进行了整合,也用注解的方式实现。优先加载配置,你们 要记住,配置大于一切,当没有发现配置文件时,就再来加载。所以我无耻的修改了前面的所有代码。别骂我。

package com.shop.mvc.util.SP;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.shop.mvc.DB.DBSql;

public class BeanFactory {

	private static ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<String, Object>();
	private static ConcurrentHashMap<String, Object> mapNew = new ConcurrentHashMap<String, Object>();
	
	//核心部分的代码
	public BeanFactory(){
		if(map.size()==0){
			Xml x = new Xml("Cmd.xml");
			map = x.getCmdLoad("beans");
			for(Map.Entry<String,Object> e: map.entrySet() ){
					try{
						Object obj = Class.forName(String.valueOf(e.getValue())).newInstance();
						map.put(e.getKey(), obj);
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
			}
		}
		if(mapNew.size() == 0){
			mapNew = CmdDao.getcmd().init();
			for(Map.Entry<String,Object> e: mapNew.entrySet() ){
				try{
					Cmd c = (Cmd) e.getValue();
					Object obj = Class.forName(String.valueOf(c.getPath())).newInstance();
					mapNew.put(e.getKey(), obj);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
		}
		}
	}

	public static BeanFactory getCmd(){
		return new BeanFactory();
	}
	
	public Object getBean(String key){
		if(map.get(key) != null){
			return map.get(key);
		}else{
			return mapNew.get(key);
		}
	}
	public static void main(String[] args) {
		DBSql db = (DBSql) BeanFactory.getCmd().getBean("Logins");
		db.getLogin("xxxx", "xxx");
	}
}

Cmd

/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:45:26
 *	@功能  :
 *	@return :  
 */
package com.shop.mvc.util.SP;

/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:45:26
 *	@功能  :
 *	@return :  
 */
public class Cmd {

	/**
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:45:26
	 *	@功能  :
	 *	@return :  
	 */
	private String cmd;
	
	private String path;
	
	private String ExcRun;
	
	/**
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:48:00
	 *	@功能  : 通过将
	 *	@return :  
	 */
	public Cmd(){
		
	}
	public Cmd(ServiceMeta meta) {
		super();
		this.cmd = meta.cmd();
		this.path=meta.path();
	}
	public String getCmd() {
		return cmd;
	}
	public void setCmd(String cmd) {
		this.cmd = cmd;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}

	public String getExcRun() {
		return ExcRun;
	}
	public void setExcRun(String excRun) {
		ExcRun = excRun;
	}
}

/**
 *  @作者  杨英
 *	@时间  2015年5月19日下午4:36:05
 *	@功能  :
 *	@return :  
 */
package com.shop.mvc.util.SP;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 *  @作者  杨英
 *	@时间  2015年5月19日下午4:36:05
 *	@功能  :
 *	@return :  
 */
public class CmdDao {
	public static Set<?> e=new HashSet<Object>();
	
	public ConcurrentHashMap<String, Object> init(){
		ConcurrentHashMap<String, Object> list = new ConcurrentHashMap<String, Object>();
		if(e == null || e.size() < 1){
			try {
				e= Getergodic.getClasses();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		for( Iterator<?>   it = e.iterator(); it.hasNext(); )
	    {             
			try {
				String[] a = it.next().toString().split(" ");
				//System.out.println(a[1]);
				Class<?> class1 = Class.forName(a[1]);
				Method[] fields = class1.getMethods();  
				for(Method f : fields){
					//获取字段中包含fieldMeta的注解
					ServiceMeta meta = f.getAnnotation(ServiceMeta.class);
					if(meta!=null){
						Cmd sf = new Cmd(meta);
						sf.setPath(a[1]);
						sf.setExcRun(f.getName());
						//list.add(sf);
						list.put(sf.getCmd(), sf);
					}
				}
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
	    }
		return list;
	}
	/**
	 *  @作者  杨英
	 *	@时间  2015年5月19日下午4:36:05
	 *	@功能  :
	 *	@return :  
	 */
	public static CmdDao getcmd(){
		return new CmdDao();
	}
	
	
	public Cmd getpath(String key){
		Map<String,Object> list =init();;//获取泛型中类里面的注解
		Cmd c = (Cmd) list.get(key);
		return c;
	}
}


package com.shop.mvc.util.SP;

import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Decrypt {

	private static ArrayList<Hashtable<String, String>> li = new ArrayList<Hashtable<String, String>>();
	
	//核心部分的代码
	public ArrayList<Hashtable<String, String>> Cmd(){
		if(li.size()>0){
			System.out.println("Loading I18N file!");
			return li;
		}else{
			li =getCmdLoad();
			return li;
		}
	}
	
	public List<String> getInit(){
		List<String> pack = new ArrayList<String>();
		Decrypt.getCmd().Cmd();  // 加载核心部分内容
		for(int i = 0 ;i<li.size();i++){
			Hashtable<?, ?> a =  (Hashtable<?, ?>) li.get(i);
			pack.add(String.valueOf(a.get("name-path")));
		}
		return pack;
	}

	public ArrayList<Hashtable<String, String>> getCmdLoad(){
		ArrayList<Hashtable<String, String>> a = new ArrayList<Hashtable<String, String>>();
		Element element = null;
		File file = new File(Decrypt.class.getResource("/").getPath()); 
		String FilePath =file.toString(); 
		File f = null;
		try{
			 f = new File(FilePath+"/Cmd.xml");
		}catch(Exception e){
			 f = new File(FilePath+"\\Cmd.xml");
		}
		  DocumentBuilder db = null;
		  DocumentBuilderFactory dbf = null;
		  try {
			   dbf = DocumentBuilderFactory.newInstance();
			   db = dbf.newDocumentBuilder();
			   Document dt = db.parse(f);
			   element = dt.getDocumentElement();
			   NodeList childNodes = element.getChildNodes();
			   for (int i = 0; i < childNodes.getLength(); i++) {
				   Hashtable<String, String> H = new Hashtable<String, String>();
			    // 获得每个对应位置i的结点
			    Node node1 = childNodes.item(i);
			    if ("package".equals(node1.getNodeName())) {

			     NodeList nodeDetail = node1.getChildNodes();
			     for (int j = 0; j < nodeDetail.getLength(); j++) {
			    	 Node detail = nodeDetail.item(j);
				      if("name".equals(detail.getNodeName()) || "#text".equals(detail.getNodeName())){
				      }else{
				    	  H.put(detail.getNodeName(), detail.getTextContent());
				      }
			     }
			     a.add(H);
			    }
			   }
			  }
			  catch (Exception e) {
			   e.printStackTrace();
			  }
		return a;
	}

	public static void main(String[] args){
		System.out.println(getCmd().getInit());
	}
	public static Decrypt getCmd(){
		return new Decrypt();
	}
}

package com.shop.mvc.util.SP;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

public class Getergodic {
	static Set<Class<?>> getClasses() throws IOException {
		
		File directory = new File("");// 参数为空
		String courseFile = courseFile = directory.getCanonicalPath().toString().replace("\\", "/");
		String[] st = courseFile.split("/");
		String spl = st[st.length-1];
		String temp1 = Getergodic.class.getResource("/").getFile().toString().split(spl)[1];
		String path  =courseFile+temp1;
		
		File file = new File(path);
		File[] ft = file.listFiles();
		Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
		for(int i =0 ; i < ft.length ; i++){
			try {
				Select(ft[i],classes);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				break;
			}
		}
		return classes;
	}
	
	private static void Select(File f,Set<Class<?>> classes) throws Exception{
		
		if(f.isFile()){
			String path = f.getPath().toString();
			if(path.indexOf(".class")>0){
				String pathcals = f.getPath().toString().split("classes")[1];
				try{
					pathcals = pathcals.substring(1, pathcals.length()).replace("\\",".").replace(".class", "");
				}catch(Exception e){
					pathcals = pathcals.substring(1, pathcals.length()).replace("/",".").replace(".class", "");
				}
				classes.add(Thread.currentThread().getContextClassLoader().loadClass(pathcals)); 
			}
		}else{
			File[] ft = f.listFiles();
			for(int i =0 ; i < ft.length ; i++){
				Select(ft[i],classes);
			}
		}
	}
}
package com.shop.mvc.util.SP;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *  @作者  杨英
 *	@时间  2016年1月26日下午14:42:11
 *	@功能  :
 *	@return :  
 */
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface ImplMeta {

	String key() default "";
	String path() default "";
	String ExcRun() default "";
	
}

/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:44:06
 *	@功能  :
 *	@return :  
 */
package com.shop.mvc.util.SP;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:44:06
 *	@功能  :
 *	@return :  
 */
public class Parent {

	//缓存扫描包的数据。
	public static Set<?> e=new HashSet<Object>();
	//缓存扫描包的路径
	public static List<String> pak = new ArrayList<String>();
	/**
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:44:06
	 *	@功能  :
	 *	@return :  
	 */
	public static Parent getParent(){
		return new Parent();
	}
	
	public Map<String,Object> init(){
		//List<Cmd> list = new ArrayList<Cmd>();
		Map<String,Object> list = new HashMap<String,Object>();
		if(pak == null || pak.size()<1){
			pak = Decrypt.getCmd().getInit();
		}
		if(e == null || e.size() < 1){
			e= getClasses(pak);
		}
		for( Iterator<?>   it = e.iterator(); it.hasNext(); )
	    {             
			try {
				String[] a = it.next().toString().split(" ");
				
				Class<?> class1 = Class.forName(a[1]);
				Method[] fields = class1.getMethods();  
				for(Method f : fields){
					//获取字段中包含fieldMeta的注解
					ServiceMeta meta = f.getAnnotation(ServiceMeta.class);
					
					if(meta!=null){
						Cmd sf = new Cmd(meta);
						sf.setPath(a[1]);
						sf.setExcRun(f.getName());
						//list.add(sf);
						list.put(sf.getCmd(), sf);
					}
				}
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
	    }
		return list;
		
	}
	
	/**
	 * 从包package中获取所有的Class
	 * 
	 * @param pack
	 * @return
	 */
	public static Set<Class<?>> getClasses(List<String> pack) {

		// 第一个class类的集合
		Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
		// 是否循环迭代
		boolean recursive = true;
		// 获取包的名字 并进行替换
		for(int i=0;i<pack.size();i++){
			String packageName = pack.get(i);
			String packageDirName = packageName.replace('.', '/');
			// 定义一个枚举的集合 并进行循环来处理这个目录下的things
			Enumeration<URL> dirs;
			try {
				dirs = Thread.currentThread().getContextClassLoader().getResources(
						packageDirName);
				// 循环迭代下去
				while (dirs.hasMoreElements()) {
					// 获取下一个元素
					URL url = dirs.nextElement();
					// 得到协议的名称
					String protocol = url.getProtocol();
					// 如果是以文件的形式保存在服务器上
					if ("file".equals(protocol)) {
						System.err.println("file类型的扫描");
						// 获取包的物理路径
						String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
						// 以文件的方式扫描整个包下的文件 并添加到集合中
						findAndAddClassesInPackageByFile(packageName, filePath,
								recursive, classes);
					
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return classes;
	}
	
	/**
	 * 以文件的形式来获取包下的所有Class
	 * 
	 * @param packageName
	 * @param packagePath
	 * @param recursive
	 * @param classes
	 */
	public static void findAndAddClassesInPackageByFile(String packageName,
			String packagePath, final boolean recursive, Set<Class<?>> classes) {
		// 获取此包的目录 建立一个File
		File dir = new File(packagePath);
		// 如果不存在或者 也不是目录就直接返回
		if (!dir.exists() || !dir.isDirectory()) {
			// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
			return;
		}
		// 如果存在 就获取包下的所有文件 包括目录
		File[] dirfiles = dir.listFiles(new FileFilter() {
			// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
			public boolean accept(File file) {
				return (recursive && file.isDirectory())
						|| (file.getName().endsWith(".class"));
			}
		});
		// 循环所有文件
		for (File file : dirfiles) {
			// 如果是目录 则继续扫描
			if (file.isDirectory()) {
				findAndAddClassesInPackageByFile(packageName + "."
						+ file.getName(), file.getAbsolutePath(), recursive,
						classes);
			} else {
				// 如果是java类文件 去掉后面的.class 只留下类名
				String className = file.getName().substring(0,
						file.getName().length() - 6);
				try {
					// 添加到集合中去
					//classes.add(Class.forName(packageName + '.' + className));
                                         //经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
                                        classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));  
                     } catch (ClassNotFoundException e) {
					// log.error("添加用户自定义视图类错误 找不到此类的.class文件");
					e.printStackTrace();
				}
			}
		}
	}
	
}


/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:09:11
 *	@功能  :
 *	@return :  
 */
package com.shop.mvc.util.SP;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *  @作者  杨英
 *	@时间  2015年5月18日下午5:09:11
 *	@功能  :
 *	@return :  
 */
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface ServiceMeta {

	/**
	 * 所有请求的cmd
	 * @return
	 */                                                                                                                 
	String cmd() default "";
	/**
	 * 
	 *  @作者  杨英
	 *	@时间  2015年5月18日下午5:26:08
	 *	@功能  :所有请求的路径
	 *	@return :
	 */
	String path() default "";
	/**
	 * 所有请求的备注
	 * @return
	 */
	String description() default "";
}

package com.shop.mvc.util.SP;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

public class Util {

	public static Cookie setCookie(String key,String value){
		Cookie c = new Cookie(key,value);
		c.setMaxAge(1000*60*60*360);
		return c;
	}
	
	public static String getCookie(String key,HttpServletRequest request){
		Cookie[] t = request.getCookies();
		for(Cookie c:t){
			if(key.equals(c.getName())){
				return c.getValue();
			}
		}
		return "";
	}
	
	public static String getRandCode(int max){
		String code = "";
		for(int i = 0 ; i < max ; i++){
			String temp = String.valueOf(Math.random()*10).substring(0, 1);
			code = code+ temp;
		}
		return code;
	}
	
	public static String getNextDay(int i) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH,  i);
		Date date = calendar.getTime();
		return df.format(date).substring(0,10);
	}
}

package com.shop.mvc.util.SP;

import java.io.File;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class Xml {

	private  String path; 
	
	public Xml(String xmlpath){
		this.path = xmlpath;
	} 
	
	public ConcurrentHashMap<String,Object> getCmdLoad(String Node){
		ConcurrentHashMap<String,Object>  a = new ConcurrentHashMap<String,Object>();
		Element element = null;
		File file = new File(this.getClass().getResource("/").getPath()); 
		String FilePath =file.toString(); 
		File f = null;
		try{
			 f = new File(FilePath+"/"+path);
		}catch(Exception e){
			 f = new File(FilePath+"\\"+path);
		}
		  DocumentBuilder db = null;
		  DocumentBuilderFactory dbf = null;
		  try {
			   dbf = DocumentBuilderFactory.newInstance();
			   db = dbf.newDocumentBuilder();
			   Document dt = db.parse(f);
			   element = dt.getDocumentElement();
			   NodeList childNodes = element.getChildNodes();
			   for (int i = 0; i < childNodes.getLength(); i++) {
			    Node node1 = childNodes.item(i);
			    
			    if (Node.equals(node1.getNodeName())) {
			    	
			    	NodeList nodeDetail = node1.getChildNodes();
			    
			     for (int j = 0; j < nodeDetail.getLength(); j++) {
			    	 Node detail = nodeDetail.item(j);
				      if(!"#text".equals(detail.getNodeName())){
				    	  String key = detail.getAttributes().getNamedItem("id").getNodeValue();
				    	  String vlaue = detail.getAttributes().getNamedItem("class-path").getNodeValue();
				    	  a.put(key, vlaue);
				      }
				    
			     }
			    }
			   }
			  }
			  catch (Exception e) {
			   e.printStackTrace();
			  }
		return a;
	}
}

package com.Servlet;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.shop.mvc.util.SP.Cmd;
import com.shop.mvc.util.SP.CmdDao;

/**
 * Servlet implementation class IndexServlet
 */
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String path = request.getServletPath();
		String reqUrl = request.getRequestURL().toString();
		path = reqUrl.split(path)[1];
		System.out.println(path+" \t "+reqUrl + "\t" );
		
		Cmd c = CmdDao.getcmd().getpath(path);//获取泛型中类里面的注解
		try {
			Class<?> class1 = Class.forName(c.getPath());
			Method method = class1.getDeclaredMethod(c.getExcRun(), HttpServletRequest.class,HttpServletResponse.class);
			method.invoke(class1.newInstance(), request,response);
		} catch (Exception e) {
			System.out.println("处理请求报错错误信息来源:"+c.getPath());
			e.printStackTrace();
			
		}
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值