(Web核心)HTTP&Tomcat&Servlet


Javaweb - day8 - HTTP&Tomcat&Servlet

学习计划(Web核心)

* 第一天: HTTP、Tomcat、Servlet
* 第二天: Request(请求)、Response(响应)
* 第三天:JSP、会话技术(Cookie、Session)
* 第四天: Filter(过滤器)、Listener (监听器)
* 第五天: Ajax、Vue、ElementUI
* 第六天:综合案例

HTTP

  • 概念: HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。

HTTP协议特点

  • 基于TCP协议:面向连接,安全
  • 基于请求-响应模型的:一次请求对应一次响应
  • HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。

缺点:多次请求间不能共享数据。
优点:速度快

HTTP-请求数据格式

请求数据分为3部分:

  • 请求行:

请求数据的第一行。其中GET表示请求方式,/
表示请求资源路径,HTTP/1.1表示协议版本

  • 请求头:第二行开始,格式为key: value形式。
  • 请求体:POST请求的最后一部分,存放请求参数。

GET请求和POST请求区别:

  • GET请求请求参数在请求行中,没有请求体。POST请求请求参数在请求体中。
  • GET请求请求参数大小有限制,POST没有。

HTTP-响应数据格式

响应数据分为3部分:

  • 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述。
  • 响应头:第二行开始,格式为key: value形式。
  • 响应体:最后一部分,存放响应数据。

常见的HTTP响应头:

实例

//import sun.misc.IOUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
/*
    自定义服务器
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080); // 监听指定端口
        System.out.println("server is running...");
        while (true){
            Socket sock = ss.accept();
            System.out.println("connected from " + sock.getRemoteSocketAddress());
            Thread t = new Handler(sock);
            t.start();
        }
    }
}

class Handler extends Thread {
    Socket sock;

    public Handler(Socket sock) {
        this.sock = sock;
    }

    public void run() {
        try (InputStream input = this.sock.getInputStream()) {
            try (OutputStream output = this.sock.getOutputStream()) {
                handle(input, output);
            }
        } catch (Exception e) {
            try {
                this.sock.close();
            } catch (IOException ioe) {
            }
            System.out.println("client disconnected.");
        }
    }

    private void handle(InputStream input, OutputStream output) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
        // 读取HTTP请求:
        boolean requestOk = false;
        String first = reader.readLine();
        if (first.startsWith("GET / HTTP/1.")) {
            requestOk = true;
        }
        for (;;) {
            String header = reader.readLine();
            if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
                break;
            }
            System.out.println(header);
        }
        System.out.println(requestOk ? "Response OK" : "Response Error");
        if (!requestOk) {
            // 发送错误响应:
            writer.write("HTTP/1.0 404 Not Found\r\n");
            writer.write("Content-Length: 0\r\n");
            writer.write("\r\n");
            writer.flush();
        } else {
            // 发送成功响应:

            //读取html文件,转换为字符串
            BufferedReader br = new BufferedReader(new FileReader("http/html/a.html"));
            StringBuilder data = new StringBuilder();
            String line = null;
            while ((line = br.readLine()) != null){
                data.append(line);
            }
            br.close();
            int length = data.toString().getBytes(StandardCharsets.UTF_8).length;

            writer.write("HTTP/1.1 200 OK\r\n");
            writer.write("Connection: keep-alive\r\n");
            writer.write("Content-Type: text/html\r\n");
            writer.write("Content-Length: " + length + "\r\n");
            writer.write("\r\n"); // 空行标识Header和Body的分隔
            writer.write(data.toString());
            writer.flush();
        }
    }
}

Web服务器 – Tomcat

简介

  • 概念: 开源免费的轻量级Web服务器,支持Servlet/SP少量JavaEE规范。
  • Tomcat也被称为Web容器、servlet容器。Servlet需要依赖于Tomcat才能运行。

Web服务器作用

  • 封装HTTP协议操作,简化开发。
  • 可以将web项目部署到服务器中,对外提供网上浏览服务。

基本使用 —— 安装、卸载、启动、关闭、配置、部署项目

Tomcat - 基本使用

Tomcat - 部署项目

IDEA中创建Maven Web项目

使用骨架

maven地址要进行选择(阿里云镜像),否则下载很慢!!!

不使用骨架

IDEA中使用Tomcat

集成本地Tomcat

Tomcat Maven插件(但最高只支持到Tomcat7)

实例

<build>
    <plugins>
      <plugin>
        <!--tomcat插件-->
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
      </plugin></plugins>
  </build>

Servlet

  • Servlet是Java提供的一门动态web资源开发技术。
  • Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。

快速入门

实例(配置servlet-maven)

<dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

实例2

package com.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

//ctrl+o 重写父类方法
@WebServlet("/demo1")
public class servlet implements Servlet {
    public servlet() {
        super();
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return super.toString();
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
    }

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

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

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

    @Override
    public void destroy() {

    }
}

Servlet 执行流程

Servlet由谁创建? Servlet方法由谁调用?

  • Servlet由web服务器创建,Servlet方法由web服务器调用。

服务器怎么知道servlet中一定有service方法?

  • 因为我们自定义的Servlet,必须实现servlet接口并复写其方法,而Servlet接口中有service方法。

Servlet生命周期

实例

package com.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

/**
 * Servlet 生命周期方法
 */
