how tomcat works-02

怼烎@ 2021-09-28 21:02 397阅读 0赞

Request

Response

RequestFacade

ResponseFacade

StaticSourceProcessor

ServletProcessor

HttpServer

Constants


Request.java

  1. package qhf02.pyrmont;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.UnsupportedEncodingException;
  6. import java.util.Enumeration;
  7. import java.util.Locale;
  8. import java.util.Map;
  9. import javax.servlet.AsyncContext;
  10. import javax.servlet.DispatcherType;
  11. import javax.servlet.RequestDispatcher;
  12. import javax.servlet.ServletContext;
  13. import javax.servlet.ServletInputStream;
  14. import javax.servlet.ServletRequest;
  15. import javax.servlet.ServletResponse;
  16. public class Request implements ServletRequest {
  17. private InputStream input;
  18. private String uri;
  19. public Request() {
  20. super();
  21. }
  22. public Request(InputStream input) {
  23. this.input = input;
  24. }
  25. public String getUri() {
  26. return uri;
  27. }
  28. public void parse() {
  29. StringBuffer request = new StringBuffer(2048);
  30. int len;
  31. byte[] buffer = new byte[2048];
  32. try {
  33. len = input.read(buffer);
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. len = -1;
  37. }
  38. for (int j = 0; j < len; j++) {
  39. request.append((char) buffer[j]);
  40. }
  41. System.out.println(request.toString());
  42. uri = parseUri(request.toString());
  43. }
  44. /**
  45. * 第一行的第一个空格和第二个空格之间就是uri
  46. * 比如:GET /index.html HTTP/1.1
  47. **/
  48. private String parseUri(String requestString) {
  49. int index1, index2;
  50. index1 = requestString.indexOf(' ');
  51. if(index1 != -1) {
  52. index2 = requestString.indexOf(' ', index1 + 1);
  53. if(index2 > index1) {
  54. return requestString.substring(index1 + 1, index2);
  55. }
  56. }
  57. return null;
  58. }
  59. @Override
  60. public AsyncContext getAsyncContext() {
  61. // TODO Auto-generated method stub
  62. return null;
  63. }
  64. @Override
  65. //....实现父类接口的方法
  66. }

Response.java

  1. package qhf02.pyrmont;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.OutputStream;
  6. import java.io.PrintWriter;
  7. import java.util.Locale;
  8. import javax.servlet.ServletOutputStream;
  9. import javax.servlet.ServletResponse;
  10. public class Response implements ServletResponse {
  11. private static final int BUFFER_SIZE = 1024;
  12. Request request;
  13. OutputStream output;
  14. PrintWriter writer;
  15. public Response() {
  16. super();
  17. }
  18. public Response(OutputStream output) {
  19. this.output = output;
  20. }
  21. public void setRequest(Request request) {
  22. this.request = request;
  23. }
  24. public void sendStaticResource() throws IOException {
  25. byte[] bytes = new byte[BUFFER_SIZE];
  26. FileInputStream fis = null;
  27. try {
  28. File file = new File(HttpServer1.WEB_ROOT, request.getUri());
  29. if (file.exists()) {
  30. fis = new FileInputStream(file);
  31. int ch = fis.read(bytes, 0, BUFFER_SIZE);
  32. while (ch != -1) {
  33. output.write(bytes, 0, ch);
  34. ch = fis.read(bytes, 0, BUFFER_SIZE);
  35. }
  36. } else {
  37. // file not found
  38. String errorMessage = "HTTP/1.1 404 File Not Found\r\n"
  39. + "Content-Type: text/html\r\n"
  40. + "Content-Length: 23\r\n"
  41. + "\r\n"
  42. + "<h1>File Not Found</h1>";
  43. output.write(errorMessage.getBytes());
  44. }
  45. } catch (Exception e) {
  46. System.out.println(e.toString());
  47. } finally {
  48. if (fis != null) {
  49. fis.close();
  50. }
  51. }
  52. }
  53. public static void main(String[] args) {
  54. System.out.println(System.getProperty("user.dir") + File.separator + "webroot");
  55. }
  56. @Override
  57. public PrintWriter getWriter() throws IOException {
  58. writer = new PrintWriter(output, true);//println时自动刷新
  59. return writer;
  60. }
  61. //...实现父类接口的方法
  62. }

