这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战
1.web路径分析
https://juejin.cn/pins/recommended
协议://地址/端口/路由地址
我们只关注这里就可以了
前面的容器处理了
2.路由思路
2.1定义注解
2.2系统初始化的时候扫描注解,解解析路由缓存起来
2.3接收请求的时候由自定义过滤器进行拦截
2.4解析请求的路径,并匹配缓存的路由,处理业务
2.5注意对于业务处理的action进行单例实例化
2.6目前这里这里处理方法还只是servlet的request,response只是个例子了解下流程
3.基本实现
3.1注解简单的定义
@Retention(RetentionPolicy.RUNTIME)
public @interface PathAnnotation {
String path();//这里是路径
String type();//这里是类型
}
3.2扫描注解,缓存路径
这里就是遍历读取class文件,找到注解为PathAnnotation的类
解析路径然后缓存起来
//路由对应的实体类
public class Route {
/** 路径*/
private String path;
/** 执行方法*/
private String method;
/** 方法类型*/
private String type;
/** action控制类*/
private Object action;
}
/**
* 扫描的class类,解析路径缓存起来routeList
* @param path
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void addAllRoutes(Set<Class> actionClass) throws InstantiationException, IllegalAccessException {
if (null != actionClass) {
for (Class cls : actionClass) {
PathAnnotation pa = (PathAnnotation) cls.getAnnotation(PathAnnotation.class);
String routPath = "";
if (null != pa) {
routPath = pa.path();
}
Method[] methods = cls.getMethods();
for (Method m : methods) {
pa = m.getAnnotation(PathAnnotation.class);
if (null == pa) {
continue;
}
routPath += "/" + pa.path();
Route rt = new Route(routPath, m.getName(), pa.type(), BeanUtil.getBeanUtil().getObj(cls));
logger.info("加载路由:" + rt.toString());
routeList.add(rt);
}
}
}
}
3.3路径匹配
/**
* 这里是个匹配的路径内容
* 这里的匹配路径所有的都根据/来的
* @param rs
* @param path
* @return
*/
public static Route findRoute(Routes rs,String path) {
if(null==rs||rs.getRouteList().size()<1) {
return null;
}else {
List<Route> allRoute=rs.getRouteList();
//首先要把路径给格式化为标准的路径
if(null==path) {
return null;
}else {
/**
* 1.这里首先要去掉开始的项目地址,然后把字符\转换为/
* 2.如何是/结尾的要去掉
* 3.开始的项目地址如何去掉
* 4.项目路径匹配返回正常的路由
*/
String currentPath=path.trim().replace('\\', '/');
if(currentPath.endsWith("/")) {
currentPath=currentPath.substring(0,currentPath.length()-1);
}
if(currentPath.startsWith("/")) {
currentPath=currentPath.substring(1,currentPath.length());
}
for(Route rt:allRoute) {
if(rt.getPath().equals(currentPath)) {
return rt;
}
}
}
return null;
}
}
4.效果测试
4.1指定过滤器配置
<filter>
<filter-name>pingpang</filter-name>
<filter-class>com.pingpang.core.Core</filter-class>
<init-param>
<param-name>autoPackage</param-name>
<!--这里是扫描的包路径-->
<param-value>com.pingpang.test</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>pingpang</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.2测试action
//路由注解的测试
@PathAnnotation(path = "hello", type = "")
public class PingPangTest {
@PathAnnotation(path = "test", type = "")
public void helloWord(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
System.out.println("-----------");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}