美文网首页
《深入剖析tomcat》[2] servlet容器

《深入剖析tomcat》[2] servlet容器

作者: 老林_ | 来源:发表于2021-05-31 16:24 被阅读0次

用到了几个类
Contants 常量类
HttpServlet1 启动类(使用ServerSocket监听端口,并进行分发处理)
PrimitiveServlet (被处理的javax.servlet.Servlet类)
Request类 (处理客户端传来的请求)
Response类 (处理返回给客户端的请求,这里是返回静态资源)
ServletProcess1 (处理servlet)
StaticResourceProcessor (处理静态资源)

Constants.java 静态类,存放静态变量,这里不放代码了
HttpServer1.java

public class HttpServer1 {
    private static final String SHUTDOWN_COMMAND="/SHUTDOWN";
    private boolean shutdown=false;

    public static void main(String[] args) {
        HttpServer1 server=new HttpServer1();
        server.await();
    }

    private void await() {
        int port=8080;
        try(ServerSocket serverSocket=new ServerSocket(port,
                1, InetAddress.getByName("127.0.0.1"))){
            while (!shutdown){
                Socket socket=serverSocket.accept();
                InputStream input=socket.getInputStream();
                OutputStream output=socket.getOutputStream();
                Request request=new Request(input);
                request.parse();

                Response response=new Response(output);
                response.setRequest(request);
                //response.sendStaticResource();
                //处理uri
                if(request.getUri().startsWith("/servlet/")){
                    ServletProcess1 process=new ServletProcess1();
                    process.process(request,response);
                }else {
                    StaticResourceProcessor processor=
                            new StaticResourceProcessor();
                    processor.process(request,response);
                }
                socket.close();
                shutdown=request.getUri().equals(SHUTDOWN_COMMAND);
            }
        }catch (Exception e){
            e.printStackTrace();
            System.exit(1);
        }
    }
}

PrimitiveServlet


public class PrimitiveServlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("from service");
        PrintWriter printWriter=servletResponse.getWriter();
        //注意,这里要加http头信息,要不chrome会认为请求失败
        String head="HTTP/1.1 200 OK\r\n"+
                "Content-Type: text/html\r\n\r\n";
        printWriter.println(head);
        printWriter.println("Hello. Roses are red.");
        printWriter.println("Violets are blue.");
        printWriter.flush();
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

Request.java


public class Request implements ServletRequest {
    private InputStream input;
    private String uri;

    public Request(InputStream inputStream) {
        this.input=inputStream;
    }

    public void parse() {
        StringBuffer request=new StringBuffer(2048);
        int i;
        byte[] buffer=new byte[2048];
        try{
            //这里返回读取的实际字节的大小
            i=input.read(buffer);
        }catch (IOException e){
            e.printStackTrace();
            i=-1;
        }
        for(int j=0;j<i;j++){
            request.append((char)buffer[j]);
        }
        System.out.println(request.toString());
        uri=parseUri(request.toString());
    }

    /**
     * 获取uri
     * @param requestString
     * @return
     */
    private String parseUri(String requestString){
        int index1,index2;
        index1=requestString.indexOf(' ');
        if(index1 != -1){
            index2=requestString.indexOf(' ',index1+1);
            if(index2 > index1){
                //截取http请求的rui
                return requestString.substring(index1+1,index2);
            }
        }
        return null;
    }

    public String getUri() {
        return uri;
    }
//----省略一些继承方法------
}

RequestFacade .java

/**
 * 可以保护外界调用不到servletRequest
 * 保护request类的公共方法
 */
public class RequestFacade implements ServletRequest {
    private ServletRequest request=null;
    public RequestFacade(ServletRequest request){
        this.request=request;
    }
    @Override
    public Object getAttribute(String s) {
        return request.getAttribute(s);
    }
//-----省略一些继承方法------
}

Response .java


public class Response implements ServletResponse {
    private static final int BUFFER_SIZE=1024;
    Request request;
    OutputStream output;
    PrintWriter writer;

    public Response(OutputStream outputStream) {
        this.output=outputStream;
    }

    public void setRequest(Request request) {
        this.request=request;
    }

    public PrintWriter getWriter(){
        writer=new PrintWriter(output);
        return writer;
    }

