Servlet(未完结~)

news2024/11/15 5:22:29

文章目录

  • 前言
  • 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.coloradmin.cn/o/1430161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle12c R2 ORA-12805 BUG导致生成巨大TRC文件问题处理

1、基础环境 操作系统&#xff1a;unix&solaris 11.3 数据库版本&#xff1a;oracle 12.2 CDB&PDB 数据库补丁信息 oracleQSSJJZDB2:~$ opatch lspatches 23333567; 27959048; 26187578;OCW Interim patch for 26187578 27674384;Database Apr 2018 Release Update :…

HarmonyOS--Stage模型

构建第一个ArkTS应用(Stage模型)-快速入门-入门 | 华为开发者联盟 (huawei.com) 鸿蒙开发两种模型 FA模型:早期使用,现在不主推。Stage模型:推荐HarmonyOS4和HarmonyOS NEXT版本开发从源码到编译到运行 @entry就是一个Ability类的一个模块。 编译期 源码中的所有Ability模…

常见API

文章目录 Math类1.1 概述1.2 常见方法 System类2.1 概述2.2 常见方法 Runtime3.1 概述3.2 常见方法 Object类4.1 概述4.2 常见方法 Objects类5.1 概述5.2 常见方法 BigInteger类6.1 引入6.2 概述6.3 常见方法6.4 底层存储方式&#xff1a; 7 BigDecimal类7.1 引入7.2 概述7.3 常…

《数据安全法》解读篇

《中华人民共和国数据安全法》 颁布时间&#xff1a;2021年6月10日实施时间&#xff1a;2021年9月1日《中华人民共和国数据安全法》整体架构图 数据安全的定义&#xff1a;是指通过采取必要措施&#xff0c;确保数据处于有效保护和合法利用的状态&#xff0c;以及具备保障持续…

STM32--USART串口(2)串口外设

一、USART简介 可配置数据位&#xff1a;不需要校验就是8位&#xff0c;需要校验就选9位&#xff1b; 停止位&#xff1a;决定了帧的间隔; STM32F103C8T6USART&#xff1a;USART1挂载在APB2总线上&#xff0c;USART2和USART3挂载在APB1总线上&#xff1b; 二、USART框图 TXE…

【数据分析】Excel中的常用函数公式总结

目录 0 引用方式0.1 相对引用0.2 绝对引用0.3 混合引用0.4 3D引用0.5 命名引用 1 基础函数1.1 加法、减法、乘法和除法1.2 平均数1.3 求和1.4 最大值和最小值 2 文本函数2.1 合并单元格内容2.2 查找2.3 替换 3 逻辑函数3.1 IF函数3.2 AND和OR函数3.3 IFERROR函数 4 统计函数4.1…

STM32 UART/USART与RTOS的多任务通信和同步机制设计

在STM32微控制器中&#xff0c;UART/USART与RTOS的多任务通信和同步机制设计可以通过操作系统提供的任务调度机制和各种同步原语&#xff08;例如信号量、邮箱、消息队列等&#xff09;来实现。在下面的解释中&#xff0c;我将介绍如何设计基于FreeRTOS的STM32多任务通信和同步…

【后端开发】正向代理与反向代理

正向代理 正向代理&#xff08;forward proxy&#xff09;&#xff1a;是一个位于客户端和目标服务器之间的服务器(代理服务器)&#xff0c;为了从目标服务器取得内容&#xff0c;客户端向代理服务器发送一个请求并指定目标&#xff0c;然后代理服务器向目标服务器转交请求并将…

Acwing第 141 场周赛

A题 签到模拟即可 B题 单独考虑每一个a[i]&#xff0c;如果i要是答案需要指针移动多少次&#xff0c;然后算完&#xff0c;排个序&#xff0c;指针移动最少的就是答案。 #include <bits/stdc.h> #define int long long #define rep(i,a,b) for(int i (a); i < (…

嵌入式学习第十八天

51单片机 51单片机是基于Intel的微处理器体系结构发展而来的。 主要由CPU、存储器、定时器/计数器、串行口等模块组成 优点&#xff1a;低功耗、低成本、高性能 开发工具&#xff1a; Keil uVision4&#xff08;支持汇编语言和C语言编程&#xff09; stc-isp-v6.92L&…

