手写tomcat+servlet
< 返回列表时间: 2018-11-30来源:OSCHINA
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
写程序一定要有思路,思路很重要!
一、我们分两步第一步先实现手写tomcat,第二部写servlet
所用技术:
1、soket通信 IO流
2、http请求与相应
3、解析xml
4、java反射技术
导入所需要的jar: <dependencies> <!-- https://mvnrepository.com/artifact/dom4j/dom4j --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> </dependencies>
项目目录结构:

现在开始我们的第一步,手写tomcat
新建 Request 类: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class Request { private String method; private String url; public Request(InputStream inputStream) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String[] methodAndUrl = bufferedReader.readLine().split(" "); this.method= methodAndUrl[0]; this.url=methodAndUrl[1]; System.out.println(method); System.out.println(url); } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
Response 类: import java.io.IOException; import java.io.OutputStream; public class Response { public OutputStream outputStream; public String wirte; public static final String responseHeader="HTTP/1.1 200 \r\n" + "Content-Type: text/html\r\n" + "\r\n"; public Response(OutputStream outputStream) throws IOException { this.outputStream= outputStream; } public String getWirte() { return wirte; } public void setWirte(String wirte) { this.wirte = wirte; } }
SocketProcess 类: import java.io.OutputStream; import java.net.Socket; import java.util.Map; public class SocketProcess extends Thread{ protected Socket socket; public SocketProcess(Socket socket){ this.socket = socket; } @Override public void run() { try { Request request = new Request(socket.getInputStream()); Response response = new Response(socket.getOutputStream()); // Map<String, Object> map = Mytomcat.servletMapping; // // System.out.println("map大小为:"+map.size()); // for (Map.Entry<String, Object> entry : map.entrySet()) { // System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); // } //从映射中找 System.out.println(request.getUrl()); String servelName = (String) Mytomcat.servletMapping.get(request.getUrl()); System.out.println(servelName); if(servelName!=null && !servelName.isEmpty()) { //映射有的话找到对应的对象 Servelt servlet = (Servelt) Mytomcat.servlet.get(servelName); if(servlet!=null) { servlet.doGet(request, response); }else { System.out.println("找不到对应的servlet"); } }else { System.out.println("找不到对应的servletMapping"); } String res = Response.responseHeader+response.getWirte(); OutputStream outputStream = socket.getOutputStream(); outputStream.write(res.getBytes("GBK")); outputStream.flush(); outputStream.close(); }catch (Exception ex){ ex.printStackTrace(); }finally { if (socket != null) { try { socket.close(); } catch (Exception e) { e.printStackTrace(); } } } } }
Mytomcat import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.List; import org.dom4j.Element; public class Mytomcat { private static final int port = 8099; public static final HashMap<String, Object> servletMapping = new HashMap<String, Object>(); public static final HashMap<String, Object> servlet = new HashMap<String, Object>(); private void init() { InputStream io = null; String basePath; try { System.out.println("加载配置文件开始"); //读取web.xml UtilsXml xml = new UtilsXml(UtilsXml.class.getResource("/")+"web.xml"); //讲所有的类都存储到容器中 并且创造对象 List<Element> list = xml.getNodes("servlet"); for (Element element : list) { servlet.put(element.element("servlet-name").getText(), Class.forName(element.element("servlet-class").getText()).newInstance()); } //映射关系创建 List<Element> list2 = xml.getNodes("servlet-mapping"); for (Element element : list2) { servletMapping.put(element.element("url-pattern").getText(), element.element("servlet-name").getText()); } System.out.println("加载配置文件结束"); } catch (Exception ex) { ex.printStackTrace(); } finally { if (io != null) { try { io.close(); } catch (Exception e) { e.printStackTrace(); } } } } private void start() { try { ServerSocket serverSocket = new ServerSocket(port); System.out.println("Tomcat 服务已启动,地址:localhost ,端口:" + port); this.init(); //持续监听 do { Socket socket = serverSocket.accept(); System.out.println(socket); //处理任务 Thread thread = new SocketProcess(socket); thread.start(); } while (true); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { Mytomcat tomcat = new Mytomcat(); tomcat.start(); } }
UtilsXml: import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class UtilsXml { //定义解析器和文档对象 public SAXReader saxReader; public Document document; public UtilsXml(String path){ //获取解析器 saxReader = new SAXReader(); try { //获取文档对象 document = saxReader.read(path); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 根据节点名称获取内容 * @param name 节点名称 * @return 节点内容 */ public String getElementText(String name){ //定位根节点 Element root = document.getRootElement(); List<Element> mapp = root.elements("servlet-mapping"); List<Element> servlet = root.elements("servlet"); String serveltName = ""; String classpath = ""; for (Element e : mapp) { // System.out.println(e.element("url-pattern").getText()); if(e.element("url-pattern").getText().equals(name)){ serveltName = e.element("servlet-name").getText(); break; } } for (Element e : servlet) { // System.out.println(e.element("servlet-name").getText()); if(e.element("servlet-name").getText().equals(serveltName)){ classpath = e.element("servlet-class").getText(); break; } } return classpath; // //根据名称定位节点 // Element element = root.element(name); // //返回节点内容 // return element.getText(); } /** * 获取节点下的所有节点 * @param root * @param name * @return */ public List<Element> getNodes(String name){ Element root = document.getRootElement(); return root.elements(name); } public static void main(String[] args) { UtilsXml xml = new UtilsXml(UtilsXml.class.getResource("/")+"web.xml"); //System.out.println(xml.getElementText("/myhtml.html")); List<Element> list = xml.getNodes("servlet"); for (Element element : list) { System.out.println(element.element("servlet-name").getText() ); System.out.println(element.element("servlet-class").getText() ); } }
Servelt 抽象类: import com.siyuan.http.Request; import com.siyuan.http.Response; public abstract class Servelt { public void service(Request request, Response response) { //判断是调用doget 还是 dopost if ("get".equalsIgnoreCase(request.getMethod())) { this.doGet(request, response); } else { this.doPost(request, response); } } public abstract void doGet(Request request, Response response); public abstract void doPost(Request request, Response response); }
第一个servlet : import com.siyuan.http.Request; import com.siyuan.http.Response; public class MyfisrtServlet extends Servelt { @Override public void doGet(Request request, Response response) { System.out.println("进入了我的第一个servlet"); response.setWirte("进入了第一个servlet"); } @Override public void doPost(Request request, Response response) { } }
第二个servlet: import com.siyuan.http.Request; import com.siyuan.http.Response; public class ScoendServlet extends Servelt{ @Override public void doGet(Request request, Response response) { System.out.println("进入了我的第二个servlet"); response.setWirte("进入了第二个servlet"); } @Override public void doPost(Request request, Response response) { // TODO Auto-generated method stub } }
新建web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>myhtml.html</servlet-name> <servlet-class>com.siyuan.servlet.MyfisrtServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myhtml.html</servlet-name> <url-pattern>/myhtml.html</url-pattern> </servlet-mapping> <servlet> <servlet-name>myhtml2.html</servlet-name> <servlet-class>com.siyuan.servlet.ScoendServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myhtml2.html</servlet-name> <url-pattern>/myhtml2.html</url-pattern> </servlet-mapping> </web-app>
运行效果:






有问题讨论可以加群一起讨论:
600922504
热门排行