Servlet(未完结~)

文章目录

  • 前言
  • 1 Servlet简介
  • 2 Servlet初识
    • 2.1 Servlet开发流程
    • 2.2 配置欢迎页
  • 3 Servlet案例开发!
    • 3.1 开发登录页
    • 3.2 开发后台Servlet
    • 3.3 配置Servlet
  • 4 HttpServletRequest
    • 4.1 回顾http请求
    • 4.2 自定义servlet流程图
    • 4.3 HttpServletRequest
    • 4.4获取请求行信息
    • 4.5获取请求头信息
    • 4.6获取请求数据
  • 5 HttpServletResponse
    • 5.1回顾http响应
    • 5.2HttpServletResponse
  • 6 关于乱码问题
    • 6.1控制台乱码
    • 6.2post请求乱码
    • 6.3get请求乱码
    • 6.4响应乱码
  • 7 Servlet的继承结构
    • 7.1 Servlet接口
    • 7.2 ServletConfig接口
    • 7.3 GenericServlet抽象类
    • 7.4 HttpServlet
  • 8 Servlet的生命周期
    • 8.1 初始化时间问题
  • 9 ServletContext和servletConfig
    • 9.1 ServletContext 重要
    • 9.1.1 ServletContext对象的作用
    • 9.1.2 ServletContext对象的使用
      • 9.1.2.1 基本使用
      • 9.1.2.2 获取web.xml文件中的信息
      • 9.1.2.3全局容器
    • 9.2 SerlvetConfig对象
  • 10 ur-pattern的匹配规则
    • 10.1 精确匹配
    • 10.2 扩展名匹配
    • 10.3 路径匹配
    • 10.4 任意匹配
    • 10.5 匹配所有
    • 10.6 优先顺序
    • 10.7 URL映射方式
  • 11 注解模式开发Servlet
  • 12 请求转发
    • 12.1 forword处理流程
    • 12.2 include处理流程
    • 12.3 总结
  • 13 响应重定向
    • 13.1 总结
  • 14 路径问题
    • 14.1前段的路径问题
    • 14.2 请求转发的路径问题
    • 14.3 响应重定向的路径问题
  • 15 会话管理
    • 15.1 认识Cookie和Session
    • 15.2 Cookie的使用
  • 16 域对象

前言

开发工具专栏
上篇接tomcat

历史简单篇tomcat,servlet

1 Servlet简介

Servlet介绍
Servlet是Server Applet的简称,称为服务端小程序,是JavaEE平台下的技术标准,基于Java语言编写的服务端程序。Web容器或应用服务器实现了Servlet标准所以Servlet需运行在Web容器或应用服务器中。Servlet主要功能在于能在服务器中执行并生成数据。

Servlet技术特点
Servlet使用单进程多线程方式运行。
在这里插入图片描述

Servlet在应用程序中的位置
两个图来展示,帮助我们理解
在这里插入图片描述
在这里插入图片描述

静态资源和动态资源区分
静态资源:每次访问都不需要运算,直接就可以返回的资源,如HTML CSS JS多媒体文件等等,每次访问获得的资源都是一样的
动态资源:每次访问都需要运算代码生成的资源,如Servlet JSP ,每次访问获得的结果可能都是不一样的
Servlet作为一种动态资源技术,是我们后续学习框架的基础

Servlet在程序中到底处于一个什么地位?
Servlet是可以接受Http请求并作出相应的一种技术,是JAVA语言编写的一种动态资源
Servlet是前后端衔接的一种技术,不是所有的JAVA类都可以接收请求和作出相应,Servlet可以
在MVC模式中,Servlet作为Controller层(控制层)主要技术,用于和浏览器完成数据交互,控制交互逻辑

2 Servlet初识

2.1 Servlet开发流程

案例:

在后台随机生成一个整数当浏览器请求一个Servlet时 如果生成的是奇数,返回"happy new year"如果生成的是偶数,返回"happy birthday"

1创建一个JAVAWEB项目,并在项目中开发一个自己的Servlet ,继承HttpServlet类
在这里插入图片描述
一定要查看External Libraries中有Tomcat中的两个JAR jsp-api servlet-api

2在MyServlet类中重写service方法
在这里插入图片描述

在这里插入图片描述
如果我们想获得请求中的信息,就要通过HttpServetRequest对象获得
如果我们想给浏览器响应一些信息,就要通过HttpServletResponse对象响应

3在service方法中定义具体的功能代码
在这里插入图片描述

4在web.xml中配置Servlet的映射路径
在这里插入图片描述
上述图片我们设置的访问路径为localhost:/xxx

2.2 配置欢迎页

当我们访问项目名的时候为什么默认访问的是index.html呢?我们找到tomcat目录下conf/web.xml文件最后面可以看到,他帮我默认配置了输入了项目名访问的路径
在这里插入图片描述
假如我们想自定义默认路径可以在项目中的web.xml文件中进行配置
查找顺序是从上往下进行查找
在这里插入图片描述

3 Servlet案例开发!

案例开发需求
准备一个登录页,可以输入用户名和密码
输入完毕后向后台Servlet提交用户名和密码
Servlet接收到用户名和密码之后,校验是否正确
如果正确响应Success
如果不正确响应Fail

开发过程如下

3.1 开发登录页

在webapp文件夹下创建login.xml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="get" action="loginServlet.do">
    <table style="margin: 0px auto" width="300px" cellpadding="0px" cellspacing="0px" border="1px">
        <tr><td>用户名</td><td><input type="text" name="username"></td></tr>
        <tr><td>密码</td><td><input type="password" name="pwd"></td></tr>
        <tr align="center"><td colspan="2"><input type="submit" value="登录"></td></tr>
    </table>
</form>
</body>
</html>

我们在web.xml文件中配置login.xml为根目录

    <welcome-file-list>
        <welcome-file>login.html</welcome-file>
    </welcome-file-list>

