加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
MyDispatcherServlet.java 6.39 KB
一键复制 编辑 原始数据 按行查看 历史
jerry 提交于 2019-04-03 17:40 . sss
package com.wangkai.servlet;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wangkai.annotation.MyController;
import com.wangkai.annotation.MyRequestMapping;
@SuppressWarnings("serial")
public class MyDispatcherServlet extends HttpServlet {
private Properties properties =new Properties();
private List<String> classNames=new ArrayList<String>();
private Map<String, Object>ioc=new HashMap<String, Object>();
private Map<String,Method> handlerMapping = new HashMap<String, Method>();
private Map<String ,Object>controllerMap=new HashMap<String, Object>();
public void init(ServletConfig config) {
//加载配置文件
doLoadConfig(config.getInitParameter("contextConfigLocation"));
//初始化所有相关联的类 扫面用户设定的包下边所有的类
doScanner(properties.getProperty("scanPackage"));
//拿到扫描到的类 通过反射机制 实例化并且放到IOC容器中
doInstance();
//初始化handlermapping
initHandlerMapping();
}
private void doInstance() {
if(classNames.isEmpty()) {
return;
}
for (String className : classNames) {
try {
//将类搞出来,反射来实例化
Class<?>clazz=Class.forName(className);
if(clazz.isAnnotationPresent(MyController.class)) {
ioc.put(toLowerFirstWord(clazz.getSimpleName()), clazz.newInstance());
}else {
continue;
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
private void initHandlerMapping() {
if(ioc.isEmpty()) {
return;
}
try {
for (Entry<String,Object> entry : ioc.entrySet()) {
Class<? extends Object> clazz=entry.getValue().getClass();
if(!clazz.isAnnotationPresent(MyController.class)) {
continue;
}
//拼接url时 是controller头的URL拼上方法的URL
String baseUrl="";
if(clazz.isAnnotationPresent(MyRequestMapping.class)) {
MyRequestMapping annotation=clazz.getAnnotation(MyRequestMapping.class);
baseUrl=annotation.value();
}
Method[] methods=clazz.getMethods();
for (Method method : methods) {
if(!method.isAnnotationPresent(MyRequestMapping.class)) {
continue;
}
MyRequestMapping annotation=method.getAnnotation(MyRequestMapping.class);
String url=annotation.value();
url=(baseUrl+"/"+url).replaceAll("/+", "/");
handlerMapping.put(url, method);
controllerMap.put(url, clazz.newInstance());
System.out.println(url+","+method);
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
private String toLowerFirstWord(String name) {
char[] charArray=name.toCharArray();;
charArray[0]+=32;
return String.copyValueOf(charArray);
}
private void doLoadConfig(String location) {
//吧web.xml中的contextconfiglocation对应的value值得文件加载到流里面
InputStream resourceAsStream=this.getClass().getClassLoader().getResourceAsStream(location);
try {
//用properties文件架子啊文件里的内容
properties.load(resourceAsStream);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(null!=resourceAsStream) {
try {
resourceAsStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void doScanner(String packageName) {
URL url=this.getClass().getClassLoader().getResource("/"+packageName.replaceAll("\\.", "/"));
File dir=new File(url.getFile()) ;
for (File file : dir.listFiles()) {
if(file.isDirectory()) {
doScanner(packageName+"."+file.getName());
}else {
String className=packageName+"."+file.getName().replace(".class", "");
classNames.add(className);
}
}
}
protected void doGet(HttpServletRequest req,HttpServletResponse res) {
try {
this.doPost(req,res);
} catch (Exception e) {
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse res) {
try {
doDispatch(req, res);
} catch (Exception e) {
}
}
private void doDispatch(HttpServletRequest req,HttpServletResponse res) throws IOException {
if(handlerMapping.isEmpty()) {
return;
}
String url=req.getRequestURI();
String contextPath=req.getContextPath();
url=url.replace(contextPath, "").replaceAll("/+", "/");
if(!this.handlerMapping.containsKey(url)) {
res.getWriter().write("404");
return;
}
Method method =this.handlerMapping.get(url);
//获取方法的参数列表
Class<?>[]paramterTypes = method.getParameterTypes();
//获取请求的参数
Map<String, String[]>paramterMap=req.getParameterMap();
//保存请求的参数
Object[] paramObjects = new Object[paramterTypes.length];
//方法的参数列表
for (int i = 0; i < paramObjects.length; i++) {
//根据参数名称 做某些处理
String requestParam=paramterTypes[i].getSimpleName();
if(requestParam.equals("HttpServletRequest")) {
paramObjects[i]=req;
continue;
}
if (requestParam.equals("HttpServletResponse")){
paramObjects[i]=res;
continue;
}
if(requestParam.equals("String")){
for (Entry<String, String[]> param : paramterMap.entrySet()) {
String value =Arrays.toString(param.getValue()).replaceAll("\\[|\\]", "").replaceAll(",\\s", ",");
paramObjects[i]=value;
}
}
}
try {
method.invoke(this.controllerMap.get(url), paramObjects);
} catch (Exception e) {
// TODO: handle exception
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化