Servlet

1.Tomcat(Http服务器,Http Container)

1.对下,实现了HTTP协议,服务器端,可以通过网络和客户端进行通信
2.对上,是实现了java规定的Servlet协议(Java 规定了几个interface)Tomcat定义了这些接口的实现类

2.Web应用的文件结构(docBase) 404 问题

WEB-INF web应用下的配置,类文件,依赖文件
—web.xml --XML格式的,用于web应用的配置
class\ 用户自定义类(业务类)的ClassPath
.calss
lib\一类是
.class文件 一类是.jar文件

3.Tomcat(Servlet)中如何区分不同的web应用(webapp)

1.web app | Context | ServletContext

Tomcat通过URL中的第一部份 Http://127.0.0.1:8080/hello/login
Tomcat通过URL中的后面部份 Http://127.0.0.1:8080/hello/login
Servlet对象(动态文档 | 动态文档)
1.根据web.xml中的配置去查找
—1.根据url找到对应的servlet-mapping(映射关系)->servlet
—2.根据servlet名字找到对应的Servlet的类
2.静态文档
直接在docBase为相对路径查找

4.请求是如何从浏览器到你的Servlet的代码的(动态的说是Servlet的对象)
1.结合网络2.结合Tomcat的分用逻辑
在这里插入图片描述
Tomcat和Servlet的其他重要信息:
1.Servlet(interface)(主要用于TCP|UDP业务的)
–Servlet(interface)下的一个HttpServlet(abstract class)
2.Servlet

init()初始化用的
service()每次提供服务是调用的
destroy()销毁是使用

Servlrt对象的生命周期:

Tomcat:启动流程

1.读取conf下的配置文件
2.监听8080端口(server.xml)
3.扫描目录(webapps)
读取并解析zhaoyanlong\WEB-INF\web-xml
4.进行Servlet对象的初始化
(每一个Servlet类在进程运行过程中有且仅有一个对象:单例模式)
调用Servlet对象的init()方法
5.定义了Map<url,Servlet名称>
Map<Servlet名称,Servlet对象>
先使用url获取,名称然后再换取到对象。
在这里插入图片描述
6.Socket socket =ss.accpet();
为了并发能力,Tomcat使用了多线程处理各个请求
7.每个线程中

1.从socket的inputStream读取内容
2. 按照HTTP协议,解析请求
3.构造一个HttpServletRequest对象
4.构造一个HttpServletResponse对象
5.根据url找对应的Servlet对象去处理
0.根据url中的第一部分,先确定哪一个context(ROOT)无前缀
1.看是否能根据两个Map找到对应的Servlet对象
2.再给一个静态资源的机会,(就是在docBase找文件)
找不到就404了
6.去调用该Servlet对象的service()方法
HttpServlet实现了service方法,根据HTTP方法分别调用
doGET/doPost/doPut/doDelete
7.我们自己做的Servlet中填充response的内容
8.把response按照HTTP协议,发送给socket.outputStream

8.当退出时
遍历所有的的Servlet对象,调用他们的destroy()方法
总结:对于Servlet对象的生命周期(只有一个Servlet对象)
init()/destroy()只会被调用一次
service()每次服务就会调用一次(会被调用多次)
2.使用service的时候,是在多线程环境下工作(考虑线程安全)

Annotation 注解:@WebServlet()

public @interface MyAnnotation {
}

@MyAnnotation
public class MyMain {
}

使用注解后就可以不需要的web.xml文件中配置,会直接获取注解中信息。

Servlet API有以下三个java包:

javax.servlet(重点):其中包含定义Servlet和Servlet容器之间的类和接口
javax.servlet.http(重点):其中包含定义HTTP Servlet和Servlet容器之间的类和接口
javax.servlet.annotation:其中包含标注Servlet,Filter,Listener的注解

disable cache 为了减少服务器的访问量,会在浏览器中有一个缓存池,访问相同连接,会直接从池中读信息,需要注意ctrl+F5
如果使用GET方法不能有请求体个人输入的信息会随着QueryString一起显示出来。
使用post的话,会出现在正文中。
测试代码:
在这里插入图片描述

