• Java-Web-Servlet入门1.0


    1、设置编码

    注:设置编码必须放在所有的获取参数动作之前
    
    • 1

    post方式下:
    需要设置编码req.setCharacterEncoding(“UTF-8”);
    get方式下现在不需要设置编码(基于tomcat8,tomcat8之前的不行)
    get方式下:(tomcat8之前,get请求发送的中文数据,转码稍微有点麻烦)
    String fname=req.getParameter(“fname”);
    1、将字符串打散为字节数组
    byte[] bytes=fname.getBytes(“ISO-8859-1”);
    2、将字节数组按照设定的编码重新组装成字符串
    fname=new String(bytes,“UTF-8”);
    例:

    package com.atguigu.servlets;
    
    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 AddServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("UTF-8");
            String fname = req.getParameter("fname");
            String pricestr=req.getParameter("price");
            Integer price=Integer.parseInt(pricestr);
            String fcountstr=req.getParameter("fcount");
            Integer fcount=Integer.parseInt(fcountstr);
            String remark=req.getParameter("remark");
            System.out.println("fname= "+fname);
            System.out.println("price= "+price);
            System.out.println("fcount= "+fcount);
            System.out.println("remark= "+remark);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2、Servlet的继承关系 - 重点查看的是服务方法(service())

    1)、继承关系
        javax.servlet.Servlet接口
            javax.servlet.GenericServlet抽象类
                javax.servlet.HttpServlet抽象子类
    2)、相关方法
        javax.servlet.Servlet接口:
            void init(config)-初始化方法
            void service(request,response)- 服务方法
            void destroy-销毁方法
        javax.servlet.GenericServlet抽象类:
            void service(request,response)-仍然是抽象类
        javax.servlet.HttpServlet抽象子类:
            void service(request,response)-不是抽象类
            1.String method=req.getMethod();获取请求的方式
            2.根据if判断的结果,得出请求的方式、决定调用的不同的do方法
                if(method.equals("GET")){
                    this.doGet(req,resp);
                }else if(method.equals("Head")){
                    this.doHead(req,resp);
                }else if(method.equals("POST")){
                    this.doPost(req,resp);
                }else if(method.equals("PUT"){
                    this.doPut(req,resp);
                }
            3.在HttpServlet这个抽象类中,do方法都差不多
                protected void doGet (HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException{
                    String protocol = req.getProtocol () ;
                    String msg = lStrings.getString ("http.method_get_not_supported" );
                    if (protocol.endsWith ("1.1") ) {
                        resp.sendError (405,msg);
                    }else {
                        resp. sendError ( 400,msg) ;
                    }
                }
    3)、小结
        1)、继承关系:HttpServlet ->GenericServlet ->Servlet
        2)、Servlet 中的核心方法:init() 、service() 、destroy()
        3)、服务方法:当有请求过来时,service方法会自动响应(其实是tomcat容器调用)
                在HttpServlet中我们会分析请求的方式:到底是get、post、head、还是delete等等
                然后再决定调用哪个do开头的方法
                那么在HttpServlet中这些do方法默认都是405的实现风格-要我们子类去实现对应的方法,否则默认会报405错误
        4)、因此,我们在新建Servlet时,我们才会去考虑请求方法,从而决定要重写哪个do方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3、Servlet的生命周期

    1)、生命周期:从出生到死亡的过程就是生命周期。对应的Servlet中的三个方法:init()、service()、destroy()
    2)、默认情况下:
        第一次就接受请求时,这个servlet会进行实例化(调用构造方法)、初始化(调用init())、然后服务(调用service())
        第二次请求开始时,每一次都是服务
        当容器开始时,其中的所有的servlet实例会被销毁,调用销毁方法
    3)、
        -Servlet案例tomcat只会创建一个,所有的请求都是这个实例去响应的
        -默认情况下,第一次请求时tomcat才会实例化,初始化,然后再服务。
            好处是:提高系统的启动速度
            缺点是:第一次请求时,耗时较长
        -因此:如果需要提高系统的启动速度,当前默认情况就是这样。如果需要提高响应速度,我们应该Servlet的初始化时机
    4)、Servlet的初始化时机
        可以在xml中中设置 值可以是0、1、2、3等,尽量不要写负数
        设置Servlet启动的先后顺序,数字越小启动越靠前,最小值0
            好处是:响应速度变快
            缺点是:系统的启动速度变慢
    5)、Servlet在容器中是单例的、线程不安全的
            -单例:所有的请求都是在同一个实例中去响应
            -线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断。
                但是在中间的某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程的执行路径发生改变
            -办法:尽量不要在servlet中定义成员变量。如果不得不定义成员变量,
                那么不要去:I不要去修改成员变量的值 II不要去根据成员变量的值做一些逻辑判断
    6)、总结:1、Servlet接口:init() 、service() 、destroy()
                GenericServlet抽象子类:(这个方法没有实现,还是抽象)abstract service();
                HttpServlet抽象子类:实现了service方法,在service方法内部通过request.getMethod()来判断请求的方式
                                 然后根据请求的方式调用内部的do方法。每一个do方法进行了简单的实现,主要是如果请求方式不符,
                                 则报405错误,目的是让我们的Servlet子类去重写对应的方法(如果重写的不对,则调用父类的405错误实现)
              2、生命周期:实例化(Tomcat帮我们new的)、初始化、服务、销毁
                    -Tomcat负责维护Servlet实例的生命周期
                    -每一个Servlet在Tomcat容器中只有一个实例,他是线程不安全的
                    -启动时机:通过设置
                    -Servlet3.0开始支持注解:@webServlet
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    4、Http协议

    1)、Http 称之为 超文本传输协议
    2)、Http 是无状态的:服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的
            -无状态带来的现实问题:
                例第一次请求添加商品到购物车,第二次请求是结账;如果两次请求服务器无法区分是同一个用户,那么就会导致混乱
            -通过会话跟踪技术解决无状态问题
    3)、Http请求响应包含两部分:请求和响应
        -请求:
            请求包含三部分:1、请求行 2、请求消息头 3、请求主题
                I、请求行包含的三个信息:1、请求的方式 2、请求的URL 3、请求的协议(一般都是Http1.1)
                II、请求消息头包含很多客户端需要告诉服务器的信息,
                    比如:我的浏览器的版本型号、版本、我能接收的内容的类型、我给你发的内容的类型、内容的长度等等
                III、请求体,三种情况
                    get方式,没有请求体,但是有一个queryString
                    post方式,有请求体,form data
                    json方式,有请求体,request payload
        -响应:
            响应也包含三部分:1、响应状态行 2、响应消息头  3、响应体
                I、响应行包含三个信息:1、协议 2、响应状态码(200) 3、响应状态(ok)
                II、响应头:包含了服务器的信息,服务器发送给浏览器的信息(内容的媒体类型、编码、内容长度等)
                III、响应体:相应的实际内容(比如请求add.html页面时,响应的内容就是
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5、会话

    1)、会话跟踪技术
        -客户端第一次发请求给服务器,服务器获取session,获取不到,则创建新的,然后响应给客户端
        -下次客户端给服务器发请求时,会把sessionID带给服务器,那么服务器就能获取到sessionID,
            那么服务器就判断这个请求和上次某一次请求是同一个,从而能区分开客户端
        -常用API:
            request.getSession()->获取当前的会话,没有则创建一个新的会话
            request.getSession(true)->效果和不带参数相同
            request.getSession(false)->获取当前会话,没有则返回null,不会创建新的会话
    
            session.getId()->获取sessionID
            session.isNew()->判断当前session是否是全新的
            session.getMaxInactiveInterval()->session的非激活间隔时长,默认1800秒
            session.setMaxInactiveInterval()
            session.invalidate()->强制性让会话立即失效
    2)、session保存作用域
        -session保存作用域是和具体的某一个session对应的
        -常用的API:
            void session.setAttribute(k,v);
            Object session.getAttribute(k);
            void removeAttribute(k);
    3)、总结:1、HttpSession:表示 会话
             2、为什么需要HttpSession:原因是Http协议是无状态的
             3、Session保存作用域:一次会话 范围都有效;void session.setAttribute(k,v);Object getAttribute(k)
             4、其他API:(获取ID)session.getId();(判断是否是新的) session.isNew();
                        (获取创建的时间) session.getCreationTime();(强制性让某一个会话失效)session.invalidate() 等等
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    6、服务器内部转发以及客户端重定向

    1)、服务器内部转发:request.getRequestDispatcher("...").forward(request,response);
            -一次请求响应的过程。对于客户端,内部经过多少次转发,客户端是不知道的
            -地址栏没有变化
    2)、客户端重定向:response.sendRedirect("...");
            -两次请求响应的过程。客户端肯定知道请求URL有变化
            -地址栏有变化
    3)、总结:1、服务器端转发:request.getRequestDispatcher("index.html").forward(request,response);
            2、客户端重定向:response.sendRedirect("index.html");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    7、Thymeleaf-视图模板技术

    1)、添加thymeleaf的jar包
    2)、新建一个Servlet类ViewBaseServlet
    3)、在web.xml文件中添加配置
        -配置前缀 view-prefix
        -配置后缀 view-suffix
    4)、使得我们的Servlet继承ViewBaseServlet
    5)、根据逻辑视图名称 得到 物理视图名称
    //此处的视图名称是index
    //那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图名称上去
    //逻辑视图名称:index
    //物理视图名称:view-prefix+逻辑视图名称+view-suffix
    //所以真实的视图名称是:(view-prefix对应的名称)    +index   +(view-suffix对应的名称)
    super.processTemplate("index",request,response);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6)、使用thymeleaf标签
    th:if , th:unless , th:each , th:text
    7)、总结:
    1、使用步骤:添加jar ,新建ViewBaseServlet (有两个方法),配置两个: view-prefix, view-suffix
    2、部分标签:
    3、
    //200:正常响应
    //302:重定向
    //404:找不到资源
    //405:请求方式不支持
    //500:服务器内部错误

  • 相关阅读:
    二、java版 SpringCloud分布式微服务云架构之Java 开发环境配置
    Chatbot UI集成LocalAI实现自托管的ChatGPT
    信息化发展69
    python自动解析301、302重定向链接
    Promise从入门到精通(第3章 自定义(手写)Promise)
    多御安全浏览安卓版升级尝鲜,新增下载管理功能
    角谱迭代与傅里叶变换迭代算法(GS)的原理及其实例演示分析
    手机系统要不要更新?来看看这个答案
    .NET使用分布式网络爬虫框架DotnetSpider快速开发爬虫功能
    ctfshow 反序列化篇(下)
  • 原文地址:https://blog.csdn.net/hzsd_ygdcs/article/details/126059234