3.2 开发后台Servlet

创建LoginServlet 类继承HttpServlet并重写service方法

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.err.println("进入了servlet");
        //获取请求中的数据
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        //判断数据
        String message = null;
        if(username.equals("123") && pwd.equals("123")){
            message = "Success";
        }else{
            message = "Fail";
        }
        //作出响应
        resp.getWriter().write(message);
    }
}

3.3 配置Servlet

from表单中的action属性需要配置访问路径
我们在web.xml中配置LoginServlet 访问路径"/loginServlet.do"

<?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-name>loginServlet</servlet-name>
        <servlet-class>com.msr.demo_servlet.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>loginServlet</servlet-name>
        <url-pattern>/loginServlet.do</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>login.html</welcome-file>
    </welcome-file-list>
</web-app>

运行测试
http://localhost:9008/demo_servlet_war_exploded/

4 HttpServletRequest

4.1 回顾http请求

在这里插入图片描述
请求行
在这里插入图片描述
请求头
在这里插入图片描述
请求体

get方式提交的请求数据通过地址栏提交没有请求体
post方式提交请求数据单独放到请求体中,
请求时所携带的数据(post方式)

http支持的请求方式
在这里插入图片描述

post和get方式提交请求的差别(面试重要)

  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行ur编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST则没有。对参数的数据类型GET只接受ASCI字符,而POST即可是字符也可是字节。
  • GETE比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在Request body中。

4.2 自定义servlet流程图

在这里插入图片描述

4.3 HttpServletRequest

HttpServletRequest对象代表客户端浏览器的请求,当客户端浏览器通过HTTP协议访问服务器时,HTTP请求中的所有信息都
会被Tomcat所解析并封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

请求数据
在这里插入图片描述

4.4获取请求行信息

测试代码

System.out.println("完整的URL:"+req.getRequestURL());//返回客户端浏览器发出请求时的完整URL。
System.out.println("请求的指定资源:"+req.getRequestURI());//返回请求行中指定资源部分。
System.out.println("客户端的IP:"+req.getRemoteAddr());//返回发出清求的客户机的IP地址。
System.out.println("WEB服务器IP:"+req.getLocalAddr());//返回WEB服务器的IP地址。
System.out.println("服务器端处理HTTP请求的端口:"+req.getLocalPort());//返回WEB服务器处理Http协议的连接器所监听的端口。
System.out.println("主机名:"+req.getLocalName());
System.out.println("客户端PORT:"+req.getRemotePort());
System.out.println("当前项目部署名:"+req.getContextPath());
System.out.println("协议名:"+req.getScheme());
System.out.println("请求方式:"+req.getMethod());

打印结果

完整的URL:http://localhost:9008/demo_servlet_war_exploded/loginServlet.do
请求的指定资源:/demo_servlet_war_exploded/loginServlet.do
客户端的IP:0:0:0:0:0:0:0:1
WEB服务器IP:0:0:0:0:0:0:0:1
服务器端处理HTTP请求的端口:9008
主机名:0:0:0:0:0:0:0:1
客户端PORT:49648
当前项目部署名:/demo_servlet_war_exploded
协议名:http
请求方式:GET

4.5获取请求头信息

测试代码

String headerValue = req.getHeader("accept-encoding");//根据请求头中的key获取对应的value。
System.out.println(headerValue);
//早期的Iterator
Enumeration<String> headerNames = req.getHeaderNames();//获取请求头中所有的key,该方法返回枚举类型。
while(headerNames.hasMoreElements()){
	String headerName = headerNames.nextElement();
	System.out.println(headerName+":"+req.getHeader(headerName));
	}

打印结果

gzip, deflate, br
host:localhost:9008
connection:keep-alive
pragma:no-cache
cache-control:no-cache
sec-ch-ua:"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
sec-fetch-site:same-origin
sec-fetch-mode:navigate
sec-fetch-user:?1
sec-fetch-dest:document
referer:http://localhost:9008/demo_servlet_war_exploded/
accept-encoding:gzip, deflate, br
accept-language:zh-CN,zh;q=0.9
进入了servlet

4.6获取请求数据

