很久没写这样的东西了,我先不说废话了。
我们大家都知道,在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();
}
public class index {
@ServiceMeta(cmd="/xxx",description="这是用来测试的")
public void xxx(HttpServletRequest request, HttpServletResponse response){
System.out.println("您好呀,测试通过");
}
}
这个就执行了。是不是很熟悉,没错这个就是和Spring很像的一个玩意。执行结果:
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对象。
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();
}
}
}