详解Servlet API
目录
前言
HttpServlet
HttpServletRequest
代码实例
打印请求信息
通过URL中的queryString进行传递。
通过post请求的body,使用form表单传递
通过POST 请求中的 body 按照 JSON 的格式进行传递
HttpServletResponse
核心方法代码实例
设置状态码
自动刷新
重定向
总结
前言
Servlet的API是非常多的,但是我们只需要重点掌握三个类即可!!!
- HttpServlet
- HttpServletRequest
- HttpServletResponse
HttpServlet
我们在写Servlet代码的时候,第一步都是先创建一个类,然后让这个类去继承HttpServlet,并重写其中的某些方法。那么我们就需要知道,HttpServlet这个类中都有那些方法,都是干啥的。
方法名称 | 调用时机 |
---|---|
init | 在HttpServlet实例化之后被调用一次 |
destroy | 在HttpServlet实例之后不再使用的时候调用一次 |
service | 在收到HTTP请求时调用 |
doGet | 在收到get请求的时候由service调用 |
doPost | 在收到post请求的时候由service调用 |
doPut/doDlete/...... | 在收到其他请求时由service调用 |
@WebServlet("/hello1")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("hello world");resp.getWriter().write("hello");}
}
init():
HttpServlet被实例化之后,会调用一次,使用这个方法来做一些初始化的工作。
需要注意的是,init方法不是被实例化的时候调用,而是首次收到请求的时候调用。
这个请求就会触发HelloServlet类的doGet方法的执行。但是会在执行doGet方法之前,先调用init方法。
init方法的调用时机:
只会在首次收到请求的时候调用一次,等下次再次收到请求,就不会再调用init方法了。也就是说,init方法在Servlet整个生命周期中,只会调用一次。
destroy():
这个方法时在HttpServlet实例销毁之前调用一次,来做一些收尾工作。
这个方法需要注意的是,如果通过Servlet的管理端口8005来停止Servlet服务,此时的destroy方法就会执行,如果要是通过直接杀死进程的方式来停止Servlet服务,那么destroy就不会执行。
service():
service方法是当收到一个路径匹配的请求时,就会执行一次。
我们的doGet/doPost/doDelete....等方法,都是在service方法中进行调用的。
所以我们在重写方法的时候,一般不会去重写service方法,而是重写doXXX方法。
一道面试题:Servlet的生命周期?
上述方法的调用时机,就成为Servlet的生命周期。
HttpServletRequest
这个类对应一个HTTP请求,一个HTTP请求中有什么,这个类中就有什么。
这个类中的方法是比较多的,但是都比较清晰。
方法 | 描述 |
String getProtocol() | 返回请求协议的名称和版本。 |
String getMethod() | 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。 |
String getRequestURI() | 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请 求的 URL 的一部分。 |
String getContextPath() | 返回指示请求上下文的请求 URI 部分。 |
String getQueryString() | 返回包含在路径后的请求 URL 中的查询字符串。 |
Enumeration getParameterNames() | 返回一个 String 对象的枚举,包含在该请求中包含的参数的名 称。 |
String getParameter(String name) | 以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。 |
String[] getParameterValues(String name) | 返回一个字符串对象的数组,包含所有给定的请求参数的值,如 果参数不存在则返回 null。 |
Enumeration getHeaderNames() | 返回一个枚举,包含在该请求中包含的所有的头名。 |
String getHeader(String name) | 以字符串形式返回指定的请求头的值。 |
String getCharacterEncoding() | 返回请求主体中使用的字符编码的名称。 |
String getContentType() | 返回请求主体的 MIME 类型,如果不知道类型则返回 null。 |
int getContentLength() | 以字节为单位返回请求主体的长度,并提供输入流,或者如果长 度未知则返回 -1。 |
InputStream getInputStream() | 用于读取请求的 body 内容. 返回一个 InputStream 对象. |
代码实例
打印请求信息
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.util.Enumeration;@WebServlet("/ShowRequest")
public class ShowRequest extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {StringBuilder result = new StringBuilder(); //使用StringBuilder来显示请求的内容result.append(req.getProtocol()); //请求的协议和版本result.append("<br>");result.append(req.getMethod()); //请求的方法result.append("<br>");result.append(req.getRequestURI()); //请求的uri 唯一资源标识符result.append("<br>");result.append(req.getQueryString()); //请求的queryStringresult.append("<br>");result.append(req.getContextPath()); //请求URL的上下文路径result.append("<br>");result.append("=========================<br>");Enumeration<String> headerNames = req.getHeaderNames(); //请求的header头名,返回值是一个枚举类型while (headerNames.hasMoreElements()) { //遍历这个headerNames枚举对象//header中是一个个的键值对String headerName = headerNames.nextElement(); //获取到header中键值对的键String headerValue = req.getHeader(headerName); //通过键值对中的键获取到对应的值result.append(headerName+": " + headerValue+"<br>");}//设置响应到浏览器的类型和字符格式resp.setContentType("text/html;charset=utf8");//把响应写会浏览器resp.getWriter().write(result.toString());}
}
上述在进行append的时候,我们并不是使用的\n来表示换行,因为我们返回的String在浏览器页面上是以HTML的格式进行解析的,所以我们要想换行,就得使用HTML中的换行标签。
Enumeration<String> headerNames = req.getHeaderNames(); //请求的header头名,返回值是一个枚举类型while (headerNames.hasMoreElements()) { //遍历这个headerNames枚举对象//header中是一个个的键值对String headerName = headerNames.nextElement(); //获取到header中键值对的键String headerValue = req.getHeader(headerName); //通过键值对中的键获取到对应的值result.append(headerName+": " + headerValue+"<br>");}
上述代码则是把整个header中内容全部拼接到stringbuilder中
下面来看看运行结果。
接下来介绍下一组API
获取get请求中的值
前端先后端传递值的方法有多种。
通过URL中的queryString进行传递。
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;@WebServlet("/getParameter")
public class getParameter extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//前端通过URL中的query String 来传递username和password两个属性String username = req.getParameter("username");if (username == null) {System.out.println("username 这个key在queryString中不存在");}String password = req.getParameter("password");if (password == null) {System.out.println("password 这个key在queryString中不存在");}System.out.println("username " + username + " password" + password);resp.getWriter().write("ok");}
}
我们知道QueryString是键值对的方式来向后端传递数据的。
比如前端通过QueryString的方式传递username和password两个属性。我们要获取这两个属性中对于的value。就可以通过getParameter()方法来获取键对应的值。
下面我们运行程序,来看效果。
我们在URL中通过QueryString的方法向后端传递了两个键值对,分别是username=zhangsan,
password=123。
可以看出后端在控制台成功的输出了这两个键对应的值。
通过post请求的body,使用form表单传递
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;@WebServlet("/getParameter")
public class getParameter extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf8");//前端通过body form表单 传递username和passwordString username = req.getParameter("username");if (username == null) {System.out.println("username 这个key在queryString中不存在");}String password = req.getParameter("password");if (password == null) {System.out.println("password 这个key在queryString中不存在");}System.out.println("username " + username + " password" + password);resp.getWriter().write("ok");}
}
我们通过Postman来构造通过form表单传递数据的请求。
可以看出服务器成功的返回了一个ok。这个OK并不能代表什么,我们来看看服务器控制台的输出。
服务器也成功的打印出来了对应的value。
通过POST 请求中的 body 按照 JSON 的格式进行传递
我们需要引入 Jackson 这个库, 进行 JSON 解析。
1:在Maven中央仓库搜索Jackson,选择Jackson Databind
然后选择版本2.15.0
2:把中央仓库中的依赖配置添加到 pom.xml 中, 形如
<!--Jackson依赖用来前端通过JSON发送数据 后端进行JSON解析--><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.0</version></dependency>
然后就可以编写代码了。
import com.fasterxml.jackson.databind.ObjectMapper;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;class User {public String username;public String password;
}
@WebServlet("/JSON")
public class JsonServlet extends HttpServlet {
// 创建 ObjectMapper 对象. 这个是 Jackson 中的核心类public ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过post请求的body传递过来一个JSON格式请求的字符串
// 通过 readValue 方法把 body 这个字符串转成 User对象User user = objectMapper.readValue(req.getInputStream(), User.class);System.out.println("username "+ user.username +", password"+user.password);resp.getWriter().write("ok");}
}
可以看出我们代码中用多了一个User类,这个类用于解析生成后的JSON对象,这个类中的属性名字要和传递过来的key对应。
User user = objectMapper.readValue(req.getInputStream(), User.class);
通过反射的机制把body中的key对应的value全部放在User对象中去,这就是为什么User类的属性和类型、名称都要和body中的key保持一致的原因。
然后就可以通过user对象来获取到username和password两个属性的value了。
下面我们运行代码看效果:
我们通过Postman构造了JSON的请求并发送,服务器也成功的响应了。
接下来我们看服务器控制台输出的内容。
服务器也是成功的获取到了key对应的value。
HttpServletResponse
这个类是一个HTTP的响应,一个响应中有什么,这个类中就有什么。
Servlet中的doXXX方法就是根据请求计算响应,然后把响应的数据写回到HttpServletResponse这个对象中。
然后Tomcat会把这个对象按照HTTP协议相应的格式,转成一个字符串,并通过socket写回给浏览器。
方法 | 描述 |
void setStatus(int sc) | 为该响应设置状态码。 |
void setHeader(String name, String value) | 设置一个带有给定的名称和值的 header. 如果 name 已经存在, 则覆盖旧的值. |
void addHeader(String name, String value) | 添加一个带有给定的名称和值的 header. 如果 name 已经存在, 不覆盖旧的值, 并列添加新的键值对 |
void setContentType(String type) | 设置被发送到客户端的响应的内容类型。 |
void setCharacterEncoding(String charset) | 设置被发送到客户端的响应的字符编码(MIME 字符集)例如, UTF-8。 |
void sendRedirect(String location) | 使用指定的重定向位置 URL 发送临时重定向响应到客户端。 |
PrintWriter getWriter() | 用于往 body 中写入文本格式数据. |
OutputStream getOutputStream() | 用于往 body 中写入二进制格式数据. |
核心方法代码实例
设置状态码
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;@WebServlet("/status")
public class Status extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setStatus(200); //给响应设置状态码resp.setContentType("text/html; charset=utf8");resp.getWriter().write("返回设置状态码200");}
}
服务器返回数据,下面我们通过fiddler来抓包看看。
可以看到,状态码确实设置为了200。
自动刷新
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;@WebServlet("/Refresh")
public class RefreshServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//在响应里面设置自动刷新字段 1秒刷新一次resp.setHeader("refresh","1");resp.getWriter().write("time"+ System.currentTimeMillis()); //记录当前时间戳}
}
此时就会每隔一秒刷新一次页面。
重定向
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;@WebServlet("/redirect")
public class Redirect extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//当用户访问这个路径的时候,自动重定向到百度的主页resp.setStatus(302); //设置重定向状态码302resp.setHeader("location","https://www.baidu.com");}
}
当我们在地址栏输出URL时,就会重定向到百度的页面。
总结
以上就是Servlet API的讲解,不足之处,希望各位大佬多多指教。
相关文章:
详解Servlet API
目录 前言 HttpServlet HttpServletRequest 代码实例 打印请求信息 通过URL中的queryString进行传递。 通过post请求的body,使用form表单传递 通过POST 请求中的 body 按照 JSON 的格式进行传递 HttpServletResponse 核心方法代码实例 设置状态码 自动刷…...
【小白教程】Docker安装使用教程,以及常用命令!
【小白教程】Docker安装使用教程,以及常用命令! - 带你薅羊毛最近调试Docker内容,顺手记录一下,我常用的几个命令!这里总结一下,方便自己也同时方便大家使用! 内容慢慢完善更新!如有…...
TypeScript基础
TS编译运行 ts不是在终端运行,是一门中间语言,最终编译为js运行。 手动编译 // 1. ts编译为js npm i -g typescript // 查看版本 tsc -v// 2. ts直接运行,主要用来查看是否报错 npm i -g ts-node // 查看版本 ts-node -v1.手动编译ts代码 …...
QML学习二:Doxygen为qml工程生成代码文档
效果如下: 设置后能够支持.js和.qml文档。 QML学习二:Doxygen为工程生成注释文档 前言一、安装doxyqml二、Doxygen设置1.文档目录设置2.文档目录设置三、添加注释总结前言 好的代码必须配一个好的文档说明,方便以后维护以及学习。 前提条件: 1.安装好了Doxygen代码生成工…...
Vue 有哪些经典面试题?
前言 下面总结了vue的一些经典的面试题,希望对正在找工作面试的小伙伴们提供一些帮助,我们废话少说直接进入整体、 简述一下什么是MVVM模型 MVVM,是Model-View-ViewModel的简写,其本质是MVC模型的升级版。其中 Model 代表数据模…...
pandas速学-DataFrame
一、理解DataFrame 他是一个表格结构:DataFrame 是一个表格型的数据结构 他是有序的,不同值类型:它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。 他可以被看做一个由series组成的…...
在任务与执行策略之间的隐性耦合
我们已经知道, Executor 框架可以将任务的提交与任务的执行策略解耦开来。就像许多对复杂过程的解耦操作那样,这种论断多少有些言过其实了。虽然Executor 框架为制定和修改执行策略都提供了相当大的灵活性,但并非所有的任务都能适用所有的执行…...
Spring Cloud Alibaba Nacos 构建配置中心
构建配置中心 新建命名空间 登录 Nacos 面板,依次点击左侧菜单栏【命名空间→新建命名空间】、填写命名空间名和描述信息,点击【确定】: 新建配置文件 依次点击左侧菜单栏【配置管理→配置列表】、切换到指定命名空间【此处为 shop】、点击…...
华为OD机试真题 Java 实现【猴子爬山】【2023 B卷 100分】,附详细解题思路
一、题目描述 一天一只顽猴想去从山脚爬到山顶,途中经过一个有个N个台阶的阶梯,但是这猴子有一个习惯: 每一次只能跳1步或跳3步,试问猴子通过这个阶梯有多少种不同的跳跃方式? 二、输入描述 输入只有一个整数N(0<N<=50)此阶梯有多少个阶梯。 三、输出描述 输…...
【19JavaScript for 循环】JavaScript for 循环:掌握重复执行的关键
JavaScript for 循环 在JavaScript中,for循环是一种常用的循环结构,它允许您重复执行一段代码,达到循环的目的。 基本语法 for (initialization; condition; iteration) {// 要执行的代码}for循环由以下几个关键部分组成: init…...
MySQL学习(联结,组合查询,全文本搜索)
联结 SQL最强大的功能之一就是能在数据检索查询的执行中联结表; 关系表 为什么要使用关系表? 使用关系表可以储存数据不重复,从而不浪费时间和空间;如果有数据信息变动,只需更新一个表中的单个记录,相关…...
Nautilus Chain:独特且纯粹的创新型 Layer3
以 Layer3 架构为主要特点的模块化公链 Nautilus Chain 即将在近期上线主网,这也进一步引发了行业关于 Layer3 的讨论。 实际上,在2022年以太坊的创始人 Vitalik 提出了三大目标:Layer2 用于扩展,Layer3 用于定制功能,…...
十六、立方体贴图(天空盒)
第一部分 概念: 1) 引用 OpenGL ES 立方体贴图本质上还是纹理映射,是一种 3D 纹理映射。立方体贴图所使的纹理称为立方图纹理,它是由 6 个单独的 2D 纹理组成,每个 2D 纹理是立方图的一个面。 立方图纹理的采样通过一个 3D 向量…...
UniAD:实现多类别异常检测的统一模型
来源:投稿 作者:Mr.Eraser 编辑:学姐 论文标题:用于多类异常检测的统一模型 论文链接:https://arxiv.org/abs/2206.03687 论文贡献: 提出UniAD,它以一个统一框架完成了多个类别的异常检测。 …...
Java 面试 | tcp ip http https(2023版)
文章目录 HTTP&HTTPS1、Http和Https的区别?2、什么是对称加密与非对称加密3、客户端不断进行请求链接会怎样?DDos(Distributed Denial of Service)攻击?4、GET 与 POST 的区别?5、什么是 HTTP 协议无状态协议?怎么解决Http协议无状态协议?6、Session、Cookie 与 Appl…...
全志V3S嵌入式驱动开发(音频输出和音频录制)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 之前在芯片公司的时候,基本没有看过音频这一块,只知道有个alsa框架这么个知识点。要驱动音频,需要两部分&#…...
使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED
使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED 开发环境HelloWorld!闪烁 LED 灯代码 由于比较简单就放在一起写了 开发环境 软件:Thonny HelloWorld! 要想使串口打印HelloWorld! 只需要一行代码 print("HelloWorld!")保…...
康耐视In-Sight2800相机的使用
In-Sight2800相机注册分类程序 一、登录相机 二、图像导入 IS相机支持拍摄图像和从文件中导入图像 如选择从文件中导入图像,文件夹选择位置在页面左下方,如下图 三、注册分类器 在检查模块注册分类器,注册图像需要一张一张去学习&#x…...
驱动开发:内核封装WFP防火墙入门
WFP框架是微软推出来替代TDIHOOK传输层驱动接口网络通信的方案,其默认被设计为分层结构,该框架分别提供了用户态与内核态相同的AIP函数,在两种模式下均可以开发防火墙产品,以下代码我实现了一个简单的驱动过滤防火墙。 WFP 框架分…...
python+vue校园快递代取系统的设计与实现3i0v9
开发语言:Python 框架:django/flask Python版本:python3.7.7 数据库:mysql 数据库工具:Navicat 开发软件:PyCharm 本系统名为“基于vue快递代取系统”,系统主要适用于毕业设计,不…...
C 语言详细教程
目录 第一章 C语言基础知识 第二章 数据类型、运算符和表达式 第三章 结构化程序设计 第四章 数组 第五章 函数 第六章 指针 第七章 结构体类型和自定义类型 第八章 编译预处理 第九章 文件 说明:本教程中的代码除一二三个之外,都在https://ligh…...
函数重载与缺省参数
目录 一 缺省参数 缺省参数分半缺省和全缺省。 2,半缺省参数 3,全缺省参数 4.缺省参数的注意事项 二 函数重载 2 .函数重载参数类型不同强调 三 函数名修饰规则 一 缺省参数 1.缺省参数特性(备胎) 缺省参数是指我们定义函数时有给缺省值的参数…...
线程引入的开销
单线程程序既不存在线程调度,也不存在同步开销,而且不需要使用锁来保证数据结构的一致性。在多个线程的调度和协调过程中都需要一定的性能开销:对于为了提升性能而引入的线程来说,并行带来的性能提升必须超过并发导致的开销。 上下…...
学生成绩管理系统
基于springboot vue实现的学生成绩管理系统 主要模块: 1)学生模块:我的成绩、成绩统计、申述管理、修改密码 2)教师模块:任务管理、对学生班级任务安排、班级学生的成绩查看、申述管理 3)管理员模块&…...
什么是关系模型? 关系模型的基本概念
关系模型由IBM公司研究员Edgar Frank Codd于1970年发表的论文中提出,经过多年的发展,已经成为目前最常用、最重要的模型之一。 在关系模型中有一些基本的概念,具体如下。 (1)关系(Relation)。关系一词与数学领域有关,它是集合基…...
shell编程-02-变量作用域
作用域 局部变量:变量只能在函数内部使用 全局变量:变量可以在当前 Shell 进程中使用 环境变量:变量还可以在子进程中使用 局部变量 函数中定义的变量默认是全局变量,在定义时加上local命令,此时该变量就成了局部变…...
C++服务器框架开发6——日志系统LogFormatter/size_t学习
该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。 其教学视频见:[C高级教程]从零开始开发服务器框架(sylar) 上一篇:C服务器框架开发5——日志系统LogAppender/IO类“3种stream”/双感叹号 C服务器框架开发6——日志系统logFormatter/size_t学…...
MYSQL实战45讲笔记--深入浅出索引
深入浅出索引 索引的常见模型 索引模型:是哈希表、有序数组和搜索树。 区别: 哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。哈希的思…...
SpringCloudAlibaba:分布式事务之Seata学习
目录 一、分布式事务基础 (一)事务 (二)本地事务 (三)分布式事务 二、Seata概述 1.Seata 的架构包含: 2.其工作原理为: 3.如果需要在 Spring Boot 应用中使用 Seata 进行分布式事务管理,主要步骤为…...
【MySQL数据库 | 第四篇】SQL通用语法及分类
目录 🤔SQL通用语法: 😊语句: 😊注释: 🤔SQL语句分类: 😊1.DDL语句: 😊2.DML语句: 😊3.DQL语言: &…...
ps网站首页设计/电脑培训网
国内有科技企业公布了EUV光刻机专利,热闹了几天,然而仔细想来,这专利恐怕对于中国光刻机产业影响有限,离量产依然很远,就如此前的石墨烯专利一样。EUV光刻机可谓是科技行业的皇冠,它集中了全球诸多科技的精…...
东莞企业网站建设价格/企业网络营销策略分析案例
关于cmake的安装,CMakeLists.txt的语法规则,CMakeLists.txt的各种配置选项等复杂而专业的知识,限于本人能力,这里不再说明演示使用glibc2.0库一 项目目录laolanglaolang-Lenovo-G470:~/code/cmake/eclipse/HelloCMake$ tree.├──…...
上海专业网站建设报价/舆情系统
SVG总结的 svg 知识,方便以后复习查看 ~ ~SVG是什么SVG 表示可缩放矢量图SVG 用来定义WEB上使用的矢量图SVG 用XML格式定义矢量图SVG 在缩放时不会损失任何的图片质量SVG 文件里的所有元素和属性都可以运用动画效果SVG 是W3C推荐的SVG 集成了其它W3C标准,…...
大连地区建设网站/百度人工客服电话24小时
JSP 脚本元素 JSP脚本元素用来插入Java代码,这些Java代码将出现在由当前JSP页面生成的Servlet中。脚本元素有三种格式: 表达式格式<% expression %>:计算表达式并输出其结果。 Scriptlet格式<% code %&…...
租车网站 模板/软文媒体
1.主要的子类: 1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作 2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用 3) StringBufferInputStream&…...
推广平台软件/南宁seo推广优化
一、原型 任何对象都有一个原型对象,这个原型对象由对象的内置属性_proto_指向它的构造函数的prototype指向的对象 即任何对象都是由一个构造函数创建的,但是,不是每一个对象都有prototype,只有方法才有prototype。 function Per…...