在Servlet获取请求数据的方式
req.getParameter(“key” );//根据key获取指定value。
String str = req.getParameter(“key”);
获取复选框(checkbox组件)中的值
eq.getParameterValues("checkboxkey );//获取复选框(checkbox组件)中的值,返回- -个String[I。
String[] userlikes = req.getParameterValues(“checkboxkey”);
获取所有提交数据的key
req.getParameterNames0);//获取请求中所有数据的key,该方法返回一个枚举类型。
Enumeration parameterNames = req.getParameterNames()
使用Map结构获取提交数据
req.getParameterMap0://获取请求中所有的数据并存放到一 个Map结构中,该方法返回一个Map,其中key为String类
型value为String[]类型。
Map<String, String[]> parameterMap = req.getParameterMap(;
设置请求编码
req.setCharacterEncoding(“utf-8”)
请求的数据包基于字节在网络上传输,Tomcat接收到请求的数据包后会将数据包中的字节转换为字符。在Tomcat中使用的
是ISO-8859-1的单字节编码完成字节与字符的转换,所以数据中含有中文就会出现乱码,可以通req.setCharacterEncoding(“utf-8” )方法来对提交的数据根据指定的编码方式重新做编码处理。

测试代码
前段

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
开发form表单注意事项
1.form 不是from
2.form表单内部不是所有的标签信息都会提交  一些输入信息 input  select  textarea ...
3.要提交的标签必须具备name属性 name属性的作用是让后台区分数据 id属性是便于在前端区分数据
4.要提交的标签一般都要具备value属性 value属性确定我们要提交的具体的数据
5.get  post
    get方式数据是通过URL携带
     提交的数据只能是文本
     提交的数据量不大
     get方式提交的数据相对不安全
    post 将数据单独打包方法请求体中
     提交的数据可以是文本可以是各种文件
     提交的数据量理论上没有上线
     post方式提交数据相对安全

    当一个表单标签
    readonly只读 也是会提交数据的
    hidden隐藏 也是会提交数据
    disabled不可用 显示但是不提交
-->
<form method="get" action="myServlet">
    <table style="margin: 0px auto" width="300px" cellpadding="0px" cellspacing="0px" border="1px">
        <tr><td>用户名</td><td><input type="text" name="username"></td></tr>
        <tr><td>密码</td><td><input type="password" name="pwd"></td></tr>
        <tr><td>性别</td>
            <td><input type="radio" name="gender" value="1" checked><input type="radio" name="gender" value="0">
            </td>
        </tr>
        <tr><td>爱好</td>
            <td>
                <input type="checkbox" name="hobby" value="1">篮球
                <input type="checkbox" name="hobby" value="2">足球
                <input type="checkbox" name="hobby" value="3">羽毛球
                <input type="checkbox" name="hobby" value="4">乒乓球
            </td>
        </tr>
        <tr><td>个人简介</td>
            <td>
                <!--文本域 双标签 页面上显示的文字是双标签中的文本  不是value属性

                文本域提交的数据不是value属性值,是双标签中的文本
                -->
                <textarea name="introduce"></textarea>
            </td>
        </tr>
        <tr>
            <td>籍贯</td>
            <td>
                <select name="provience">
                    <option value="1"></option>
                    <option value="2"></option>
                    <option value="3"></option>
                </select>
            </td>
        </tr>
        <tr align="center"><td colspan="2"><input type="submit" value="提交数据"></td></tr>
    </table>
</form>
</body>
</html>

web.html

    <servlet>
        <servlet-name>myServlet</servlet-name>
        <servlet-class>com.msr.demo_servlet.servlet.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>myServlet</servlet-name>
        <url-pattern>/myServlet</url-pattern>
    </servlet-mapping>

后端

public class MyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // req获取参数
        //如果前端发过米的数据由教构名但是没有值,getParameter 返回的是一个空字符申 ""
        //获取的参数在提交的数据中名都没有,getParameter返回的是null
        String username = req.getParameter("username");
        System.out.println("username:"+username);
        System.out.println("password:"+req.getParameter("pwd"));
        System.out.println("gender:"+req.getParameter("gender"));
        //hobby=1&hobby=2&hobby=3 想要获得多个同名的参数 getParameterValues返回的是一个String数组
        //获取的参数在提交的数据中名都没有,getParameterValues返回的是null
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("hobbies:"+ Arrays.toString(hobbies));
        //textarea
        System.out.println("introduce:"+req.getParameter("introduce"));
        //select
        System.out.println("provience:"+req.getParameter("provience"));
        System.out.println("-----------------------------------------");
        //如果不知道参数的名字?
        //获取所有的参数名
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String pname = parameterNames.nextElement();
            String[] parameterValues = req.getParameterValues(pname);
            System.out.println(pname+":"+Arrays.toString(parameterValues));
        }
        System.out.println("---------------------------------------");
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));
        }
    }
}

输出

username:aaa
password:123
gender:1
hobbies:[1, 2, 3]
introduce:111
provience:2
-----------------------------------------
username:[aaa]
pwd:[123]
gender:[1]
hobby:[1, 2, 3]
introduce:[111]
provience:[2]
---------------------------------------
username:[aaa]
pwd:[123]
gender:[1]
hobby:[1, 2, 3]
introduce:[111]
provience:[2]

5 HttpServletResponse

5.1回顾http响应

http响应部分可以分为三部分:响应行,响应头,响应体
在这里插入图片描述

响应行
在这里插入图片描述
响应状态码列表如下
在这里插入图片描述
响应头
Content-Type:响应内容的类型(MIME)
在这里插入图片描述响应实体
服务器响应回来的内容

5.2HttpServletResponse

HttpServletResponse对象代表服务器的响应。这个对象中封装了响应客户端浏览器的流对象,以及向客户端浏览器响应的响应头、响应数据、响应状态码等信息。

响应的设置

ContentType响应头

resp.setContentType(“MIME”);//该方法可通过MIME-Type设置响应类型。
MIME的全称是Multipurpose Internet Mail Extensions,即多用途互联网邮件扩展类型。
这是HTTP协议中用来定义文档性质及格式的标准。对HTTP传输内容类型进行了全面定义。
服务器通过MIME告知响应内容类型,而浏览器则通过MIME类型来确定如何处理文档。

代码

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //行相关信息
        resp.setStatus(500);
        //头相关信息
        resp.setHeader("Date","2022-2-2");
        resp.setHeader("aaa","xxx");
        //Content-Type响应头 响应给浏览器的MIME类型
        // 如果想知道都可以响应什么类型可以去tomcat的web.xml文件中查看 大概650行开始,有很多
        resp.setHeader("Content-Type","text/html");
        //体相关信息
        PrintWriter writer = resp.getWriter();
        writer.write("<h1>this is tag h1<h1/>");
    }

在这里插入图片描述

6 关于乱码问题

6.1控制台乱码

tomcat有三个打印日志的地方
Server乱码
在这里插入图片描述
修改
找到tomcat中的日志配置文件编码改为GBK
在这里插入图片描述

如果其他两个日志也是乱码
在这里插入图片描述
修改为GBK
在这里插入图片描述

6.2post请求乱码

通过HttpServletRequest设置请求编码
在这里插入图片描述

6.3get请求乱码

需要手动进行编码解码,或者设置tomcat中的server.xml中的URL编码,tomcat9已经解决了该问题
在这里插入图片描述

6.4响应乱码

通过HttpServletResponse设置响应编码
在这里插入图片描述

