只有一个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);
}
}
|