@WebServlet(urlPatterns="/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {

    /**
     * 初始化方法
     * 1. 调用时机:默认情况下,Servlet被第一次访问时,调用
     *      * loadOnStartup:
     * 2. 调用次数:1次
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init...");
    }


    /**
     * 提供服务
     * 1. 调用时机:每一次Servlet被访问时,调用
     * 2. 调用次数:多次
     *
     *
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }


    /**
     * 销毁方法
     * 1. 调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
     * 2. 调用次数:1次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }

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

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

Servlet方法介绍

实例

package com.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

/**
 * Servlet 方法介绍
 */
@WebServlet(urlPatterns="/demo3",loadOnStartup = 1)
public class ServletDemo3 implements Servlet {
    private ServletConfig config;
    /**
     * 初始化方法
     * 1. 调用时机:默认情况下,Servlet被第一次访问时,调用
     *      * loadOnStartup:
     * 2. 调用次数:1次
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        System.out.println("init...");
    }
    @Override
    public ServletConfig getServletConfig() {
        return config;
    }

    /**
     * 提供服务
     * 1. 调用时机:每一次Servlet被访问时,调用
     * 2. 调用次数:多次
     *
     *
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }


    /**
     * 销毁方法
     * 1. 调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
     * 2. 调用次数:1次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }

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

Servlet体系结构

实例

package com.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post...");
    }
}

总结

HttpServlet使用步骤

  • 继承HttpServlet
  • 重写doGet和doPost方法

HttpServlet原理

  • 获取请求方式,并根据不同的请求方式,调用不同的doXxx方法。

Servlet urlPattern配置

  • Servlet要想被访问,必须配置其访问路径(urlPattern)。

实例

package com.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * urlPattern:一个Servlet可以配置多个访问路径
 */

@WebServlet(urlPatterns = {"/demo7","/demo8"})
public class ServletDemo7 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("demo7 get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


    }
}

urlPattern配置规则

实例(精确匹配)

package com.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * urlPattern:
 *  * 精确匹配
 */

@WebServlet(urlPatterns = "/user/select")
public class ServletDemo8 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("demo8 get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

实例2(目录匹配)

package com.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * urlPattern:
 *  * 目录匹配:/user/*
 */

@WebServlet(urlPatterns = "/user/*")
public class ServletDemo9 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("demo9 get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


    }
}

实例3(扩展名匹配)

package com.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * urlPattern:
 *  * 扩展名匹配: *.do
 */

@WebServlet(urlPatterns = "*.do")
public class ServletDemo10 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("demo10 get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


    }
}

实例4(任意匹配)

package com.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * urlPattern:
 *  * 任意匹配:/
 */

//@WebServlet(urlPatterns = "/")
public class ServletDemo11 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("demo11 get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


    }
}

XML配置方式编写Servlet(以后会学到用注解来编写)

  • Servlet 从3.0版本后开始支持使用注解配置,3.0版本前只支持XML 配置文件的配置方式。

步骤

实例

package com.web;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo13 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo13 get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

实例(web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">



  <!--
      Servlet 全类名
  -->

  <servlet>
    <servlet-name>demo13</servlet-name>
    <servlet-class>com.web.ServletDemo13</servlet-class>
  </servlet>


  <!--
      Servlet 访问路径
  -->

  <servlet-mapping>
    <servlet-name>demo13</servlet-name>
    <url-pattern>/demo13</url-pattern>
  </servlet-mapping>
</web-app>

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - (Web核心)HTTP&Tomcat&Servlet


三二一的一的二