7 Servlet的继承结构

在这里插入图片描述

7.1 Servlet接口

1.init(),创建Servlet对象后立即调用该方法完成其他初始化工作。
2.getServletConfig(),ServletConfig是容器向servlet传递参数的载体。
3.service(),处理客户端请求,执行业务操作,利用响应对象响应客户端请求。
4.getServletlnfo(),获取servlet相关信息
5.destroy(),在销毁Servlet对象之前调用该方法,释放资源。

7.2 ServletConfig接口

Servlet运行期间,需要一些辅助信息,这些信息可以在web.xml文件中,使用一个或多个元素,进行配置。当Tomcat初始化一个Servlet时,会将该Servlet的配置信息,封装到一个ServletConfig对象中,通过调用init(ServletConfig config)方法,将ServletConfig对称传递给Servlet

7.3 GenericServlet抽象类

GenericServlet是实现了Servlet接口的抽象类。在GenericServlet中进一步的定义了Servlet接口的具体实现,其设计的目的是为了和应用层协议解耦,在GenericServlet中包含一个Service抽象方法。我们也可以通过继承GenericServlet并实现Service方法实现请求的处理,但是需要将ServletReuqest和ServletResponse转为HttpServletRequest和HttpServletResponse。

7.4 HttpServlet

继承自GercSenvlt.针对于处理HTP协议的青求所定制。在Httpendeb的sevcel)方法中已经把Se veReucet和Se verRspone转为HtperveBleuest和Htpservrtrkesponse。直按使甲用HtoSenveEkeqest和HttpServletResponse,不再需要强转。实际开发中,直接继承HttpServlet,并根据请求方式复写doXx()方法即可。
在这里插入图片描述

在这里插入图片描述
在我们自定义的Servlet中,如果想区分请求方式不同的请求方式使用不同的代码处理,那么我么重写doGet doPost即可如果我们没有必要区分请求方式的差异,那么我们直接重写service方法即可

8 Servlet的生命周期

Servlet的生命周期是由容器管理的,分别经历四各阶段:

>阶段            次数     时机
>创建		     1次      第一次请求
>初始化          1次      实例化之后 
>执行服务        多次      每次请求
>销毁            一次     停止服务

在这里插入图片描述

当客户端浏览器第一次请求Servlet时,容器会实例化这个Servlet,然后调用一次init方法,并在新的线程中执行service方法处理请
求。service方法执行完毕后容器不会销毁这个Servlet而是做缓存处理,当客户端浏览器再次请求这个Servlet时,容器会从缓存中直接找到这个Servlet对象,并再一次在新的线程中执行Service方法。当容器在销毁Servlet之前对调用一次destory方法。

注意:
在Serlvet中我们一般不要轻易使用成员变量!!! 可能会造成线程安全问题
如果要使用的话,应该尽量避免对成员变量产生影响修改
如果要产生影响我们应该注意线程安全问题
如果我们自己添加线程安全编码处理,会严重影响效率
综上所述:原则,能不用成员变量就不用!!!

8.1 初始化时间问题

假如servlet的初始化时间比较长,这就会导致我们第一次访问页面的时候会等待较长的时间,这样我们可以在web.xml文件中配置servlet自动初始化,这样他就会在tomcat启动的时候进行初始化

设置初始化顺序从6开始,前五个被tomcat使用了

<servlet>
	<servlet-name>myServlet</servlet-name>
	<servlet-class>com.msr.demo_servlet.servlet.MyServlet</servlet-class>
	<load-on-startup>6</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>myServlet</servlet-name>
	<url-pattern>/myServlet</url-pattern>
</servlet-mapping>

9 ServletContext和servletConfig

9.1 ServletContext 重要

ServletContext官方叫Servlet上下文。服务器会为每一个Web应用创建一个ServletContext对象。这个对象全局唯一,而且Web应用中的所有Servlet都共享这个对象。所以叫全局应用程序共享对象
在这里插入图片描述

9.1.1 ServletContext对象的作用

  • 相对路径转绝对路径
  • 获取容器的附加信息
  • 读取配置信息
  • 全局容器

9.1.2 ServletContext对象的使用

9.1.2.1 基本使用

获取项目的部署名
context.getContextPath()
相对路径转绝对路径(文件上传下载时需要注意)
context.getRealPath(“path”)
该方法可以将一个相对路径转换为绝对路径,在文件上传与下载时需要用到该方法做路径的转换。获取容器的附加信息
servletContext.getServerlnfo()
返回Servlet容器的名称和版本号
servletContext.getMajorVersion()
返回Servlet容器所支持Servlet的主版本号servletContext.getMinorVersion()
返回Servlet容器所支持Servlet的副版本号。

代码

public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //获取Servlet对象的方式
        //通过req对象
        ServletContext servletContext1 = req.getServletContext();
        //通过继承的方式
        ServletContext servletContext2 = this.getServletContext();
        System.out.println(servletContext1 ==servletContext2);

        //获取当前项目的部署名
        String contextPath= servletContext1.getContextPath();
        System.out.println("contextPath"+contextPath);
		//将一个相对路径转化为项目的绝对路径
        String fileupload = servletContext1.getRealPath( "fileupload");
        System.out.println(fileupload);
        String serverInfo = servletContext1.getServerInfo();
        System.out.println( "servletInfo"+serverInfo);
        int majorversion = servletContext1.getMajorVersion();
        int minorVersion = servletContext1.getMinorVersion();
        System.out. println(majorversion+":"+minorVersion);
	}
}

输出

true
contextPath/demo_servlet_war_exploded
D:\word\demo_servlet\target\demo_servlet-1.0-SNAPSHOT\fileupload
servletInfoApache Tomcat/8.5.45
3:1

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-name>Servlet1</servlet-name>
        <servlet-class>com.msr.demo_servlet.servlet.Servlet1</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Servlet1</servlet-name>
        <url-pattern>/servlet1.do</url-pattern>
    </servlet-mapping>
