只有一个servlet,这个servlet处理所有的*.do;
当有请求来时,根据请求的uri,选择对应的action进行处理;
action和uri使用注解来相互映射,中央控制的servlet在启动的时候就扫描classes目录下面的所有class文件,找出带有注解的类,并放入map中,key为uri的值,value为action对象;
需要自定义classloader来加载指定目录下的classes文件;
1.定义注解:
package com.oterman;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Control {
String value();
}
|
2.定义Action
package com.oterman;
@Control("/book" )
public class BookAction
{
/**
* 默认执行该方法
*/
public void exec()
{
System.out.println( "exec()....执行了哦" );
System.out.println( this.getClass().getClassLoader());//com.oterman.MyClassLoader@3d637d45
}
public void add(){
System.out.println( "add()....执行了哦" );
}
public void delete(){
System.out.println( "delete()....执行了哦" );
}
}
|
3.定义中央处理的ControllServlet,该servlet的映射为:
<servlet >
<servlet-name >ControllServlet </servlet-name>
<servlet-class> com.oterman.ControllServlet</servlet-class >
</servlet >
<servlet-mapping >
<servlet-name >ControllServlet </servlet-name>
<url-pattern >*.do </url-pattern>
</servlet-mapping >
|
ControllServlet.java
package com.oterman;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ControllServlet extends HttpServlet
{
private Map<String,
Object> actionMap = null ;
@Override
public void init() throws ServletException
{
super.init();
//中央处理servlet创建时,扫描classes目录下所有的class文件,找出action的class,并将 uri和对应的action放入到map中去;
actionMap = new HashMap<String,
Object>();
String classpath = this.getServletContext().getRealPath("/WEB-INF/classes" );
File dir = new File(classpath);
try {
scanClass(dir);
} catch (Exception
e) {
e.printStackTrace();
}
}
//判断一个文件是目录还是文件,如果是文件,判断是否为class文件,如果为class文件,判断是有注解!
public void scanClass(File
dir) throws Exception {
if (dir.isDirectory())
{//为目录
File[] files = dir.listFiles();
for (File
file : files) {
scanClass(file); //迭代操作
}
}
if (dir.isFile())
{//为文件
if (dir.getName().endsWith(".class" ))
{
//将硬盘上的class文件读取为byte[];
FileInputStream fis = new FileInputStream(dir);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[]
buffer = new byte[1024];
int len
= 0;
while ((len
= fis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
byte[]
bytes = bos.toByteArray();//class文件的字节码
//自定义classloader,将byte[]翻译成class对象
MyClassLoader classloader = new MyClassLoader(this.getClass().getClassLoader());
Class clazz =classloader.getClass(bytes);
//判断该类上是否有注解,如果有,则放入map中去;
Control annotation
= ( Control) clazz.getAnnotation(Control.class) ;
if (annotation
!= null) {
String uri = annotation.value();
actionMap.put(uri,
clazz.newInstance());
}
}
}
}
public void doGet(HttpServletRequest
request, HttpServletResponse response)
throws ServletException,
IOException {
//获取请求参数的 uri;
String uri = request.getRequestURI(); //
/MySimpleWebFrame/book.do
String url = request.getRequestURL().toString();//http://localhost/MySimpleWebFrame/book.do
//截取需要的uri;/book
uri=uri.substring(uri.lastIndexOf( "/"),
uri.lastIndexOf("." ));
System. out.println(uri);
//根据uri,查找map,得到处理请求的action
Object action= actionMap.get(uri);
if(action==null ){
throw new RuntimeException("该请求没有对应的action!" );
}
//得到请求参数method,调用action相应的方法;
String methodname=request.getParameter("method" );
if(methodname==null){//如果请求参数没有改方法,则默认执行 exec方法!
methodname= "exec";
}
Method method= null;
try {
method= action.getClass().getMethod(methodname, null);
} catch (SecurityException
e) {
e.printStackTrace();
} catch (NoSuchMethodException
e) {
e.printStackTrace();
throw new RuntimeException("该action上没有"+methodname+ "方法!");
}
//调用该方法
try {
method.invoke(action, null);
} catch (IllegalArgumentException
e) {
e.printStackTrace();
} catch (IllegalAccessException
e) {
e.printStackTrace();
} catch (InvocationTargetException
e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest
request, HttpServletResponse response)
throws ServletException,
IOException {
doGet(request, response);
}
}
/**
* 自定义类加载器,将byte[]加载为class对象
* @author oterman
*
*/
class MyClassLoader extends ClassLoader{
//自定父加载器,按照加载机制进行加载!加载一个类时,都先交给父类加载,父类加载不了,才一级一级往下传!
public MyClassLoader(ClassLoader
parent) {
super(parent);
}
public Class getClass(byte[]
bytes){
System. out.println("myclassloader2...." );
return defineClass(null,
bytes, 0, bytes.length);
}
}
|