• 使用Tomcat搭建一个Servlet项目


    Tomcat

    Tomcat是一个HTTP服务器,在TCP服务器的基础上加了一些额外的功能,能够解析请求中的HTTP报文,把请求转换成结构化数据(对象),也能很方便的构造HTTP响应。HTTP服务器提供了一组API,方便程序员直接调用来操作HTTP协议,从而简化程序员的开发工程。servlet程序是一个war后缀的文件,tomcat会自动把war解压缩得到一个目录,每个war其实就对应了一个webapp,一个Tomcat可以部署多个servlet程序,所以可以把Tomcat称为“servlet的容器”。

    maven

    maven是java世界中非常知名的“工程管理工具”/“构建工具”,核心功能:管理依赖,构建/编译,打包。maven存在的意义就是能够直接把这些操作串起来,一气呵成。

    • 依赖:进行A操作前,先执行B操作
    • 构建/编译:调用jdk
    • 打包:把java代码构造成jar或者war

    使用

    创建maven项目

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    管理依赖

    在这里插入图片描述
    在这里插入图片描述

    实践

    完成一个servlet的hello world
    1.创建一个maven项目
    2.引入依赖
    需要在代码中引入servlet api,这个api不是jdk内住的,而是第三方tomcat提供的,借助Maven直接引入。
    在这里插入图片描述

    3.创建目录结构
    在这里插入图片描述
    在这里插入图片描述

    DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
        <display-name>Archetype Created Web Applicationdisplay-name>
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.编写servlet代码
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    5.打包和部署
    使用smart tomcat插件

    6.验证程序
    在这里插入图片描述

    可以这样认为:
    一个Tomcat上可以同时部署多个网站,一个网站上又有多个页面,一个请求中的第一级路径用于告诉tomcat要访问的网站是哪个,第二级路径告诉tomcat要访问的页面是这个网站的那个页面。

    使用总结

    在这里插入图片描述

    GET,POST请求应用场景

    啥时候浏览器发的是GET请求?

    1. 直接在地址栏里输入URL
    2. 通过a标签跳转
    3. 通过img/link/script
    4. 通过form表单,method指定为GET
    5. 通过ajax,type指定为GET

    啥时候浏览器发送的是POST请求?

    1. 通过form表单,method指定为POST
    2. 通过ajax,type类型为POST

    Servlet运行原理

    在这里插入图片描述

    Tomcat伪代码

    Tomcat初始化

    1)让Tomcat先从指定的目录中找到所有要加载的Servlet类
    前面部署的时候是把Servlet代码编译成了.class,然后打包成了war包。然后拷贝到了webapps里面。Tomcat就会从webapps里来找到哪些.class对应的Servlet类,并进行加载。
    2)根据刚才类加载的结果,给这些类创建Servlet实例
    在这里插入图片描述

    3)实例创建好之后,就可以调用当前Servlet实例的init方法了
    在这里插入图片描述

    4)创建TCP socket,监听8080端口,等待有客户端来连接
    在这里插入图片描述

    5)如果循环退出了,Tomcat也要结束了就会一次循环调用每个Servlet的destroy方法
    在这里插入图片描述

    Tomcat处理请求

    在这里插入图片描述

    1)req司通过读取socket中的数据,然后爱按照HTTP协议的请求格式来解析的,构造成了一个HttpServletRequest对象,resq这里则是相当于new了一个空对象
    2)判定当前要的顶球是否是静态文件,如果是静态文件就要读取文件内容,把文件内容够遭到resq对象的body中,并且返回这个resq对象
    3)根据请求的URL来获取到使用哪个类来处理
    URL里有两个路径。
    第一级路径:Context Path,确定一个webapp
    第二级路径:Servlet path,确定一个Servlet类
    如果没有找到匹配的Servlet类就会返回404
    4)根据刚才找到的Servlet对象,来调用service方法,在service方法内部又会进一步调用doGet/doPost,下面是service方法内部
    在这里插入图片描述

    Servlet的关键API

    HTTPServlet

    我们写的代码就是通过继承这个类,重写其中的方法来被Tomcat执行
    在这里插入图片描述
    在这里插入图片描述

    HttpServletRequest和HttpServletResponse

    在这里插入图片描述
    在这里插入图片描述

    例子1:

    展示请求的响应

    @WebServlet("/showRequest")
    public class ShowRequestServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("

    首行部分

    "
    ); stringBuilder.append(req.getProtocol()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getMethod()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getRequestURI()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getContextPath()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getQueryString()); stringBuilder.append("
    "
    ); stringBuilder.append("

    header部分

    "
    ); Enumeration<String> headerNames = req.getHeaderNames(); while(headerNames.hasMoreElements()){ String headerName = headerNames.nextElement(); String headerValue = req.getHeader(headerName); stringBuilder.append(headerName + ":" + headerValue + "
    "
    ); } resp.setContentType("text/html; charset=utf8"); resp.getWriter().write(stringBuilder.toString()); } }
    • 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

    在这里插入图片描述

    例子2:

    展示参数的请求

    @WebServlet("/getParameter")
    public class getParameter extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String userId = req.getParameter("userId");
            String classId = req.getParameter("classId");
            resp.getWriter().write("userId=" + userId + "classId=" + classId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    body格式

    请求body格式

    1.x-www-form-urlencoded
    获取参数的方式和GET一样,也是getParameter
    在前端构造一个这样格式的请求
    1)form表单
    userId=1234&classId=5678

    <form action="postGetParameter" method="post">
        <input type="text" name="userId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2)postman
    在这里插入图片描述

    3)json

    可以使用第三方的库来直接处理json格式数据,主要使用的库叫做Jackson,通过maven把jackson这个库下载到本地并引入到项目中。
    在浏览器前端代码中通过js构造json格式的请求
    在这里插入图片描述
    在这里插入图片描述

    在java后端代码中通过jackson来进行出,需要使用jackson把请求body中的数据读取出来并解析成Java中的对象。
    在这里插入图片描述

    class User{
        public int userId;
        public int classId;
    }
    @WebServlet("/postJson")
    public class PostJsonServlet extends HttpServlet {
        //1.创建一个Json的核心对象
        private ObjectMapper objectMapper = new ObjectMapper();
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //2.读取body中的请求,然后使用ObjectMapper来解析成需要的对象
            //readValue就是把Json格式的字符串转成Java的对象
            //第一个参数表示对那个字符串进行转换,这个参数可以填成一个String,也可以填成一个InputStream对象,还可以填一个File
            //第二个参数表示要把这个JSON格式的字符串转成哪个Java对象
            User user = objectMapper.readValue(req.getInputStream(), User.class);
            resp.getWriter().write("userId=" + user.userId + ",classId:" + user.classId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    点击提交之后在浏览器控制台中就打印出来了服务器的响应数据,当前使用的是ajax的方式来提交数据,这个操作默认不会产生页面跳转,就和使用form风格差别很大。

    响应body格式

    在这里插入图片描述

    例子1:
    服务器返回状态码

    @WebServlet("/status")
    public class StatusServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setStatus(200);
            resp.getWriter().write("hello");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    例子2:
    实现自动刷新这样的页面效果,给HTTP响应中设置一个header:Refresh即可

    @WebServlet("/autoRefresh")
    public class AutoRefreshServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setHeader("Refresh", "1");
            resp.getWriter().write("timestamp:" + System.currentTimeMillis());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    例子3:
    构造一个重定向,构造一个302

    @WebServlet("/redirect")
    public class RedirectServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setStatus(302);
            resp.setHeader("Location", "https://www.sogou.com");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Cookie和Session

    Servlet提供的关键API

    HttpServletRequest类中的相关方法

    HttpSession getSession():在服务器中获取会话,参数如果为true,则当不存在会话时创建会话;参数如果为false,则当不存在会话时返回null

    Cookie[] getCookies():返回一个数组,包含客户端发送该请求的所有Cookie对象,会自动把Cookie中的东西解析成键值对。每个Cookie对象又包含了两个属性name和value

    在调用getSession的时候具体要做的事情:
    1.创建会话
    首先现获取请求中cookie里面的sessionId字段(相当于会话的身份标识),判定这个sessionId是否存在当前服务器上存在,如果不存在则进入创建会话逻辑。创建会话,会创建一个HttpSession对象,并且生成一个sessionId(是一个很长的数字,通常是用16进制来表示,能够保证唯一性),接下来就会把这个seesionId作为key,把这个HttpSession对象作为value,把这个键值对给保存到服务器内存的一个“哈希表”这样的结构中。再然后服务器就会返回一个HTTP响应,把sessionId通过Set-Cookie字段返回给浏览器,浏览器就可以保存这个sessionId到cookie中了。
    2.获取会话
    先获取到请求中的cookie里面的sessionId字段,判定这个sessionId是否存在当前服务器上存在,如果有就直接查询出这个HttpSession对象,并且通过返回值返回回去。

    HttpSession
    这个对象本质上也是一个键值对的结构,允许程序员往HttpSession对象中,存储人的键值对数据,key必须是String,value是一个Object
    在这里插入图片描述

    HttpSession里面的每个键值对称为属性。

    HttpSession提供了两个方法:
    getAttribute取键值对
    setAttribute存键值对

    Cookie提供的方法:
    String getName():该方法返回cookie的名称,名称在创建后不能改变。
    String getValue():该方法获取与cookie关联的值
    void setValue(String newValue):该方法设置于cookie关联的值

    HttpServletResponse类中的相关方法

    void addCookie(Cookie cookie):把指定的cookie添加到响应中,响应中就可以根据addCookie这个方法,来添加一个Cookie信息到响应报文中。这里添加进来的键值对就会作为HTTP响应中的Set-Cookie字段来表示。

  • 相关阅读:
    使用Signposts分析App性能
    我的MQTT操作类(M2Mqtt.Net)
    大模型的东风中,看雄安的数字飞翔
    MySQL日志
    架构问题:技术选型
    柯桥生活口语学习,英语中初次见面,除了Nice to meet you,还能说什么?
    使用Redis入门Golang
    Linux mkdir -p 以及如何创建带有空格的文件夹
    第二章《Java程序世界初探》第8节:条件运算符
    最新版成人高考专升本高数一、高数二有什么区别?
  • 原文地址:https://blog.csdn.net/weixin_46429649/article/details/126520641