FirstServlet

package com.zhaoyanlong;
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;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<table>");
        out.println("<thead>");
        out.println("<tr>");
        out.println("<th>名称</th>");
        out.println("<th>值</th>");
        out.println("</tr>");
        out.println("</thead>");
        out.println("<tbody>");
        String method=req.getMethod();
        tr(out, "Method", method);
        String pathInfo = req.getPathInfo();
        tr(out, "PathInfo",pathInfo);
        String pathTranslated = req.getPathTranslated();
        tr(out, "PathTranslated",pathTranslated);
        String contextPath = req.getContextPath();
        tr(out, "ContextPath",contextPath);
        String queryString = req.getQueryString();
        tr(out,"QueryString" ,queryString);
        String requestURI = req.getRequestURI();
        tr(out,"RequestURL" ,requestURI );
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (Map.Entry<String,String[]> entry:parameterMap.entrySet()) {
            for (String val:entry.getValue()) {
                tr(out, entry.getKey(),val);
            }
        }
        System.out.println(req.getParameter("你好"));
        System.out.println(Arrays.toString(req.getParameterValues("你好")));

        Enumeration<String> headerNames = req.getHeaderNames();
        //只要有更多元素就去遍历
        while (headerNames.hasMoreElements()){
            //我们可以拿到name
            String name=headerNames.nextElement();
            //通过name拿到val  现在拿到的还是数组
            Enumeration<String>heads=req.getHeaders(name);
            while (heads.hasMoreElements()){
                //拿到每一个val
                String val=heads.nextElement();
                tr(out, name,val);
            }
        }
        out.println("</tbody>");
        out.println("</table>");
    }
    private void tr(PrintWriter out,String name,String val){
        out.println("<tr>");
        out.printf("<td>%s</td>",name);
        out.printf("<td>%s</td>",val);
        out.println("</tr>");
    }
}

LoginServlet

package com.zhaoyanlong;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
public class LoginServlet extends HttpServlet {
    //统计接口被调用此时
    //结合Servlet的生命周期理解多线程中存在共享变量
    //private int count=0;错误

    private AtomicInteger count=new AtomicInteger();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //请求就是告诉编码返回时以同类型返回
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out=resp.getWriter();
        out.println("<h1>2020</h1>");
        out.printf("<p>被访问次数:%d</p>",count.getAndIncrement());
    }
}

SecondServlet

package com.zhaoyanlong;
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;
import java.io.PrintWriter;
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
    //通过表单来提交
    private void run(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out=resp.getWriter();
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        out.println("<h1>"+req.getMethod()+"</h1>");
        out.println("<p>用户名:"+username+"</p>");
        out.println("<p>密码:"+password+"</p>");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        run(req,resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        run(req,resp);
    }
}

index.css

h1{
    font-size: 50px;
    color: aqua;
    background: blue;
}

index.js

alert("wansui")

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_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.zhaoyanlong.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>

index.html

<!DOCTYPE html>
<html>
<head>
    <title>中华人民</title>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html: char; charset=utf-8"/>
    <script src="js/index.js"charset="UTF-8"></script>
    <link rel="stylesheet"type="text/css"href="css/index.css">
</head>
<body>
<h1>成立l</h1>
<a href="login">站起来</a>
</body>
</html>

Login.html

<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form method="post"action="/second">
    <label for="username">用户名:</label>
    <input type="text"name="username" placeholder="请填写用户名"/>
    <label for="password">密码:</label>
    <input type="password" name="password" placeholder="请输入密码"/>
    <input type="submit"value="登录"/>
</form>
</body>
</html>

table.html

<meta charset="UTF-8"/>
<table>
    <thead>
    <tr>
        <th>姓名</th>
        <th></th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>年龄</td>
        <td>18</td>
    </tr>
    <tr>
        <td>生日</td>
        <td>0101</td>
    </tr>
    <tr>
        <td>爱好</td>
        <td>篮球</td>
    </tr>
    </tbody>
</table>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章