    public void sendStaticResource() throws IOException {
        byte[] bytes=new byte[BUFFER_SIZE];
        FileInputStream fis=null;
        try {
            File file=new File(Constants.WEB_ROOT,request.getUri());
            if(file.exists()){
                fis=new FileInputStream(file);
                int ch=fis.read(bytes,0,BUFFER_SIZE);
                //注意 这里一定要添加响应返回头信息,否则chrome不无打开,
                //会出现ERR_INVALID_HTTP_RESPONSE
                String head="HTTP/1.1 200 OK\r\n"+
                        "Content-Type: text/html\r\n\r\n";
                output.write(head.getBytes());
                while (ch!=-1){
                    output.write(bytes,0,ch);
                    //一次性读取部分字节
                    ch=fis.read(bytes,0,BUFFER_SIZE);
                }
                output.flush();
            }else {
                //文件不存在
                String errorMessage="HTTP/1.1 404 FileNot Found\r\n"+
                        "Content-Type: text/html\r\n"+
                        "Content-Length:23\r\n"+
                        "\r\n"+
                        "<h1>File Not Found</h1>";
                output.write(errorMessage.getBytes());
            }
        }catch (Exception e){
            System.out.println(e.toString());
        }finally {
            if(fis!=null){
                fis.close();
            }
        }
    }
//---省略一些继承方法---

ServletProcess1.java servlet处理器


public class ServletProcess1 {
    public void process(Request request, Response response) {
        String uri=request.getUri();
        String servletName=uri.substring(uri.lastIndexOf("/")+1);
        servletName="com.ly3."+servletName;
        URLClassLoader loader=null;
        try {
            URL[] urls=new URL[1];
            URLStreamHandler streamHandler=null;
            File classPath=new File(Constants.WEB_ROOT);
            String repository=
                    (new URL("file",null,classPath.getCanonicalPath()+
                            File.separator)).toString();
            urls[0]=new URL(null,repository,streamHandler);
            loader=new URLClassLoader(urls);
        }catch (IOException e){
            System.out.println(e.toString());
        }

        Class myClass=null;
        try {
            System.out.println(servletName);
            myClass=loader.loadClass(servletName);
            Servlet servlet=(Servlet)myClass.newInstance();
            RequestFacade requestFacade=new RequestFacade(request);
            servlet.service(requestFacade,(ServletResponse)response);


        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

静态资源处理器

public class StaticResourceProcessor {
    public void process(Request request, Response response) {
        try {
            response.sendStaticResource();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

相关文章

  • 《深入剖析tomcat》[2] servlet容器

    用到了几个类Contants 常量类HttpServlet1 启动类(使用ServerSocket监听端口,并进行...

  • 深入理解Tomcat——Servlet容器(Container)

    深入理解Tomcat——Servlet容器 Servlet容器处理客户端的请求并填充response对象。Serv...

  • Tomcat、Servlet、JSP之间是什么关系

    概述 Tomcat: 是Servlet的容器,Servlet运行在Tomcat容器当中,Servlet容器有很多(...

  • Servlet

    一、了解tomcat容器 个人学习笔记,所以很乱~ 先上几篇好文洗脑? 深入理解Tomcat架构Servlet 体...

  • Servlet1.0

    什么是Servlet ​​ Tomcat容器等级 ​​ Servlet生命周期 ​​ Servlet容器装载Ser...

  • servlet生命周期

    Servlet部署在容器中,比如tomcat。它的生命周期由容器来管理。阶段:1.装载Servlet,容器完成。2...

  • 20160926------Servlet

    一、Servlet概述 1、什么是Servlet 2、Tomcat容器等级 3、编写第一个Servlet程序

  • JAVA Servlet工作原理

    servlet容器加载顺序 当 Servlet 容器(比如 Apache Tomcat )启动后,会部署和加载所有...

  • wed前段

    tomcat是Servlet 的容器; Servlet容器接受用户请求通过配置的映射调用Servlet中的java...

  • java wed初始

    tomcat是Servlet 的容器; Servlet容器接受用户请求通过配置的映射调用Servlet中的java...

网友评论

      本文标题:《深入剖析tomcat》[2] servlet容器

      本文链接:https://www.haomeiwen.com/subject/vamssltx.html