Ps:自动对齐图层

Ps菜单&#xff1a;编辑/自动对齐图层 Edit/Auto-Align Layers 自动对齐图层 Auto-Align Layers命令通过分析选中图层上的图像&#xff0c;识别出图像间的共同特征点&#xff08;如边缘、纹理或特定标记等&#xff09;&#xff0c;然后基于这些特征点变换&#xff08;移动、旋转…

030-安全开发-JS应用NodeJS指南原型链污染Express框架功能实现审计

030-安全开发-JS应用&NodeJS指南&原型链污染&Express框架&功能实现&审计 #知识点&#xff1a; 1、NodeJS-开发环境&功能实现 2、NodeJS-安全漏洞&案例分析 3、NodeJS-开发指南&特有漏洞 演示案例&#xff1a; ➢环境搭建-NodeJS-解析安装&…

坚持刷题|二叉树的前、中、后序遍历(递归迭代)

文章目录 题目思考递归实现迭代实现前序遍历后序遍历中序遍历 在前、中、后序的迭代遍历中&#xff0c;为什么都采用栈来模拟递归&#xff0c;而非队列&#xff1f; Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天刷&…

[SWPUCTF 2021 新生赛]ez_unserialize

根据下面的user_agent和Disallow可以判断这个是在robots.txt 我们看的出来这是一个反序列化需要我们adminadmin passwdctf construct 构造方法&#xff0c;当一个对象被创建时调用此方法&#xff0c;不过unserialize()时却不会被调用 destruct 析构方法&#xff0c;PHP将在对象…

分别用JavaScript,Java,PHP,C++实现桶排序的算法(附带源码)

桶排序是计数排序的升级版。它利用了函数的映射关系&#xff0c;高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效&#xff0c;我们需要做到这两点&#xff1a; 在额外空间充足的情况下&#xff0c;尽量增大桶的数量使用的映射函数能够将输入的 N 个数据均匀的分…

MySQL数据库②_库和表的操作_增删查改_备份恢复

目录 1. 创建数据库 2. 字符集和校验规则 2.1 默认的字符集和校验规则 2.2 支持的字符集校验规则 2.3 校验规则对数据库的影响 3. 库的查看&#xff0c;修改&#xff0c;删除 3.1 查看数据库 3.2 修改数据库 3.3 删除数据库 4. 库的备份和恢复 4.1 备份数据库 4.2 …

在虚拟机上搭建CentOS环境并配置静态IP

在虚拟机上搭建CentOS环境并配置静态IP 在进行Linux系统的学习和实践时&#xff0c;搭建一个本地的CentOS环境是一个非常好的方式。本文将介绍如何使用虚拟机&#xff08;VM&#xff09;搭建CentOS环境&#xff0c;并配置静态IP&#xff0c;以便更好地进行网络管理和测试。 步…

Java开发工具 IntelliJ IDEA 2023中文

IntelliJ IDEA 2023是一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;适用于多种编程语言&#xff0c;包括Java、Python、Kotlin等。它提供了许多特色功能&#xff0c;以提高开发效率和代码质量。 Java开发工具 IntelliJ IDEA 2023中文 以下是一些IntelliJ ID…

机器学习复习(4)——CNN算法

目录 数据增强方法 CNN图像分类数据集构建 导入数据集 定义trainer 超参数设置 数据增强 构建CNN网络 开始训练 模型测试 数据增强方法 # 一般情况下&#xff0c;我们不会在验证集和测试集上做数据扩增 # 我们只需要将图片裁剪成同样的大小并装换成Tensor就行 test_t…

跨平台开发:浅析uni-app及其他主流APP开发方式

随着智能手机的普及&#xff0c;移动应用程序&#xff08;APP&#xff09;的需求不断增长。开发一款优秀的APP&#xff0c;不仅需要考虑功能和用户体验&#xff0c;还需要选择一种适合的开发方式。随着技术的发展&#xff0c;目前有多种主流的APP开发方式可供选择&#xff0c;其…