</web-app>

9.1.2.2 获取web.xml文件中的信息

在这里插入图片描述
servletContext.getlnitParameter(“key”)
该方法可以读取web.xml文件中标签中的配置信息。servletContext.getInitParameterNames()
该方法可以读取web.xml文件中所有param-name标签中的值。

在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">
    <context-param>
        <param-name>username</param-name>
        <param-value>123</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>456</param-value>
    </context-param>
</web-app>

通过servletContext获取web.xml中的数据
web.xml中数据会保存到ServletContext ,通过HttpServletRequest可以拿到上下文对象ServletContext

public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	ServletContext servletContext1 = req.getServletContext();
        String username = servletContext1.getInitParameter("username");
        String password = servletContext1.getInitParameter("password");
        System.out.println(username+":"+password);
        }
}

9.1.2.3全局容器

servletContext.setAttribute(“key” ,ObjectValue)向全局容器中存放数据。
servletContext.getAttribute(“key”)从全局容器中获取数据。
servletContext.removeAttribute(“key”)根据key删除全局容器中的value。

ArrayList<Object> data = new ArrayList<>();
Collections.addAll(data,"张三","李四","王五");
servletContext1.setAttribute("list",data);

然后可以通过不同的servlet进行读取

ServletContext servletContext2 = req.getServletContext();
String username = servletContext2.getInitParameter("username");
String password = servletContext2.getInitParameter("password");
System.out.println(username+":"+password);

List<String> list =(List<String>) servletContext2.getAttribute("list");
System.out.println(list);

9.2 SerlvetConfig对象

ServletConfig对象对应web.xml文件中的节点。当Tomcat初始化一个Servlet时,会将该Servlet的配置信息,封个ServletConfia对象中。我们可以通过该对象读取节点中的配置信息
在这里插入图片描述
servletConfig.getlnitParameter(“key”);
该方法可以读取web.xml文件中标签中标签中的配置信息。servletConfig.getInitParameterNames();
该方法可以读取web.xml文件中当前标签中所有标签中的值。
web.xml文件

在这里插入图片描述
测试代码

 @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	ServletConfig servletConfig = this.getServletConfig();       
	System.out.println(servletConfig.getInitParameter("brand"));
}

10 ur-pattern的匹配规则

10.1 精确匹配

精确匹配是指<url-pattern>中配置的值必须与url完全精确匹配。

在这里插入图片描述
http://localhost:8080/demo/demo.do 匹配
http://localhost:8080/demo/suibian/demo.do 不匹配

10.2 扩展名匹配

在允许使用统配符“”作为匹配规则,“”表示匹配任意字符。在扩展名匹配中只要扩展名相同都会被匹配和路径无关。注意,在使用扩展名匹配时在中不能使用“r”,否则容器启动就会抛出异常。
在这里插入图片描述
http://localhost:8080/demo/demo.do 匹配
http://localhost:8080/demo/suibian/demo.do 匹配

10.3 路径匹配

根据请求路径进行匹配,在请求中只要包含该路径都匹配。"*"表示任意路径以及子路径。
在这里插入图片描述
http://localhost:8080/demo/suibian/demo.do 匹配
http://localhost:8080/demo/suibian/hehe/demo.do 匹配
http://localhost:8080/demo/hehe/demo.do 不匹配

10.4 任意匹配

匹配"/".匹配所有但不包含JSP页面
在这里插入图片描述
http://localhost:8080/demo/suibian.do 匹配
http://localhost:8080/demo/suibian.html 匹配
http://localhost:8080/demo/123/suibian.css 匹配
http://localhost:8080/demo/123/suibian.jsp 不匹配

10.5 匹配所有

在这里插入图片描述
http://localhost:8080/demo/suibian.do 匹配
http://localhost:8080/demo/suibian.html 匹配
http://localhost:8080/demo/123/suibian.css 匹配
http://localhost:8080/demo/123/suibian.jsp 匹配

10.6 优先顺序

当一个url与多个Servlet的匹配规则可以匹配时,则按照“精确路径>最长路径>扩展名”这样的优先级匹配到对应的Servlet。
案例分析
在这里插入图片描述

10.7 URL映射方式

在这里插入图片描述
方式一
在这里插入图片描述
方式二
在这里插入图片描述

11 注解模式开发Servlet

这里不做过多解释(与目录9.ServletContext和servletConfig原理一样)

//@WebServlet(urlPatterns = "Servlet1.do")
@WebServlet(urlPatterns = {"Servlet1.do","12.do"},
        	loadOnStartup = 6,
        	initParams = {@WebInitParam(name = "brand1",value = "123"),
                      	  @WebInitParam(name = "brand2",value = "321")
                     })
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

12 请求转发

12.1 forword处理流程

1清空Response存放响应正文数据的缓冲区。
2如果目标资源为Servlet或JSP,就调用它们的service()方法,把该方法产生的响应结果发送到客户端;如果目标资源文件系统中的静态HTML文档,就读取文档中的数据把它发送到客户端。
在这里插入图片描述
forword处理特点:
1由于forword()方法先清空用于存放响应正文的缓冲区,因此源Servlet生成的响应结果不会被发送到客户端,只有目标资源生成的响应结果才会被发送到客户端。
2如果源Servlet在进行请求转发之前,已经提交了响应结(flushBuffer(),close()方法),那么forward()方法抛出lllegalStateException。为了避免该异常,不应该在源Servlet中提交响应结果。

代码

Servlet1

@WebServlet(name = "servlet1", value = "/servlet1.do")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1.do");
        String money = req.getParameter("money");
        System.out.println("money:"+money);

        resp.getWriter().println("asdasd");//响应无效 后边进行了转发

        //请求转发给另一个组件
        //获取请求转发器
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("servlet2.do");
        //由请求转发器作出转发
        requestDispatcher.forward(req,resp);

