【学习笔记】手写 Tomcat 八
目录
一、NIO
1. 创建 Tomcat NIO 类
2. 启动 Tomcat
3. 测试
二、解析请求信息
三、响应数据
创建响应类
修改调用的响应类
四、完整代码
五、测试
六、总结
七、获取全部用户的功能
POJO
生成 POJO
1. 在 Dao 层定义接口
2. 获取用户数据
3. 在 Service 层定义接口
4. Service 层的实现方法
5. 创建 Servlet
6. 测试
八、作业
优化NIO
一、NIO
Non-Blocking I/O,非阻塞IO。我们之前使用的是 BIO 阻塞IO
NIO 是同步非阻塞的,服务器的实现模式是一个线程处理多个连接
关于 NIO ,可以看看这位博主写的文章 Java NIO 详解-CSDN博客
1. 创建 Tomcat NIO 类
package com.shao.net;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class TomcatNIO {public TomcatNIO() {// 1. 创建通信管道try {ServerSocketChannel ssc = ServerSocketChannel.open();// 2. 绑定端口ssc.bind(new InetSocketAddress(8080));// 3. 配置非阻塞通信管道ssc.configureBlocking(false);// 4. 创建一个选择器Selector selector = Selector.open();// 5. 将通信管道注册到选择器上,监听客户端连接请求的事件ssc.register(selector, SelectionKey.OP_ACCEPT);// 循环监听客户端请求并处理相应事件while (true) {System.out.println("等待连接...");// 6. 从 selectors 中选择并返回已就绪的通道数int number = selector.select();if (number == 0) continue;// 7. 这些 SelectionKey 对象代表了就绪的通道及其相应的注册事件。Iterator<SelectionKey> it = selector.selectedKeys().iterator();while (it.hasNext()) {SelectionKey key = it.next();// 8. 判断就绪事件类型if (key.isAcceptable()) {System.out.println("有客户端连接了...");// 1. 接受新的客户端连接SocketChannel sc = ssc.accept();// 2. 设置连接的通道为非阻塞模式sc.configureBlocking(false);// 3. 将新连接的通道注册到选择器上,监听读事件sc.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接成功");} else if (key.isReadable()) {// 读事件// 1. 创建缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);// 2. 将 key 关联的通道 (channel) 转换为 SocketChannel 类型。转换后的 socketChannel 可用于进行网络读写操作。SocketChannel socketChannel = (SocketChannel) key.channel();// 3. 读取数据到缓冲区int read = socketChannel.read(buffer);if (read > 0) {// 获取缓冲区的数据byte[] array = buffer.array();// 转成字符串String msg = new String(array, 0, read);// 将请求信息进行 URL 解码,然后使用 UTF-8 进行编码String message = URLDecoder.decode(msg, "UTF-8");System.out.println("客户端发送了:" + message);// 清空缓冲区buffer.clear();// 响应数据String content = "OK";String HttpResponse = "HTTP/1.1 200 OK\r\n" +"Content-Type: text/html;charset=utf-8\r\n" +"Content-Length: " + content.getBytes().length + "\r\n" +"\r\n" +content;// 写入到缓冲区buffer.put(HttpResponse.getBytes());// 将缓冲区的界限设置为当前位置,然后再把当前位置重置为0buffer.flip();// 响应数据到客户端socketChannel.write(buffer);} else if (read == -1) {// 关闭通道socketChannel.close();// 取消 key 关联的通道在 selector 上的注册key.cancel();}}// 移除已经处理的 SelectionKey,防止下次循环再处理这个键it.remove();}}} catch (IOException e) {e.printStackTrace();}}
}
2. 启动 Tomcat
在入口类启动 NIO 的 Tomcat
3. 测试
二、解析请求信息
因为请求信息和之前是一样的,所以可以使用 HttpRequest 解析类
三、响应数据
创建响应类
因为响应数据的方式不一样,所以需要创建一个 NIO 方式的响应类
package com.shao.net;import com.shao.Servlet.BaseServlet;
import com.shao.Utils.ServletByAnnoUtil;import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;public class HttpResponseNIO {/*** 连接的通道*/private SocketChannel sc;/*** 缓冲区*/private ByteBuffer buffer;/*** 解析类的对象*/private HttpRequest httpRequest;public HttpResponseNIO(SocketChannel sc, ByteBuffer buffer, HttpRequest httpRequest) {this.sc = sc;this.buffer = buffer;this.httpRequest = httpRequest;}public void response(String filePath) {//判断请求的是否为静态文件if (StaticResourceHandler.isLikelyStaticResource(httpRequest.getRequestModule())) {// 获取静态资源一般是 GET 请求方法if (httpRequest.getRequestMethod().equals("GET")) {// 响应静态资源responseStaticResource(filePath);}} else {// 处理动态请求System.out.println("请求动态资源");// 获取 Servlet 对象,参数是请求的模块名BaseServlet servlet = ServletByAnnoUtil.getServletClass(httpRequest.getRequestModule());// 如果没有找到对应的 Servlet ,返回 404if (servlet == null) {responseStaticResource("webs/pages/not_Found404.html");return;}// 调用 service 方法servlet.service(httpRequest, this);}}/*** 响应静态资源*/private void responseStaticResource(String filePath) {// 读取文件byte[] fileContents = StaticResourceHandler.getFileContents(filePath);// 判断文件是否存在,不存在则返回 404 的页面if (fileContents == null) {try {FileInputStream fis = new FileInputStream("webs/pages/not_Found404.html");fileContents = new byte[fis.available()];fis.read(fileContents);fis.close();} catch (Exception e) {e.printStackTrace();}}// 响应协议String protocol = httpRequest.getRequestProtocol();// 文件媒体类型String fileMimeType = StaticResourceHandler.getFileMimeType(filePath);// 清空缓冲区buffer.clear();// 写入数据到缓冲区buffer.put((protocol + " 200 OK\r\n").getBytes());buffer.put(("Content-Type: " + fileMimeType + "\r\n").getBytes());buffer.put(("Content-Length: " + fileContents.length + "\r\n").getBytes());buffer.put(("\r\n").getBytes());buffer.put(fileContents);// 将缓冲区的界限设置为当前位置,然后再把当前位置重置为0buffer.flip();try {// 响应数据到客户端sc.write(buffer);System.out.println("响应成功");} catch (IOException e) {e.printStackTrace();}}public void send(byte[] content) {// 获取请求协议String protocol = httpRequest.getRequestProtocol();// 清空缓冲区buffer.clear();// 往缓冲区写入数据buffer.put((protocol + " 200 OK\r\n").getBytes());buffer.put(("Content-Type: text/html;charset=utf-8\r\n").getBytes());buffer.put(("Content-Length: " + content.length + "\r\n").getBytes());buffer.put("\r\n".getBytes());buffer.put(content);// 设置缓冲区的界限为当前指针的位置,然后把指针指向缓冲区的起始位置buffer.flip();try {// 响应数据sc.write(buffer);System.out.println("响应成功");} catch (IOException e) {e.printStackTrace();}}
}
修改调用的响应类
四、完整代码
package com.shao.net;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class TomcatNIO {public TomcatNIO() {// 1. 创建通信管道try {ServerSocketChannel ssc = ServerSocketChannel.open();// 2. 绑定端口ssc.bind(new InetSocketAddress(8080));// 3. 配置非阻塞通信管道ssc.configureBlocking(false);// 4. 创建一个选择器Selector selector = Selector.open();// 5. 将通信管道注册到选择器上,监听客户端连接请求的事件ssc.register(selector, SelectionKey.OP_ACCEPT);// 循环监听客户端请求并处理相应事件while (true) {System.out.println("等待连接...");// 6. 从 selectors 中选择并返回已就绪的通道数int number = selector.select();if (number == 0) continue;// 7. 这些 SelectionKey 对象代表了就绪的通道及其相应的注册事件。Iterator<SelectionKey> it = selector.selectedKeys().iterator();while (it.hasNext()) {SelectionKey key = it.next();// 8. 判断就绪事件类型if (key.isAcceptable()) {System.out.println("有客户端连接了...");// 1. 接受新的客户端连接SocketChannel sc = ssc.accept();// 2. 设置连接的通道为非阻塞模式sc.configureBlocking(false);// 3. 将新连接的通道注册到选择器上,监听读事件sc.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接成功");} else if (key.isReadable()) {// 读事件// 1. 创建缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);// 2. 将 key 关联的通道 (channel) 转换为 SocketChannel 类型。转换后的 socketChannel 可用于进行网络读写操作。SocketChannel socketChannel = (SocketChannel) key.channel();// 3. 读取数据到缓冲区int read = socketChannel.read(buffer);if (read > 0) {// 获取缓冲区的数据byte[] array = buffer.array();// 转成字符串String msg = new String(array, 0, read);// 将请求信息进行 URL 解码,然后使用 UTF-8 进行编码String message = URLDecoder.decode(msg, "UTF-8");// 调用 HttpRequest 类解析请求信息HttpRequest httpRequest = new HttpRequest(message);// 拼接请求的静态资源的路径String filePath = "/webs" + httpRequest.getRequestModule();// 创建响应对象HttpResponseNIO httpResponseNIO = new HttpResponseNIO(socketChannel, buffer, httpRequest);// 响应数据到客户端httpResponseNIO.response(filePath);} else if (read == -1) {// 关闭通信通道socketChannel.close();// 取消 key 关联的通道在 selector 上的注册key.cancel();}}// 9. 移除已经处理的 SelectionKey,防止下次循环再处理这个键it.remove();}}} catch (IOException e) {e.printStackTrace();}}
}
五、测试
六、总结
七、获取全部用户的功能
POJO
因为获取的用户数据需要封装,需要一个类和数据库的字段一一对应,这就是 对象关系映射(ORM) ,这个类可以称为 POJO
生成 POJO
1. 在 Dao 层定义接口
2. 获取用户数据
public ArrayList<Users> GetAllUser() {Connection connection = null;PreparedStatement pstmt = null;ResultSet resultSet = null;ArrayList<Users> users = new ArrayList<>();try {// 3. 从连接池获取一个数据库连接connection = DBConnectPool.getInstance().getConnection();// 4. 获取可执行对象// 定义 SQL 语句String SQL = "select id, account, name, password, money from train.users";pstmt = connection.prepareStatement(SQL);// 5. 执行sql语句,获取结果集resultSet = pstmt.executeQuery();// 6. 结果处理while (resultSet.next()) {// 获取一行数据,封装到对象中Users user = new Users();user.setId(resultSet.getLong("id"));user.setAccount(resultSet.getString("account"));user.setName(resultSet.getString("name"));user.setPassword(resultSet.getString("password"));user.setMoney(resultSet.getDouble("money"));// 添加到集合中users.add(user);}} catch (SQLException e) {e.printStackTrace();} finally {DBConnectPool.getInstance().releaseConnection(connection);DBConnectUtil.releaseSource(pstmt, resultSet);}return users;}
3. 在 Service 层定义接口
4. Service 层的实现方法
public responseDTO GetAllUser() {// 调用 Dao 层获取数据ArrayList<Users> users = userDao.GetAllUser();return new responseDTO(200, users, "获取成功", users.size());}
5. 创建 Servlet
package com.shao.Servlet;import com.alibaba.fastjson2.JSON;
import com.shao.Annotation.MyServlet;
import com.shao.Service.ServiceFactory;
import com.shao.Service.UserService;
import com.shao.Utils.responseDTO;
import com.shao.net.HttpRequest;
import com.shao.net.HttpResponseNIO;@MyServlet("/GetAllUser")
public class GetAllUserServlet extends BaseServlet {responseDTO responseDTO = null;@Overridevoid doGet(HttpRequest httpRequest, HttpResponseNIO httpResponse) {// 获取实例UserService userService = ServiceFactory.getUserService();// 调用获取所有用户的方法responseDTO = userService.GetAllUser();// 响应数据httpResponse.send(JSON.toJSONBytes(responseDTO));}@Overridevoid doPost(HttpRequest httpRequest, HttpResponseNIO httpResponse) {responseDTO = new responseDTO(400, null, "不支持POST提交方法");httpResponse.send(JSON.toJSONBytes(responseDTO));}
}
6. 测试
八、作业
优化NIO
在高并发的场景下,现在的NIO配置无法及时处理,如何解决?
如果客户端发送的数据很多,如何分批次读取数据?
到目前为止,我们学习了 BIO和NIO网络通信模块、HttpRequest、HttpResponse、线程池、任务队列、线程任务对象、Servlet、业务逻辑处理 Service 、Dao 、数据库连接池、POJO、DTO、注解等。这些内容组合起来就是一个简单的框架
相关文章:
【学习笔记】手写 Tomcat 八
目录 一、NIO 1. 创建 Tomcat NIO 类 2. 启动 Tomcat 3. 测试 二、解析请求信息 三、响应数据 创建响应类 修改调用的响应类 四、完整代码 五、测试 六、总结 七、获取全部用户的功能 POJO 生成 POJO 1. 在 Dao 层定义接口 2. 获取用户数据 3. 在 Service 层定…...
24年九月份生活随笔
九月份最后一天,烈士纪念日。 上午看了一会儿直播,庄重的仪式,铭记先辈为新中国抛头颅洒热血,当今盛世,如您所愿。 郑州马拉松官方通告,今天十点公布直通,中签,候补结果。 看完直…...
[含文档+PPT+源码等]精品大数据项目-基于Django实现的高校图书馆智能推送系统的设计与实现
大数据项目——基于Django实现的高校图书馆智能推送系统的设计与实现背景,可以从以下几个方面进行详细阐述: 一、信息技术的发展背景 随着信息技术的飞速发展和互联网的广泛普及,大数据已经成为现代社会的重要资源。在大数据背景下…...
Leecode刷题之路第七天之整数反转
题目出处 07-整数反转 题目描述 个人解法 思路: 1.将整数转换为字符串 2.倒序输出字符串 3.兼容负数case 代码示例:(Java) public int reverse(int x) {Integer integer new Integer(x);String s integer.toString();Strin…...
SpringBoot项目 | 瑞吉外卖 | 短信发送验证码功能改为免费的邮箱发送验证码功能 | 代码实现
0.前情提要 之前的po已经说了单独的邮箱验证码发送功能怎么实现: https://blog.csdn.net/qq_61551948/article/details/142641495 这篇说下如何把该功能整合到瑞吉项目里面,也就是把原先项目里的短信发送验证码的功能改掉,改为邮箱发送验证…...
Windows暂停更新
目录 前言注册表设定参考 前言 不想Windows自动更新,同时不想造成Windows商店不可用,可以采用暂停更新的方案。 但是通过这里设定的时间太短了,所以我们去注册表设定。 注册表设定 win r 输入 regedit进入注册表 HKEY_LOCAL_MACHINE\SOFT…...
alpine安装docker踩坑记
文章目录 前言错误场景正确操作最后 前言 你好,我是醉墨居士,最近使用alpine操作系统上docker遇到了一些错误,尝试解决之后就准备输出一篇博客,帮助有需要的后人能够少踩坑,因为淋过雨所以想给别人撑伞 错误场景 我…...
使用openpyxl轻松操控Excel文件
目录 1. openpyxl 简介2. 安装与快速入门2.1 安装 openpyxl2.2 快速创建一个 Excel 文件2.3 读取 Excel 文件 3. openpyxl 的核心概念3.1 工作簿(Workbook)3.2 工作表(Worksheet)3.3 单元格(Cell)3.4 行与列…...
指定PDF或图片多个识别区域,识别区域文字,并批量对PDF或图片文件改名
常见场景 用户有大量图片/PDF文件,期望能按照图片/PDF中的某些文字对图片/PDF文件重命名。期望工具可以批量处理、离线识别(保证数据安全性)。手工操作麻烦。具体场景:用户有工程现场照片,订单,简历等PDF或…...
Web3中的跨链技术:实现无缝连接的挑战
Web3的到来为互联网带来了去中心化的愿景,而跨链技术则是实现这一愿景的关键。跨链技术旨在解决不同区块链之间的互操作性问题,使得用户和应用能够在多个区块链网络之间无缝地传输数据和价值。尽管这一技术具有广阔的前景,但在实现过程中仍面…...
词袋(Bag of Words, BoW)
词袋(Bag of Words, BoW)模型详解 词袋(BoW)是一种用于文本处理的特征提取方法,常用于自然语言处理(NLP)任务中。在BoW模型中,文本被表示为一个词的无序集合,而忽略了词…...
HTTP Status 404 - /brand-demo/selectAllServlet错误解决原因-Servlet/JavaWeb/IDEA
检查xml文件的包名有无错误检查html文件的url有无写错,是否与Servlet的urlPatterns一致检查Servlet的urlpattern有没有写错(如写成name),检查doPost、doGet是否正常运行 注:IDEA新建Servlet时,默认的WebServlet注解中name需要改urlPatterns&…...
宁夏众智科技OA办公系统存在SQL注入漏洞
漏洞描述 宁夏众智科技OA办公系统存在SQL注入漏洞 漏洞复现 POC POST /Account/Login?ACTIndex&CLRHome HTTP/1.1 Host: Content-Length: 45 Cache-Control: max-age0 Origin: http://39.105.48.206 Content-Type: application/x-www-form-urlencoded Upgrade-Insecur…...
Spring邮件发送:配置与发送邮件详细步骤?
Spring邮件发送教程指南?怎么用Spring邮件发送服务? Spring框架提供了强大的邮件发送支持,使得开发者能够轻松地在应用程序中集成邮件发送功能。AokSend将详细介绍如何在Spring应用中配置和发送邮件,帮助开发者快速掌握这一关键技…...
iPhone/iPad技巧:如何解锁锁定的 iPhone 或 iPad
“在我更新 iPhone 上的软件后,最近我遇到了iPhone 被锁定到所有者的消息,该如何解决?” 根据我们的研究,许多用户在 iOS 18 更新或恢复出厂设置后都会遇到同样的问题。只要出现问题,您就无法使用 iPhone 或 第 1 部分…...
无源码实现免登录功能
因项目要求需要对一个没有源代码的老旧系统实现免登录功能,系统采用前后端分离的方式部署,登录时前端调用后台的认证接口,认证接口返回token信息,然后将token以json的方式存储到cookie中,格式如下: 这里有…...
大数据毕业设计选题推荐-民族服饰数据分析系统-Python数据可视化-Hive-Hadoop-Spark
✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...
疾风大模型气象,基于气象数据打造可视化平台
引言 随着气象数据的广泛应用,越来越多的行业依赖天气预报与气候分析来做出决策。从农业、航空、能源到物流,气象信息无时不刻影响着各行各业的运作。然而,气象数据本身复杂且多样,如何将这些数据转化为直观、易于理解的图形和信…...
PHP安装后Apache无法运行的问题
问题 按照网上教程php安装点击跳转教程,然后修改Apache的httpd.conf文件,本来可以运行的Apache,无法运行了 然后在"C:\httpd-2.4.62-240904-win64-VS17\Apache24\logs\error.log"(就是我下载Apache的目录下的logs中&am…...
[论文精读]Multi-Channel Graph Neural Network for Entity Alignment
论文网址:Multi-Channel Graph Neural Network for Entity Alignment (aclanthology.org) 论文代码:https:// github.com/thunlp/MuGNN 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&a…...
Study-Oracle-10-ORALCE19C-RAC集群搭建(一)
一、硬件信息及配套软件 1、硬件设置 RAC集群虚拟机:CPU:2C、内存:10G、操作系统:50G Openfile数据存储:200G (10G*2) 2、网络设置 主机名公有地址私有地址VIP共享存储(SAN)rac1192.168.49.13110.10.10.20192.168.49.141192.168.49.130rac2192.168.49.13210.10.10.3…...
1.8 物理层下的传输媒体
欢迎大家订阅【计算机网络】学习专栏,开启你的计算机网络学习之旅! 文章目录 1 导引型传输媒体1.1 双绞线1.2 同轴电缆1.3 光缆 2 非导引型传输媒体2.1 无线电微波通信2.2 多径效应2.3 卫星通信2.4 无线局域网 在数据通信系统中,传输媒体是发…...
指纹定位的原理与应用场景
目录 原理 1. 信号特征收集 2. 定位算法 推导公式 距离估算公式 定位算法公式 使用场景 发展前景 指纹定位是一种基于无线信号强度(如Wi-Fi、RFID、蓝牙等)来实现室内定位的技术。它借助于环境中多个基站的信号特征来推断用户的位置。以下是对指纹定位的详细讲解,包…...
发现一款适合所有用户小巧且强大的编辑器(完美替换Windows记事本)
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 编辑器 📒📝 功能亮点📝 适用场景📝 安装使用📝 替换Windows记事本🎈 获取方式 🎈⚓️ 相关链接 ⚓️📖 介绍 📖 今天,发现一款小巧(仅1.26M)且功能强大的编辑器,适用于文本编辑,编程开发等,应该说是适…...
Mysql知识点整理
一、关系型数据库 mysql属于关系型数据库,它具备以下特点 关系模型:数据以二维表格形式存储,易于理解和使用。 数据一致性:通过事务处理机制(ACID特性:原子性、一致性、隔离性、持久性)保证数据…...
ISA-95制造业中企业和控制系统的集成的国际标准-(4)
ISA-95 文章目录 ISA-95ISA-95 & MES一、ISA-95是MES的系统标准二、ISA-95对MOM/MES的活动定义三、MES/MOM如何遵循ISA-95四、MES/MOM功能划分和边界定义 ISA-95 & MES ISA-95 作为企业系统与控制系统集成国际标准,提供了一个通用的框架,有助于…...
Redis篇(Redis原理 - 数据结构)(持续更新迭代)
目录 一、动态字符串 二、intset 三、Dict 1. 简介 2. Dict的扩容 3. Dict的rehash 4. 知识小结 四、ZipList 1. 简介 2. ZipListEntry 3. Encoding编码 五、ZipList的连锁更新问题 六、QuickList 七、SkipList 八、RedisObject 1. 什么是 redisObject 2. Redi…...
Disco公司的DBG工艺详解
知识星球里的学员问:可以详细介绍下DBG工艺吗?DBG工艺的优势在哪里? 什么是DBG工艺? DBG工艺,即Dicing Before Grinding,划片后减薄。Dicing即金刚石刀片划切,Grinding即背面减薄,…...
大学学校用电安全远程监测预警系统
1.概述: 该系统是基于移动互联网、云计算技术,通过物联网传感终端,将办公建筑、学校、医院、工厂、体育场馆、宾馆、福利院等人员密集场所的电气安全数据,实时传输至安全用申管理服务器,为用户提供不间断的数据跟踪&a…...
C++网络编程之IP地址和端口
概述 IP地址和端口共同定义了网络通信中的源和目标。IP地址负责将数据从源设备正确地传输到目标设备,而端口则确保在目标设备上数据被交付到正确的应用或服务。因此,在网络编程中,IP地址和端口是密不可分的两个概念,共同构成了网络…...
武汉做网站哪家专业/优化设计答案六年级
本帖最后由 uytyrt 于 2017-2-15 09:16 编辑一、mysql同步原理1、mysql主库在事务提交时将数据变更作为时间记录到二进制日志(binary log)中;2、slave IO线程将master的binary log events读写到它的中继(Relay log);3、slave SQL进程读取Relay log&#…...
wordpress添加动态图标/搜索引擎营销的原理是什么
STL之deque容器1. deque容器基本概念2. deque容器实现原理3. deque常用API1. deque容器基本概念 vector容器是单向开口的连续内存空间,deque则是一种双向开口的连续线性空间。所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作,…...
买了域名怎么做网站/百度集团公司简介
无悔入华夏怎么通关快呢?下面小编为大家带来无悔入华夏快速通关攻略,一起看看吧.名臣带的:墨子(墨守加防御),李牧(神,前期点出据守加防御,中期点出另一个加兵,相当于子弟兵),商鞅(拿来治国的),…...
潍坊网站建设怎样/网络营销专业是干嘛的
做奢侈品回收这么久,遇见最多的问题就是大多数的顾客都觉得自己包包贬值太快,舍不得卖!那究竟是什么原因让你的包包贬值这么快呢?这就要说说包包的保值率了~影响包包保值率的原因有很多,主要有:品牌、款式、…...
校级特色专业建设网站/免费推广
总结: 1.webview 无法直接更改view的属性,可以通过 handler实现,因为跨线程 2.webview可以通过js api读取 view的属性值 代码: private Handler myhandler new Handler() { Override public void handleMessage(Message msg) {…...
益阳房地产网站建设/5118关键词查询工具
函数定义语法:def 函数名(参数1,参数2...):注释:声明函数逻辑代码return 返回值def:defind 定义函数名:必须看其名知意():接受外部传入的参数注释:用来声明函数的作用return:返回给…...