网站速度慢wordpress,建站套餐推荐,四川网站推广,微信小程序公众平台官网首先#xff0c;Tomcat是一个软件#xff0c;所有的项目都能在Tomcat上加载运行#xff0c;Tomcat最核心的就是Servlet集合#xff0c;本身就是HashMap。Tomcat需要支持Servlet#xff0c;所以有servlet底层的资源#xff1a;HttpServlet抽象类、HttpRequest和HttpRespon… 首先Tomcat是一个软件所有的项目都能在Tomcat上加载运行Tomcat最核心的就是Servlet集合本身就是HashMap。Tomcat需要支持Servlet所以有servlet底层的资源HttpServlet抽象类、HttpRequest和HttpResponse否则我们无法新建Servlet。 这样我们就可以在webapps写项目了一个项目有两大资源servlet资源和静态资源servlet本身是java类我们让它调用doGet和doPost方法必须继承HttpServlet同时也需要WebServlet注解那么在Tomcat中就必须要有WebServlet注解的实现如果没有WebServlet我们就无法拿到相应的注解。这样我们就能成功搭建起Servlet资源。 如果servlet集合在Tomcat启动之前实现也就是main()方法之前需要使用static代码块去实现如果servlet集合在Tomcat启动之后实现也就是main()方法之后再去加载servlet容器。 当Http请求打过来之后先打到socket上处理Http请求其本身就是连接器从请求上能获取到请求路径和请求方法。先获取到请求路径判断servlet容器中是否含有相同路径如果有再获取请求方法判断是doGet还是doPost。 一、Servlet资源准备
1、Servlet接口
Servlet接口的作用实现Servlet生命周期定义init()、service(requestresponse)和destroy()方法。接口中的方法全都是抽象方法只定义不实现方法头默认为public abstract。
import com.qcby.Servlet.req.HttpServletRequest;
import com.qcby.Servlet.req.HttpServletResponse;public interface Servlet {void init();void service(HttpServletRequest request, HttpServletResponse response) throws Exception;void destroy();
}
2、GenericServlet抽象类 GenericServlet抽象类实现Servlet接口中的init()方法和destroy()方法。
为什么GenericServlet类是抽象类 我们知道当一个普通类继承一个接口时需要对接口中的所有方法进行实现但这里我们不实现Servlet接口中的service(requestresponse)方法因此我们需要把GenericServlet类变成抽象类因为抽象类不必实现接口中的全部方法。
public abstract class GenericServlet implements Servlet {public void init(){System.out.println(初始化成功);}public void destroy(){System.out.println(销毁成功);}
}
3、HttpServlet抽象类
HttpServlet抽象类实现Servlet接口中的service(requestresponse)方法
为什么HttpServlet类也是抽象类 之所以HttpServlet类也是抽象类是因为普通类中必须对方法进行实现而在HttpServlet类中实现servicerequestresponse方法的逻辑为如果接收到GET请求那么执行doGet方法如果接收到POST请求那么执行doPost方法。在此我们只需要对doGet和doPost方法进行定义不需要实现所以HttpServlet只有成为抽象类才不必实现doGet和doPost方法。
import com.qcby.Servlet.req.HttpServletRequest;
import com.qcby.Servlet.req.HttpServletResponse;public abstract class HttpServlet extends GenericServlet {//实现Servlet生命周期的service方法public void service(HttpServletRequest request, HttpServletResponse response) throws Exception {//如果接收到GET请求那么执行doGet方法if(request.getMethod().equals(GET)){doGet(request,response);}//如果接收到POST请求那么执行doPost方法else if(request.getMethod().equals(POST)){doPost(request,response);}}protected abstract void doGet(HttpServletRequest request,HttpServletResponse response) throws Exception;protected abstract void doPost(HttpServletRequest request,HttpServletResponse response)throws Exception;
}
4、HttpRequest类
HttpRequest类实现请求路径和请求方法的获取与输出。
public class HttpServletRequest {private String path;private String method;public String getPath(){return path;};public void setPath(String path){this.path path;}public String getMethod(){return method;}public void setMethod(String method){this.method method;}
}
5、HttpResponse类
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;public class HttpServletResponse {private OutputStream outputStream;public HttpServletResponse(OutputStream outputStream){this.outputStream outputStream;}public void writeServlet(String context) throws IOException{outputStream.write(context.getBytes());}
} 二、注解
Retention()表示该注解的作用阶段。阶段分三种源代码阶段、类对象阶段和运行时阶段。Target()表示该注解的作用范围。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;//作用阶段
Retention(RetentionPolicy.RUNTIME)//作用在运行阶段//作用范围类、方法......
Target(ElementType.TYPE)//作用在类上public interface WebServlet {String urlMapping() default ;//自定义的servlet路径
}
三、工具类
1、SearchClassUtil类 SearchUtil类的功能扫描com.qcby.webapps包下的文件获取全路径名
import java.io.File;
import java.util.ArrayList;
import java.util.List;/*
* 扫描com.qcby.webapps包下的文件获取全路径名
* */
public class SearchClassUtil {public static ListString classPaths new ArrayListString();public static ListString searchClass(){//需要扫描的包名String basePack com.qcby.webapps;//将获取到的包名转换为路径String classPath SearchClassUtil.class.getResource(/).getPath();basePack basePack.replace(., File.separator);String searchPath classPath basePack;doPath(new File(searchPath),classPath);//这个时候我们已经得到了指定包下所有的类的绝对路径了。我们现在利用这些绝对路径和java的反射机制得到他们的类对象return classPaths;}/*** 该方法会得到所有的类将类的绝对路径写入到classPaths中* param file*/private static void doPath(File file,String classpath) {if (file.isDirectory()) {//文件夹//文件夹我们就递归File[] files file.listFiles();for (File f1 : files) {doPath(f1,classpath);}} else {//标准文件//标准文件我们就判断是否是class文件if (file.getName().endsWith(.class)) {String path file.getPath().replace(classpath.replace(/,\\).replaceFirst(\\\\,),).replace(\\,.).replace(.class,);//如果是class文件我们就放入我们的集合中。classPaths.add(path);}}}public static void main(String[] args) {ListString classes SearchClassUtil.searchClass();for (String s: classes) {System.out.println(s);}}
}
2、ResponseUtil类
public class ResponseUtil {public static final String responseHeader200 HTTP/1.1 200 \r\nContent-Type:text/html; charsetutf-8 \r\n\r\n;public static String getResponseHeader404(){return HTTP/1.1 404 \r\nContent-Type:text/html; charsetutf-8 \r\n\r\n 404;}public static String getResponseHeader200(String context){return HTTP/1.1 200 \r\nContent-Type:text/html; charsetutf-8 \r\n\r\n context;}
}四、Servlet类
1、LoginServlet类
import com.qcby.Servlet.HttpServlet;
import com.qcby.Servlet.req.HttpServletRequest;
import com.qcby.Servlet.req.HttpServletResponse;
import com.qcby.Util.ResponseUtil;
import com.qcby.Util.WebServlet;import java.io.IOException;WebServlet(urlMapping /login)
public class LoginServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {System.out.println(我是LoginServlet下的doGet方法);response.writeServlet(ResponseUtil.getResponseHeader200(hello));}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) {System.out.println(我是LoginServlet下的doPost方法);}
}
五、ServletConfigMapping类 ServletConfigMapping类是Servlet容器是Tomcat中最核心的部分其本身是一个HashMap其功能为将路径和对象写入Servlet容器中。
import com.qcby.Servlet.HttpServlet;
import com.qcby.Util.SearchClassUtil;
import com.qcby.Util.WebServlet;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ServletConfigMapping {//创建servlet容器public static MapString, HttpServlet servletMap new HashMap();//将Path和对象写入servlet容器当中//采用static代码块 在启动tomcat之前实现static{ListString classesPath SearchClassUtil.searchClass();for(String path:classesPath){try{//加载类Class clazz Class.forName(path);//获取注解WebServlet webServlet (WebServlet) clazz.getDeclaredAnnotation(WebServlet.class);HttpServlet servlet (HttpServlet) clazz.newInstance();servletMap.put(webServlet.urlMapping(),servlet);} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {e.printStackTrace();}}}
}
六、MyTomcat
import com.qcby.Servlet.HttpServlet;
import com.qcby.Servlet.req.HttpServletRequest;
import com.qcby.Servlet.req.HttpServletResponse;import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class MyTomcat {static HttpServletRequest request new HttpServletRequest();public static void main(String[] args) throws Exception {//ServletConfigMapping.init(); // tomcat启动但是还没有监听之前,将信息加载入servlet容器当中//1.创建serversocket对象持续监听8080端口ServerSocket serverSocket new ServerSocket(8888);while (true){//accept():阻塞监听 当代码执行到这一样如果没有数据到来那么循环阻塞在这里。如果有数据到来就继续向下执行Socket socket serverSocket.accept();InputStream inputStream socket.getInputStream();OutputStream outputStream socket.getOutputStream();HttpServletResponse response new HttpServletResponse(outputStream);int count 0;while (count 0){count inputStream.available();}byte[] bytes new byte[count];inputStream.read(bytes);String Context new String(bytes);System.out.println(Context);//解析数据if(Context.equals()){System.out.println(你输入了一个空请求);}else {String firstLine Context.split(\\n)[0];request.setMethod(firstLine.split(\\s)[0]);request.setPath(firstLine.split(\\s)[1]);}//如果我们访问的路径在servlet容器当中存在if(ServletConfigMapping.servletMap.containsKey(request.getPath())){HttpServlet servlet ServletConfigMapping.servletMap.get(request.getPath());servlet.service(request,response);}}}
}