//在forward转发模式下,请求应该完全交给目标资源去处理,我们在源组件中,不要作出任何的响应处理
//在forward方法调用之后,也不要在使用req和resp对象做其他操作了
    }
}

Servlet2

@WebServlet(name = "servlet2", value = "/servlet2.do")
public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet2.do");

        String money = req.getParameter("money");
        System.out.println("money:"+money);

        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter writer = resp.getWriter();
        writer.println("支付宝到账:"+money+"元");
    }

}

访问接口:http://localhost:9008/demo_servlet_war_exploded/servlet1.do?money=100

12.2 include处理流程

1如果目标资源为Servlet或JSP,就调用他们的相应的service()方法,把该方法产生的响应正文添加到源Servlet的响应结果中;如果目标组件为HTML文档,就直接把文档的内容添加到源Servlet的响应结果中。
2返回到源Servlet的服务方法中,继续执行后续代码块。
在这里插入图片描述
include()处理特点
include与forward转发相比,包含有以下特点:
1源Servlet与被包含的目标资源的输出数据都会被添加到响应结果中。2在目标资源中对响应状态码或者响应头所做的修改都会被忽略。
代码
Servlet1

@WebServlet(name = "servlet1", value = "/servlet1.do")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1.do");
        String money = req.getParameter("money");
        System.out.println("money:"+money);

        设置响应类型和编码(include模式下)
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //增加响应内容(include)
        resp.getWriter().println("servlet1在转发之前做出相应内容");

        //请求转发给另一个组件
        //获取请求转发器
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("servlet2.do");
        //由请求转发器作出转发
        //equestDispatcher.forward(req,resp);
        requestDispatcher.include(req,resp);

        //继续增加响应内容(include)
        resp.getWriter().println("servlet1在转发之后做出相应内容");
    }
}

Servlet2

@WebServlet(name = "servlet2", value = "/servlet2.do")
public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet2.do");

        String money = req.getParameter("money");
        System.out.println("money:"+money);

        //设置响应类型和编码(forward模式下)
        // resp.setCharacterEncoding("UTF-8");
        // resp.setContentType("text/html;charset=UTF-8");

        resp.getWriter().println("支付宝到账:"+money+"元");
    }

}

访问接口:http://localhost:9008/demo_servlet_war_exploded/servlet1.do?money=100

12.3 总结

//在forward转发模式下,请求应该完全交给目标资源去处理,我们在源组件中,不要作出任何的响应处理
//在forward方法调用之后,也不要在使用req和resp对象做其他操作了
//在incLude较发模式下,设置响应可以在转发之前,也可以在转发之后
/*
*1请求转发是一种服务器的行为,是对浏览嚣器屏蔽
*2浏览器的地址栏不会发生变化
*3请求的参数是可以从源组件传递到目标组件的
*4请求对象和响应对象没有重新创建,而是传递给了目标组件*5请求转发可以帮助我们完成页面的跳转
*6请求转发可以转发至wEB-工NF里
*7请求转发只能转发给当前项目的内部资源,不能转发至外部资源
*8常用forward
**/

13 响应重定向

代码
Servlet3

@WebServlet(name = "servlet3", value = "/servlet3.do")
public class Servlet3 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet3");
        String money = req.getParameter("money");
        System.out.println("money:"+money);
        //响应重定向
        resp.sendRedirect("servlet4.do");
    }
}

Servlet4

@WebServlet(name = "servlet4", value = "/servlet4.do")
public class Servlet4 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet4");
    }
}

访问接口:http://localhost:9008/demo_servlet_war_exploded/servlet3.do?money=100

13.1 总结

