- 在minicat的resources目录下,增加server.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?> <Server> <!--可以有多个service--> <Service> <Connector port="8080"/> <Engine> <Host name="localhost" appBase="D:\lianxi\stage2\module1\miniCat\webapps"></Host> </Engine> </Service> </Server>
- 加载解析server.xml,获取到appBase的路径,初始化webapps,webapps中有多个demo(应用项目)
/** * 4.0 版本: 加载 server.xml,解析并初始化 webapps 下面的各个项目的 servlet */ private void loadServlet() throws DocumentException, ClassNotFoundException, FileNotFoundException { InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("server.xml"); // 使用dom4j SAXReader saxReader = new SAXReader(); Document document = saxReader.read(resourceAsStream); Element rootElement = document.getRootElement(); // <Server> 一个server下可以有多个service List<Element> servicetNodes = rootElement.selectNodes("//Service"); for (Element service : servicetNodes) { // 遍历所有service 找每一个service下的Connector <Connector port="8080"/> Element connectorElement = (Element) service.selectSingleNode("Connector"); // <Connector port="8080"/> prot = Integer.parseInt(connectorElement.attributeValue("port")); //获取到port的值 // 获取 Host List<Element> hostList = rootElement.selectNodes("//Host"); for (Element host : hostList) { // 获取host标签中那么的属性值 name="localhost" String hostName = host.attributeValue("name"); // appBase="D:\lianxi\stage2\module1\miniCat\webapps" String appBase = host.attributeValue("appBase"); // System.out.println("=======appBase转换前的格式:======="+appBase); String webapps = appBase.replaceAll("\\\\", "/"); // System.out.println("=======appBase转换后的格式:======="+webapps); // 获取该路径的文件夹 webapps File file = new File(appBase); if (file.exists() && file.isDirectory()){ // 如果该file存在而且是个文件夹 webapps,下面有多个项目应用 // 遍历该文件夹 File[] files = file.listFiles(); for (File file1 : files) { // 得到每一个demo // 获取每一个demo的路径 String path = file1.getPath(); System.out.println("获取每一个demo的路径=====>"+path); // 单个项目文件名 // String fileName = path.replace(file.getPath()+"\\",""); // System.out.println("单个项目文件名=====>"+fileName); //读取web.xml文件 String webpath = path+"\\web.xml"; System.out.println("webpath:"+webpath); loadServletwebxml(webpath,appBase); } } } } }
- 读取每一个demo下的web.xml,并解析
private void loadServletwebxml(String webPath,String clazz) throws DocumentException, ClassNotFoundException, FileNotFoundException { System.out.println("loadServletwebxml方法中的路径==="+webPath); System.out.println("clazz***"+clazz); FileInputStream resourceAsStream = new FileInputStream(webPath); // InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(webPath); // 用这个类加载器加载不了,需要自定义类加载器 MyClassLoader myClassLoader = new MyClassLoader(); // 使用dom4j SAXReader saxReader = new SAXReader(); Document document = saxReader.read(resourceAsStream); Element rootElement = document.getRootElement(); List<Element> selectNodes = rootElement.selectNodes("//servlet"); for (Element element : selectNodes) { Element servletnameElement = (Element) element.selectSingleNode("servlet-name"); // <servlet-name>myservlet</servlet-name> String servletName = servletnameElement.getStringValue(); // myservlet Element servletclassElement = (Element) element.selectSingleNode("servlet-class"); // <servlet-class>server.MyServlet</servlet-class> String servletClass = servletclassElement.getStringValue(); // server.MyServlet System.out.println("servletClass----"+servletClass); myClassLoader.findClass(clazz,servletClass); // 根据servlet-name的值,定位 url-pattern 的值 Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']"); String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue(); // <url-pattern>/</url-pattern> 就是 :/ try { // 存储解析的web.xml中 <servlet>和<servlet-mapping>的映射关系 // Map<String,HttpServlet> servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
- minicat需要自定义一个类加载器来加载部署在webapps中的class文件
package server; import java.io.*; public class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String basePath, String className) { byte[] classBytes = getClassBytes(basePath, className); return defineClass(className, classBytes, 0, classBytes.length); } /** * 读取类的字节码 * * @param basePath 根路径 * @param className 类的全限定名 * @return servlet 的字节码信息 * @throws IOException */ private byte[] getClassBytes(String basePath, String className) { InputStream in = null; ByteArrayOutputStream out = null; String path = basePath + File.separatorChar + className.replace('.', File.separatorChar) + ".class"; try { in = new FileInputStream(path); out = new ByteArrayOutputStream(); byte[] buffer = new byte[2048]; int len = 0; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } return out.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } }
开发Minicat V4.0,在已有Minicat基础上进一步扩展,模拟出webapps部署效果 磁盘上放置一个webapps目录,webapps中可以有多个项目,例如demo1、demo2、demo
最新推荐文章于 2024-05-31 10:46:10 发布