• 理解与模拟一个简单servlet容器


    servlet接口

      使用servlet编程需要实现或者继承实现了javax.servlet.Servlet接口的类,其中定义了5个签名方法:

    1 public void init(ServletConfig config) throws ServletException
    2 public void service(ServletRequest req,ServletResponse res) throws ServletException,java.io.IOException
    3 public void destroy()
    4 public ServletConfig getServletConfig()
    5 public java.lang.String getServletInfo()

    init(),service(),destroy对应着servlet的生命周期,init只在加载该servlet时执行且只此一次,容器根据用户请求调用对应servlet的service执行方法,当实例销毁移除前容器调用destroy处理后续操作。

    模拟容器主要工作流程:

    • 等待http请求
    • 根据请求创建对应Request与Response对象
    • 如果请求的是静态资源,则调用StaticResourceProcessor发送对应资源
    • 如果请求是servlet,则加载该类并执行其service方法
    简单servlet容器

     主要类信息如下:

    1. HttpServer  与web服务器类似,不同的是加入了servlet请求判断,并调用ServletProcessor处理对应servlet
    2. Request   与上一篇web服务器类似,但是实现了ServletRequest接口
    3. Response   与上一篇web服务器类似,但是实现了ServletResponse接口
    4. StaticResourceProcessor  用于处理请求静态资源时调用
    5. ServletProcessor 用于当请求是servlet时调用
    6. Constant 定义一些常量
    7. MyLogger 自己定义在控制台打印日志信息,可以忽略
    8. PrimitiveServlet 实现servlet接口,自定义servlet程序用于请求调用

    说明:部分接口只是实现了需要用到的方法,并没有完全实现所有方法,使用默认即可,代码里面没有贴出来

    (一)HttpServer 
     1 public class HttpServer {
     2     MyLogger logger = new MyLogger<>(HttpServer.class);
     3     private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
     4     private boolean  shutdown = false;
     5     
     6     public void await() {
     7         ServerSocket serverSocket = null;
     8         int port = 8080;
     9         try {
    10             serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
    11             logger.log("server started......." + "at " + serverSocket.toString());
    12         } catch (IOException e) {
    13             // TODO Auto-generated catch block
    14             e.printStackTrace();
    15             System.exit(1);
    16         }
    17         while (!shutdown){
    18             Socket socket = null;
    19             InputStream inputStream = null;
    20             OutputStream outputStream = null;
    21             try {
    22                 socket = serverSocket.accept();
    23                 logger.log("accepted new request...");
    24                 inputStream = socket.getInputStream();
    25                 outputStream = socket.getOutputStream();
    26                 Request request = new Request(inputStream);
    27                 request.Parse();
    28                 Response response = new Response(outputStream);
    29                 response.setRequest(request);
    30                 logger.log("inition done,begin process.......");
    31                 if(request.getUri() == null){
    32                     logger.log("request uri is null...close socket");
    33                     socket.close();
    34                     continue;
    35                 }
    36                 else if(request.getUri().startsWith("/servlet/")){
    37                     logger.log("execute servlet...");
    38                     ServletProcessor servletProcessor = new ServletProcessor();
    39                     servletProcessor.process(request, response);
    40                 }
    41                 else {
    42                     logger.log("send staticResource...");
    43                     StaticResourceProcessor staticResourceProcessor = new StaticResourceProcessor();
    44                     staticResourceProcessor.process(request, response);
    45                 }
    46                 socket.close();
    47                 shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
    48             } catch (IOException e) {
    49                 // TODO Auto-generated catch block
    50                 e.printStackTrace();
    51             }
    52         }
    53     }
    54 }
    (二)Request 
     1 public class Request implements ServletRequest{
     2     
     3     MyLogger logger = new MyLogger(ServletRequest.class);
     4     private String uri;
     5     private InputStream in;
     6     
     7     public Request(InputStream in){
     8         this.in = in;
     9     }
    10     
    11     public String parseUri(String request){
    12         int index1,index2;
    13         index1 = request.indexOf(" ");
    14         if (index1 != -1){
    15             index2 = request.indexOf(" ", index1+ 1);
    16             if (index1 < index2)
    17                 return request.substring(index1 + 1, index2);
    18         }
    19         return null;
    20     }
    21     
    22     public void Parse(){
    23         StringBuffer request = new StringBuffer(2048);
    24         byte[] bs = new byte[2048];
    25         int i;
    26         try {
    27             i = in.read(bs);
    28         } catch (IOException e) {
    29             e.printStackTrace();
    30             i = -1;
    31         }
    32         
    33         for(int j=0; j<i; j++){
    34             request.append((char)bs[j]);
    35         }
    36         
    37         logger.log(request.toString());
    38         uri = parseUri(request.toString());
    39         if(uri != null)
    40         logger.log("uri is " + uri);
    41     }
    42     
    43     public String getUri() {
    44         return uri;
    45     }
    46 }
    (三)Response 
     1 public class Response implements ServletResponse{
     2     
     3     MyLogger logger = new MyLogger(Response.class);
     4     private static final int BUFFER_SIZE = 1024;
     5     private Request request;
     6     private OutputStream out;
     7     private PrintWriter writer;
     8     
     9     public  Response(OutputStream out) {
    10         this.out = out;
    11     }
    12     
    13     public  void setRequest(Request request) {
    14         this.request = request;
    15     }
    16     //假设请求的是图片资源
    17     public void sendStaticResource() throws IOException{
    18         byte[] buffer = new byte[BUFFER_SIZE];
    19         FileInputStream fis = null;
    20         File file = new File(Constant.WEB_ROOT, request.getUri());
    21         try {
    22             logger.log("Begin read file + " + file.toString());
    23             fis = new FileInputStream(file);
    24             String headerMsg = "HTTP/1.1 200 OK
    " + 
    25                     "Content-Type: image/jpg
    " + 
    26                     "Content-Length: " + file.length() + "
    " +
    27                     "
    " ;
    28             logger.log("headerMsg->
    " + headerMsg);
    29             out.write(headerMsg.getBytes());
    30             int ch = fis.read(buffer, 0, BUFFER_SIZE);
    31             while (ch != -1){
    32                 out.write(buffer, 0, BUFFER_SIZE);
    33                 ch = fis.read(buffer, 0, BUFFER_SIZE);
    34             }
    35         } catch (FileNotFoundException e) {
    36             String html = "<h1>file not found</h1>";
    37             logger.log("FileNotFoundException");
    38             String errorMsg = "HTTP/1.1 404 file not found
    " + 
    39                     "Content-Type: text/html
    " + 
    40                     "Content-Length: " + html.getBytes().length + "
    " +
    41                     "
    " +
    42                     html;
    43             out.write(errorMsg.getBytes());
    44             logger.log("errorMsg->" + errorMsg);
    45         }
    46         finally {
    47             if(fis != null){
    48                 fis.close();
    49             }
    50         }
    51     }
    52 }
    (四)StaticResourceProcessor 
    1 public class StaticResourceProcessor {
    2     public void process(Request request,Response response) {
    3         try {
    4             response.sendStaticResource();
    5         } catch (IOException e) {
    6             e.printStackTrace();
    7         }
    8     }
    9 }
    (五)ServletProcessor 
     1 public class ServletProcessor {
     2     public void process(Request request,Response response){
     3         String uri = request.getUri();
     4         String servletName = uri.substring(uri.lastIndexOf("/") + 1);
     5         URLClassLoader loader = null;
     6         
     7         URL[] urls = new URL[1];
     8         URLStreamHandler urlStreamHandler = null;
     9         File classPath = new File(Constant.WEB_ROOT);
    10         try {
    11             String repository = (new URL("file",null,classPath.getCanonicalPath() + 
    12                     File.separator)).toString();
    13             urls[0] = new URL(null,repository,urlStreamHandler);
    14             loader = new URLClassLoader(urls);
    15         } catch (IOException e) {
    16             // TODO Auto-generated catch block
    17             e.printStackTrace();
    18         }
    19         Class myClass = null;
    20         try {
    21             myClass = loader.loadClass(servletName);
    22         } catch (ClassNotFoundException e) {
    23             e.printStackTrace();
    24         }
    25         
    26         Servlet servlet = null;
    27         try {
    28             servlet = (Servlet) myClass.newInstance();
    29             servlet.service((ServletRequest)request, (ServletResponse) response);
    30         
    31         } catch (InstantiationException | IllegalAccessException e) {
    32             // TODO Auto-generated catch block
    33             e.printStackTrace();
    34         } catch (ServletException e) {
    35             // TODO Auto-generated catch block
    36             e.printStackTrace();
    37         } catch (IOException e) {
    38             // TODO Auto-generated catch block
    39             e.printStackTrace();
    40         }
    41         
    42     }
    43 }
    (六)MyLogger 
     1 public  class MyLogger<T> {
     2     private String classStr = "";
     3     
     4     public  void log(T msg){
     5         System.out.println(classStr + "(" + 
     6                 (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + ")" + ": " + msg);
     7     }
     8     public MyLogger(Class classz){
     9         classStr = classz.getName();
    10     }
    11 }
    (七)PrimitiveServlet 
     1 public class PrimitiveServlet implements Servlet{
     2     MyLogger Logger = new MyLogger<>(PrimitiveServlet.class);
     3     @Override
     4     public void destroy() {
     5         // TODO Auto-generated method stub
     6         
     7     }
     8 
     9     @Override
    10     public ServletConfig getServletConfig() {
    11         // TODO Auto-generated method stub
    12         return null;
    13     }
    14 
    15     @Override
    16     public String getServletInfo() {
    17         // TODO Auto-generated method stub
    18         return null;
    19     }
    20 
    21     @Override
    22     public void init(ServletConfig arg0) throws ServletException {
    23         // TODO Auto-generated method stub
    24         
    25     }
    26 
    27     @Override
    28     public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    29         Logger.log("service execute.....");
    30         PrintWriter writer = response.getWriter();
    31         writer.println("Hey,welcome on board!");
    32         writer.println("lets rock!");
    33     }
    34 
    35 }
    (八)Constant 
    public class Constant {
        public static final String WEB_ROOT = 
                System.getProperty("user.dir") + File.separator + "bin";
    }
    View Code
  • 相关阅读:
    Delphi 10.1.2 berlin开发跨平台APP的几点经验
    (矫情)关于编程(能力第一,其它不要多想)
    Xdite:永葆热情的上瘾式学习法(套路王:每天总结自己,反省自己的作息规律,找到自己的幸运时间、幸运方法,倒霉时间、倒霉方法。幸运是与注意力挂钩的。重复才能让自己登峰造极,主动去掉运气部分来训练自己。游戏吸引自己的几个原因非常适合训练自己)good
    无锡美新赵阳:创业18年,一辈子做好一家企业(创业是一种生活方式;为了赚钱而创业,那是扯淡”。最重要的是做自己喜欢做的事情)
    Delphi中流对象的应用
    多样性的配置来源
    WeText项目的服务端
    集线器,交换机,路由器
    不知道的JavaScript
    IPerf网络测试工具
  • 原文地址:https://www.cnblogs.com/music180/p/6089002.html
Copyright © 2020-2023  润新知