//响应重定向
resp.sendRedirect(s:"servlet4.do?money="+money); 
//resp.sendRedirect("wEB-INF/bbb.htmL");
// resp.sendRedirect("https://www.baidu.com");
/*
*响应重定向总结
*1重定向是服务器给浏览器重新指定请求方向是一种浏览器行为地址栏会发生变化
* 2重定向时,请求对象和响应对象都会再次产生,请求中的参数是不会携带
*3重定向也可以帮助我们完成页面跳转
*4重定向不能帮助我们访问wEB-INF中的资源
*5重定向可以定向到外部资源

14 路径问题

14.1前段的路径问题

项目结构
在这里插入图片描述
a2.html和b1.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
this is a2/b1
</body>
</html>

a1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--
    2.
    base标签的作用是在相对路径之前自动补充base[href]中的值
    如果base标签不写,那么默认就是当前文件所在的路径
    -->
    <base href="http://127.0.0.1:9008//demo_servlet_war_exploded/">
</head>
<body>
this is a1
<!--
1.
相对(基准)路径:以当前文件本身的位置去定位其他文件,相对自己的路径,以当前文件所在的位置为基准位置
绝对(基准)路径:以一个固定的位置去定位其他文文件,以一个固定的路径作为定位文件的基准位置,和文件本身位置无关

相对路怪,不以/开头,就是相对路程..代表向上一层
绝对路径,以/开头―在页面上/代表从项目的部署目录开始找﹑从webapps中开始找
页面的绝对路径要有项目名,除非我们的项目没有设置项目名
-->

<a href="a2.html" target="_self">相对路径跳转a2</a>
<a href="../../b/b2/b1.html" target="_self">相对路径跳转b1</a>

<a href="a/a2/a2.html" target="_self">base相对路径跳转a2</a>
<a href="b/b2/b1.html" target="_self">base相对路径跳转b1</a>

<a href="/demo_servlet_war_exploded/a/a2/a2.html" target="_self">绝对路径跳转a2</a>
<a href="/demo_servlet_war_exploded/b/b2/b1.html" target="_self">绝对路径跳转b1</a>
</body>
</html>

14.2 请求转发的路径问题

在这里插入图片描述

14.3 响应重定向的路径问题

在这里插入图片描述

15 会话管理

15.1 认识Cookie和Session

Cookie对象与HttpSession对象简介
Cookie对象与HttpSession对象的作用是维护客户端浏览器与服务端的会话状态的两个对象,由于HTTP协议是一个无状态的协议,所以服务端并不会记录当前客户端浏览器的访问状态,但是在有些时候我们是需要服务端能够记录客户端浏览器的访问状态的,如获取当前客户端浏览器的访问服务端的次数时就需要会话状态的维持。在Servlet中提供了Cookie对象与Httpsession对象用于维护客户端与服务端的会话状态的维持。二者不同的是Cookie是通过客户端浏览器实现会话的维持,而HttpSession是通过服务端来实现会话状态的维持。

如何记录用户状态信息原理,举例:会员卡,银行卡
用户记录用户状态的技术
在这里插入图片描述

15.2 Cookie的使用

Cookie是一种保存少量信息至浏览器的一种技术,第一请求时,服务器可以响应给浏览器一些Cookie信息,第二次请求浏览器会携带之前的cookie发送给服务器,通过这种机制可以实现在浏览器端保留一些用户信息.为服务端获取用户状态获得依据

Cookie对象的特点

  • Cookie使用字符串存储数据
  • Cookie使用Key与Value结构存储数据单个
  • Cookie存储数据大小限制在4097个字节
  • Cookie存储的数据中不支持中文,Servlet4.0中支持
  • Cookie是与域名绑定所以不支持跨━级域名访问
  • Cookie对象保存在客户端浏览器内存上或系统磁盘中
  • Cookie分为持久化Cookie(保存在磁盘上)与状态Cookie(保存在内存上)
  • 浏览器在保存同一域名所返回Cookie的数量是有限的。不同浏览器支持的数量不同,Chrome浏览器为50个
  • 浏览器每次请求时都会把与当前访问的域名相关的Cookie在请求中提交到服务端。

Cookie对象的创建
Cookie cookie = new Cookie(“key” , “value”)
通过new关键字创建Cookie对象
response.addCookie(cookie)
通过HttpServletResponse对象将Cookie写回给客户端浏览器。

Cookie中数据的获取
通过HttpServletRequest对象获取Cookie,返回Cookie数组.
Cookie[] cookies = request.getCookies();

Cookie不支持中文解决方案
在Servlet4.0版本之前的Cookie中是不支持中文存储的,如果存储的数据中含有中文,代码会直接出现异常。我们可以通过对含有中文的数据重新进行编码来解决该问题。在Servlet4.0中的Cookie是支持中文存储的。
在这里插入图片描述
可以使用对中文进行转码处理
URLEncoder.encode(“content”,“code”)
将内容按照指定的编码方式做URL编码处理。URLDecoder.decode(“content” ,“code”)
将内容按照指定的编码方式做URL解码处理。

Cookie持久化和状态Cookie
状态Cookie:浏览器会缓存Cookie对象。浏览器关闭后Cookie对象销毁。
持久化Cookie:浏览器会对Cookie做持久化处理,基于文件形式保存在系统的指定目录中。在Windows10系统中为了安全问题不会显示Cookie中的内容。
当Cookie对象创建后默认为状态Cookie。可以使用Cookie对象下的cookie.setMaxAge(60)方法设置失效时间,单位为秒。一旦设置了失效时间,那么该Cookie为持久化Cookie,浏览器会将Cookie对象持久化到磁盘中。当失效时间到达后文件删除。

16 域对象

待编写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/368173.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【成品论文57页】2024美赛F题成品论文57页+每一小问配套代码数据

基于数据预测下的减少非法野生动物贸易研究 近年来&#xff0c;非法野生动物贸易每年涉及的金额高达 265 亿美元&#xff0c;被认为是全球第四大 非法贸易。本文基于收集的数据&#xff0c; 对非法野生动物贸易进行研究。 问题一&#xff0c;为了确定五年项目的研究对象我们利用…

Python Moviepy 视频编辑踩坑实录2:音频如何修改为单通道

一、前言&#xff1a; 通过上一篇博文的处理&#xff0c;《Python Moviepy 视频编辑踩坑实录1&#xff1a;谁动了我的音频比特率》我们成功的把音频文件的音频采样率&#xff0c;成功的转化为了目标值&#xff1a;16000&#xff0c;但是接下来遇到了&#xff0c;下面的问题&am…

给大家分好类!看下C++ STL标准模板库,有哪些模板容器类?

C STL&#xff08;Standard Template Library&#xff09;标准模板库&#xff0c;提供了多种容器&#xff0c;这些容器可用于存储和操作数据。 本文对一些常见的 C STL 容器做个简单分类&#xff0c;方便大家根据不同项目需要进行选择使用。 01 序列容器&#xff1a; std::v…

【SpringBoot】 热部署 ContextRefresher.refresh() 自定义配置一键刷新 ~

前言 在实际项目中&#xff0c;有时候我们希望能够在不重启应用的情况下动态修改Spring Boot的配置&#xff0c;以便更好地应对变化的需求。本文将探讨如何通过从数据库动态加载配置&#xff0c;并提供一键刷新的机制来实现这一目标。 背景 最近的项目中&#xff0c;我遇到了…

Deepin如何开启与配置SSH实现无公网ip远程连接

文章目录 前言1. 开启SSH服务2. Deppin安装Cpolar3. 配置ssh公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 前言 Deepin操作系统是一个基于Debian的Linux操作系统&#xff0c;专注于使用者对日常办公、学习、生活和娱乐的操作体验的极致&#xff0…

Bagging的随机森林;Boosting的AdaBoost和GBDT

集成学习应用实践 import numpy as np import os %matplotlib inline import matplotlib import matplotlib.pyplot as plt plt.rcParams[axes.labelsize] 14 plt.rcParams[xtick.labelsize] 12 plt.rcParams[ytick.labelsize] 12 import warnings warnings.filterwarnin…

java学习(面向对象基础)

一、继承(代码复用性&#xff09; 继承可以解决代码复用&#xff0c;让我们的编程更加靠近人类思维&#xff0c;当多个类存在相同的属性&#xff08;变量&#xff09;和方法时&#xff0c;可以从这些类中抽象出父类&#xff0c;在父类中定义这些相同的属性和方法&#xff0c;所…

实现无感刷新Token技术:.Net Web API与axios的完美结合

这是我之前分享在星球里面的课程&#xff0c;下面整理下&#xff0c;分享下这个无感刷新Token技术方案。 我们都知道Token是有设置有效期的&#xff0c;为了安全都不会设置过长的有效期&#xff1b;但设置有效期太短&#xff0c;又会导致经常需要重新登录。 这就需要无感刷新T…

Pyecharts炫酷散点图构建指南【第50篇—python:炫酷散点图】

文章目录 Pyecharts炫酷散点图构建指南引言安装Pyecharts基础散点图自定义散点图样式渐变散点图动态散点图高级标注散点图多系列散点图3D散点图时间轴散点图笛卡尔坐标系下的极坐标系散点图 总结&#xff1a; Pyecharts炫酷散点图构建指南 引言 在数据可视化领域&#xff0c;…

GPGPU面临的工程困境闲聊

作者&#xff1a;蒋志强 本人同意他人对我的文章引用&#xff0c;但请在引用时注明出处&#xff0c;谢谢&#xff0e;作者&#xff1a;蒋志强 0.前言 2007年作为GPGPU的工程界元年至今&#xff0c;已经发展了接近小二十年了。这个领域是如此的重要&#xff0c;几乎影响了工业…

MacBook Pro (15 英寸,2018) 本地体验运行 6B 大模型

接上篇 在 Mac 上加速 PyTorch 训练&#xff0c;准备完 MPS 环境之后&#xff0c;开始在本地体验 ChatGLM3-6B 模型。 一、下载本仓库&#xff1a; (base) markvivvMBP dev % git clone https://github.com/THUDM/ChatGLM3Cloning into ChatGLM3... remote: Enumerating obje…

[SWPUCTF 2021 新生赛]include

他让我们传入一个flag值 我们传入即可看到代码部分 传入一个php的伪类即可 得到经过Base64加密的flag&#xff0c;解密即可

jupyter notebook更改工作目录的2个细节

详细步骤参考知乎原文&#xff1a; 如何更改Jupyter Notebook的默认工作路径&#xff1f; - 知乎 (zhihu.com​​​​​​) 步骤4中需要删除 #符号和后面的空格&#xff01;一定要删除空格&#xff0c;否则会出现语法错误的报错 步骤5中&#xff0c;经过评论区提醒后&#xf…

酷开系统 | 酷开科技智慧AI带你领略神奇的世界

在这个科技日新月异的时代&#xff0c;AI已成为我们生活中不可或缺的一部分。它不仅改变了我们的生活方式&#xff0c;更让我们对未来充满期待。说起酷开系统中智慧AI的强大&#xff0c;着实让人叹为观止。无论是语音识别、数据整理还是语言处理&#xff0c;智慧AI都在不断地突…

【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]

阅读导航 引言一、C语言的输入与输出二、流是什么三、CIO流1. C标准IO流&#xff08;1&#xff09;istream&#xff08;2&#xff09;ostream&#xff08;3&#xff09;iostream&#xff08;4&#xff09;cin 和 cout 2. C文件IO流&#xff08;1&#xff09;ifstream&#xff0…

如何在Windows部署GoLand并通过SSH远程连接Linux服务器

文章目录 1. 安装配置GoLand2. 服务器开启SSH服务3. GoLand本地服务器远程连接测试4. 安装cpolar内网穿透远程访问服务器端4.1 服务器端安装cpolar4.2 创建远程连接公网地址 5. 使用固定TCP地址远程开发 本文主要介绍使用GoLand通过SSH远程连接服务器&#xff0c;并结合cpolar内…

1 初识JVM

JVM&#xff08;Java Virtual Machine&#xff09;&#xff0c;也就是 “Java虚拟机”。 对于第三点功能&#xff1a;即时编译 常见的JVM 默认安装在JDK中的虚拟机为HotSpot&#xff1a;可以用“java -version”进行查看

网络时间协议NTP工作模式

单播服务器/客户端模式 单播服务器/客户端模式运行在同步子网中层数较高层上。这种模式下,需要预先知道服务器的IP地址。 客户端:运行在客户端模式的主机(简称客户端)定期向服务器端发送报文,报文中的Mode字段设置为3(客户端模式)。当客户端接收到应答报文时,客户端会…

RHCE 综合项目-博客

目录 业务需求 一、准备工作 1、配置静态IP 2、修改主机名及hosts映射 3、开启防火墙 4、时间同步 5、配置免密ssh登录 二、环境搭建 1、Server-web端安装LAMP环境软件 2、Server-NFS-DNS端上传博客软件 3、Server-NFS-DNS端设置NFS共享 三、Server-web设置 1、挂…

新手从零开始学习数学建模论文写作(美赛论文临时抱佛脚篇)

本文记录于数学建模老哥视频的学习过程中。b站视频&#xff1a;http://【【零基础教程】老哥&#xff1a;数学建模算法、编程、写作和获奖指南全流程培训&#xff01;】https://www.bilibili.com/video/BV1kC4y1a7Ee?p50&vd_sourceff53a726c62f94eda5f615bd4a62c458 目录…
最新文章