RequestFacade

  1. package qhf02.pyrmont;
  2. import java.io.IOException;
  3. import java.io.BufferedReader;
  4. import java.io.UnsupportedEncodingException;
  5. import java.util.Enumeration;
  6. import java.util.Locale;
  7. import java.util.Map;
  8. import javax.servlet.AsyncContext;
  9. import javax.servlet.DispatcherType;
  10. import javax.servlet.RequestDispatcher;
  11. import javax.servlet.ServletContext;
  12. import javax.servlet.ServletInputStream;
  13. import javax.servlet.ServletRequest;
  14. import javax.servlet.ServletResponse;
  15. public class RequestFacade implements ServletRequest {
  16. private ServletRequest request = null;
  17. public RequestFacade(Request request) {
  18. this.request = request;
  19. }
  20. /* implementation of the ServletRequest*/
  21. //实现父类接口的方法,return则调用关于request的方法
  22. }

ResponseFacade

  1. package qhf02.pyrmont;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.util.Locale;
  5. import javax.servlet.ServletResponse;
  6. import javax.servlet.ServletOutputStream;
  7. public class ResponseFacade implements ServletResponse {
  8. private ServletResponse response;
  9. public ResponseFacade(Response response) {
  10. this.response = response;
  11. }
  12. //实现父类接口的方法,return关于response的相关方法
  13. }

StaticSourceProcessor

  1. package qhf02.pyrmont;
  2. import java.io.IOException;
  3. public class StaticResourceProcessor {
  4. public void process(Request request, Response response) {
  5. try {
  6. response.sendStaticResource();
  7. } catch (IOException e) {
  8. e.printStackTrace();
  9. }
  10. }
  11. }

ServletProcessor2

  1. package qhf02.pyrmont;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.net.URL;
  5. import java.net.URLClassLoader;
  6. import java.net.URLStreamHandler;
  7. import javax.servlet.Servlet;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10. public class ServletProcessor2 {
  11. public void process(Request request, Response response) {
  12. String uri = request.getUri();
  13. String servletName = uri.substring(uri.lastIndexOf("/") + 1);
  14. URLClassLoader loader = null;
  15. try {
  16. URL[] urls = new URL[1];
  17. File classPath = new File(Constants.WEB_ROOT);
  18. String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString();
  19. URLStreamHandler streamHandler = null;
  20. urls[0] = new URL(null, repository, streamHandler);
  21. loader = new URLClassLoader(urls);
  22. } catch (IOException e) {
  23. System.out.println(e.toString());
  24. }
  25. Class<?> myClass = null;
  26. try {
  27. myClass = loader.loadClass(servletName);
  28. } catch (Exception e) {
  29. System.out.println(e.toString());
  30. }
  31. Servlet servlet = null;
  32. RequestFacade requestFacade = new RequestFacade(request);
  33. ResponseFacade responseFacade = new ResponseFacade(response);
  34. try {
  35. servlet = (Servlet) myClass.newInstance();
  36. servlet.service((ServletRequest)requestFacade, (ServletResponse)responseFacade);
  37. } catch (Exception e) {
  38. System.out.println(e.toString());
  39. } catch (Throwable e) {
  40. System.out.println(e.toString());
  41. }
  42. }
  43. }

HttpServer2

  1. public class HttpServer2 {
  2. public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";
  3. private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
  4. private boolean shutdown = false;
  5. public static void main(String[] args) {
  6. HttpServer2 server = new HttpServer2();
  7. server.await();
  8. }
  9. private void await() {
  10. ServerSocket serverSocket = null;
  11. int port = 8080;
  12. try {
  13. serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. System.exit(1);
  17. }
  18. while (!shutdown) {
  19. Socket socket = null;
  20. InputStream input = null;
  21. OutputStream output = null;
  22. try {
  23. //1.服务器开机,等待连接,直到连接了执行这下面23后关socket,下次循环再连接
  24. socket = serverSocket.accept();
  25. input = socket.getInputStream();
  26. output = socket.getOutputStream();
  27. //2.解析请求
  28. Request request = new Request(input);
  29. request.parse();
  30. //3.回应设置对应的请求,发送静态源
  31. Response response = new Response(output);
  32. response.setRequest(request);
  33. if(request.getUri().startsWith("/servlet/")) {
  34. ServletProcessor2 processor = new ServletProcessor2();
  35. processor.process(request, response);
  36. } else {
  37. StaticResourceProcessor processor = new StaticResourceProcessor();
  38. processor.process(request, response);//其实是简单封装了response.sendStaticResource();
  39. }
  40. //4.关socket
  41. socket.close();
  42. //5.检查请求中的uri 中是否是shutdown 命令,如是则shutdown 为true 会退出循环
  43. shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. continue;//错误继续循环
  47. }
  48. }
  49. }
  50. }

Constants

  1. public class Constants {
  2. public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";
  3. public static void main(String[] args) {
  4. System.out.println(WEB_ROOT);
  5. }
  6. }

发表评论

表情:
评论列表 (有 0 条评论,397人围观)

还没有评论,来说两句吧...

相关阅读