当前位置: 首页 > 编程日记 > 正文

反向ajax实现

英文原文: Reverse Ajax, Part 1: Introduction to Comet
在过去的几年中,web开发已经发生了很大的变化。现如今,我们期望的是能够通过web快速、动态地访问应用。在这一新的文章系列中,我们学习如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用,以此来实现更好的用户体验。客户端的例子使用的是JQuery JavaScript库,在这首篇文章中,我们探索不同的反向Ajax技术,使用可下载的例子来学习使用了流(streaming)方法和长轮询(long polling)方法的Comet。

前言

web开发在过去的几年中有了很大的进展,我们已经远超了把静态网页链接在一起的做法,这种做法会引起浏览器的刷新,并且要等待页面的加载。现在需要的是能够通过web来访问的完全动态的应用,这些应用通常需要尽可能的快,提供近乎实时的组件。在这一新的由五部分组成的文章系列中,我们学习如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用。

在这第一篇文章中,我们要了解反向Ajax、轮询(polling)、流(streaming)、Comet和长轮询(long polling),学习如何实现不同的反向Ajax通信技术,并探讨每种方法的优点和缺点。你可以下载本文中例子的相应源代码。

Ajax、反向Ajax和WebSocket

异步的JavaScript和XML(Asynchronous JavaScript and XML,Ajax),一种可通过JavaScript来访问的浏览器功能特性,其允许脚本向幕后的网站发送一个HTTP请求而又无需重新加载页面。Ajax的出现已经超过了十年,尽管其名字中包含了XML,但你几乎可以在Ajax请求中传送任何的东西,最常用的数据是JSON,其与JavaScript语法很接近,且消耗更少带宽。清单1给出了这样的一个例子,Ajax请求通过某个地方的邮政编码来检索该地的名称。

清单1. Ajax请求举例

var url ='http://www.geonames.org/postalCodeLookupJSON?postalcode='
  + $('#postalCode').val() +'&country='
  + $('#country').val() +'&callback=?';
  $.getJSON(url, 
function(data) {
  $(
'#placeName').val(data.postalcodes[0].placeName);
});

在本文可下载的源代码中,你可在listing1.html中看到这一例子的作用。

反向Ajax(Reverse Ajax)本质上则是这样的一种概念:能够从服务器端向客户端发送数据。在一个标准的HTTP Ajax请求中,数据是发送给服务器端的,反向Ajax可以某些特定的方式来模拟发出一个Ajax请求,这些方式本文都会论及,这样的话,服务器就可以尽可能快地向客户端发送事件(低延迟通信)。

WebSocket技术来自HTML5,是一种最近才出现的技术,许多浏览器已经支持它(Firefox、Google Chrome、Safari等等)。WebSocket启用双向的、全双工的通信信道,其通过某种被称为WebSocket握手的HTTP请求来打开连接,并用到了一些特殊的报头。连接保持在活动状态,你可以用JavaScript来写和接收数据,就像是正在用一个原始的TCP套接口一样。WebSocket会在这一文章系列的第二部分中谈及。

反向Ajax技术

反向Ajax的目的是允许服务器端向客户端推送信息。Ajax请求在缺省情况下是无状态的,且只能从客户端向服务器端发出请求。你可以通过使用技术模拟服务器端和客户端之间的响应式通信来绕过这一限制。

HTTP轮询和JSONP轮询

轮询(polling)涉及了从客户端向服务器端发出请求以获取一些数据,这显然就是一个纯粹的Ajax HTTP请求。为了尽快地获得服务器端事件,轮询的间隔(两次请求相隔的时间)必须尽可能地小。但有这样的一个缺点存在:如果间隔减小的话,客户端浏览器就会发出更多的请求,这些请求中的许多都不会返回任何有用的数据,而这将会白白地浪费掉带宽和处理资源。

图1中的时间线说明了客户端发出了某些轮询请求,但没有信息返回这种情况,客户端必须要等到下一个轮询来获取两个服务器端接收到的事件。

图1. 使用HTTP轮询的反向Ajax

JSONP轮询基本上与HTTP轮询一样,不同之处则是JSONP可以发出跨域请求(不是在你的域内的请求)。清单1使用JSONP来通过邮政编码获取地名,JSONP请求通常可通过它的回调参数和返回内容识别出来,这些内容是可执行的JavaScript代码。

要在JavaScript中实现轮询的话,你可以使用setInterval来定期地发出Ajax请求,如清单2所示:

清单2. JavaScript轮询

setInterval(function() {
  $.getJSON(
'events'function(events) {
    console.log(events);
  });
}, 
2000);

文章源代码中的轮询演示给出了轮询方法所消耗的带宽,间隔很小,但可以看到有些请求并未返回事件,清单3给出了这一轮询示例的输出。

清单3. 轮询演示例子的输出

[client] checking for events...
[client] no event
[client] checking for events...
[client]2 events
[event] At Sun Jun 0515:17:14 EDT 2011
[event] At Sun Jun 0515:17:14 EDT 2011
[client] checking for events...
[client]1 events
[event] At Sun Jun 0515:17:16 EDT 2011

用JavaScript实现的轮询的优点和缺点:

1. 优点:很容易实现,不需要任何服务器端的特定功能,且在所有的浏览器上都能工作。

2. 缺点:这种方法很少被用到,因为它是完全不具伸缩性的。试想一下,在100个客户端每个都发出2秒钟的轮询请求的情况下,所损失的带宽和资源数量,在这种情况下30%的请求没有返回数据。

Piggyback

捎带轮询(piggyback polling)是一种比轮询更加聪明的做法,因为它会删除掉所有非必需的请求(没有返回数据的那些)。不存在时间间隔,客户端在需要的时候向服务器端发送请求。不同之处在于响应的那部分上,响应被分成两个部分:对请求数据的响应和对服务器事件的响应,如果任何一部分有发生的话。图2给出了一个例子。

图2. 使用了piggyback轮询的反向Ajax

在实现piggyback技术时,通常针对服务器端的所有Ajax请求可能会返回一个混合的响应,文章的下载中有一个实现示例,如下面的清单4所示。

清单4. piggyback代码示例

$('#submit').click(function() {
  $.post(
'ajax'function(data) {
    var valid = data.formValid;
    // 处理验证结果
    //
 然后处理响应的其他部分(事件)
    processEvents(data.events);
  });
});

清单5给出了一些piggyback输出。

清单5. piggyback输出示例

[client] checking for events...
[server] form valid ? true
[client]4 events
[event] At Sun Jun 0516:08:32 EDT 2011
[event] At Sun Jun 0516:08:34 EDT 2011
[event] At Sun Jun 0516:08:34 EDT 2011
[event] At Sun Jun 0516:08:37 EDT 2011

你可以看到表单验证的结果和附加到响应上的事件,同样,这种方法也有着一些优点和缺点:

1. 优点:没有不返回数据的请求,因为客户端对何时发送请求做了控制,对资源的消耗较少。该方法也是可用在所有的浏览器上,不需要服务器端的特殊功能。

2. 缺点:当累积在服务器端的事件需要传送给客户端时,你却一点都不知道,因为这需要一个客户端行为来请求它们。

Comet

使用了轮询或是捎带的反向Ajax非常受限:其不具伸缩性,不提供低延迟通信(只要事件一到达服务器端,它们就以尽可能快的速度到达浏览器端)。Comet是一个web应用模型,在该模型中,请求被发送到服务器端并保持一个很长的存活期,直到超时或是有服务器端事件发生。在该请求完成后,另一个长生存期的Ajax请求就被送去等待另一个服务器端事件。使用Comet的话,web服务器就可以在无需显式请求的情况下向客户端发送数据。

Comet的一大优点是,每个客户端始终都有一个向服务器端打开的通信链路。服务器端可以通过在事件到来时立即提交(完成)响应来把事件推给客户端,或者它甚至可以累积再连续发送。因为请求长时间保持打开的状态,故服务器端需要特别的功能来处理所有的这些长生存期请求。图3给出了一个例子。(这一文章系列的第2部分会更加详细地解释服务器端的约束条件)。

图3. 使用Comet的反向Ajax

Comet的实现可以分成两类:使用流(streaming)的那些和使用长轮询(long polling)的那些。

使用HTTP流的Comet

在流(streaming)模式中,有一个持久连接会被打开。只会存在一个长生存期请求(图3中的#1),因为每个到达服务器端的事件都会通过这同一连接来发送。因此,客户端需要有一种方法来把通过这同一连接发送过来的不同响应分隔开来。从技术上来讲,两种常见的流技术包括Forever Iframe(隐藏的IFrame),或是被用来在JavaScript中创建Ajax请求的XMLHttpRequest对象的多部分(multi-part)特性。

Forever Iframe

Forever Iframe(永存的Iframe)技术涉及了一个置于页面中的隐藏Iframe标签,该标签的src属性指向返回服务器端事件的servlet路径。每次在事件到达时,servlet写入并刷新一个新的script标签,该标签内部带有JavaScript代码,iframe的内容被附加上这一script标签,标签中的内容就会得到执行。

1. 优点:实现简单,在所有支持iframe的浏览器上都可用。

2. 缺点: 没有方法可用来实现可靠的错误处理或是跟踪连接的状态,因为所有的连接和数据都是由浏览器通过HTML标签来处理的,因此你没有办法知道连接何时在哪一端已被断开了。

Multi-part XMLHttpRequest

第二种技术,更可靠一些,是XMLHttpRequest对象上使用某些浏览器(比如说Firefox)支持的multi-part标志。Ajax请求被发送给服务器端并保持打开状态,每次有事件到来时,一个多部分的响应就会通过这同一连接来写入,清单6给出了一个例子。

清单6. 设置Multi-part XMLHttpRequest的JavaScript代码示例

var xhr = $.ajaxSettings.xhr();
xhr.multipart 
=true;
xhr.open(
'GET''ajax'true);
xhr.onreadystatechange 
= function() {
  if (xhr.readyState == 4) {
    processEvents($.parseJSON(xhr.responseText));
  }
};
xhr.send(
null);

在服务器端,事情要稍加复杂一些。首先你必须要设置多部分请求,然后挂起连接。清单7展示了如何挂起一个HTTP流请求。(这一系列的第3部分会更加详细地谈及这些API。)

清单7. 使用Servlet 3 API来在servlet中挂起一个HTTP流请求

protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
  // 开始请求的挂起
  AsyncContext asyncContext = req.startAsync();
  asyncContext.setTimeout(
0);

  // 给客户端发回多部分的分隔符
  resp.setContentType("multipart/x-mixed-replace;boundary=\""
  + boundary +"\"");
  resp.setHeader(
"Connection""keep-alive");
  resp.getOutputStream().print(
"--"+ boundary);
  resp.flushBuffer();

  // 把异步上下文放在列表中以被将来只用
  asyncContexts.offer(asyncContext);
}

现在,每次有事件发生时你都可以遍历所有的挂起连接并向它们写入数据,如清单8所示:

清单8. 使用Servlet 3 API来向挂起的多部分请求发送事件

for (AsyncContext asyncContext : asyncContexts) {
  HttpServletResponse peer 
= (HttpServletResponse)
  asyncContext.getResponse();
  peer.getOutputStream().println(
"Content-Type: application/json");
  peer.getOutputStream().println();
  peer.getOutputStream().println(
new JSONArray()
  .put(
"At "+new Date()).toString());
  peer.getOutputStream().println(
"--"+ boundary);
  peer.flushBuffer();
}

本文可下载文件的Comet-straming文件夹中的部分说明了HTTP流,在运行例子并打开主页时,你会看到只要事件一到达服务器端,虽然不同步但它们几乎立刻会出现在页面上。而且,如果打开Firebug控制台的话,你就能看到只有一个Ajax请求是打开的。如果再往下看一些,你会看到JSON响应被附在Response选项卡中,如图4所示:

图4. HTTP流请求的FireBug视图

照例,做法存在着一些优点和缺点:

1. 优点:只打开了一个持久连接,这就是节省了大部分带宽使用率的Comet技术。

2. 缺点:并非所有的浏览器都支持multi-part标志。某些被广泛使用的库,比如说用Java实现的CometD,被报告在缓冲方面有问题。例如,一些数据块(多个部分)可能被缓冲,然后只有在连接完成或是缓冲区已满时才被发送,而这有可能会带来比预期要高的延迟。

使用HTTP长轮询的Comet

长轮询(long polling)模式涉及了打开连接的技术。连接由服务器端保持着打开的状态,只要一有事件发生,响应就会被提交,然后连接关闭。接下来。一个新的长轮询连接就会被正在等待新事件到达的客户端重新打开。

你可以使用script标签或是单纯的XMLHttpRequest对象来实现HTTP长轮询。

script标签

正如iframe一样,其目标是把script标签附加到页面上以让脚本执行。服务器端则会:挂起连接直到有事件发生,接着把脚本内容发送回浏览器,然后重新打开另一个script标签来获取下一个事件。

1. 优点:因为是基于HTML标签的,所有这一技术非常容易实现,且可跨域工作(缺省情况下,XMLHttpRequest不允许向其他域或是子域发送请求)。

2. 缺点:类似于iframe技术,错误处理缺失,你不能获得连接的状态或是有干涉连接的能力。

XMLHttpRequest长轮询

第二种,也是一种推荐的实现Comet的做法是打开一个到服务器端的Ajax请求然后等待响应。服务器端需要一些特定的功能来允许请求被挂起,只要一有事件发生,服务器端就会在挂起的请求中送回响应并关闭该请求,完全就像是你关闭了servlet响应的输出流。然后客户端就会使用这一响应并打开一个新的到服务器端的长生存期的Ajax请求,如清单9所示:

清单9. 设置长轮询请求的JavaScript代码示例

function long_polling() {
  $.getJSON(
'ajax'function(events) {
    processEvents(events);
    long_polling();
  });
}
long_polling();

在后端,代码也是使用Servlet 3 API来挂起请求,正如HTTP流的做法一样,但你不需要所有的多部分处理代码,清单10给出了一个例子。

清单10. 挂起一个长轮询Ajax请求

protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
  AsyncContext asyncContext 
= req.startAsync();
  asyncContext.setTimeout(
0);
  asyncContexts.offer(asyncContext);
}

在接收到事件时,只是取出所有的挂起请求并完成它们,如清单11所示:

清单11. 在有事件发生时完成长轮询Ajax请求

while (!asyncContexts.isEmpty()) {
  AsyncContext asyncContext 
= asyncContexts.poll();
  HttpServletResponse peer 
= (HttpServletResponse)
  asyncContext.getResponse();
  peer.getWriter().write(
    new JSONArray().put("At " + new Date()).toString());
  peer.setStatus(HttpServletResponse.SC_OK);
  peer.setContentType(
"application/json");
  asyncContext.complete();
}

在附带的下载源文件中,comet-long-polling文件夹包含了一个长轮询示例web应用,你可以使用 mvn jetty:run 命令来运行它。

1. 优点:客户端很容易实现良好的错误处理系统和超时管理。这一可靠的技术还允许在与服务器端的连接之间有一个往返,即使连接是非持久的(当你的应用有许多的客户端时,这是一件好事)。它可用在所有的浏览器上;你只需要确保所用的XMLHttpRequest对象发送到的简单的Ajax请求就可以了。

2. 缺点:相比于其他技术来说,不存在什么重要的缺点,像所有我们已经讨论过的技术一样,该方法依然依赖于无状态的HTTP连接,其要求服务器端有特殊的功能来临时挂起连接。

建议

因为所有现代的浏览器都支持跨域资源共享(Cross-Origin Resource Share,CORS)规范,该规范允许XHR执行跨域请求,因此基于脚本的和基于iframe的技术已成为了一种过时的需要。

把Comet做为反向Ajax的实现和使用的最好方式是通过XMLHttpRequest对象,该做法提供了一个真正的连接句柄和错误处理。考虑到不是所有的浏览器都支持multi-part标志,且多部分流可能会遇到缓冲问题,因此建议你选择经由HTTP长轮询使用XMLHttpRequest对象(在服务器端挂起的一个简单的Ajax请求)的Comet模式,所有支持Ajax的浏览器也都支持该种做法。

结论

本文提供的是反向Ajax技术的一个入门级介绍,文章探索了实现反向Ajax通信的不同方法,并说明了每种实现的优势和弊端。你的具体情况和应用需求将会影响到你对最合适方法的选择。不过一般来说,如果你想要在低延迟通信、超时和错误检测、简易性,以及所有浏览器和平台的良好支持这几方面有一个最好的折中的话,那就选择使用了Ajax长轮询请求的Comet。

请继续阅读这一系列的第2部分:该部分将会探讨第三种反向Ajax技术:WebSocket。尽管还不是所有的浏览器都支持该技术,但WebSocket肯定是一种非常好的反向Ajax通信媒介,WebSocket消除了所有与HTTP连接的无状态特性相关的限制。第2部分还会谈及由Comet和WebSocket技术带来的服务器端约束。

代码下载

  reverse_ajaxpt1_source.zip

相关文章:

ef关联多实体查询_Mybatis基本知识十二:关联关系查询之延迟加载:侵入式延迟加载...

上一篇文章:《Mybatis基本知识十一:关联关系查询之延迟加载策略:直接加载》若文中有纰漏,请多多指正!!!1.前言延续上一章节,本章节主要讲解和演示在关联关系查询中侵入式延迟加载是怎么回事。与…

Java高危漏洞被再度利用 可攻击最新版本服务器

2019独角兽企业重金招聘Python工程师标准>>> 安全研究人员警告称,甲骨文在2013年发布的一个关键 Java 漏洞更新是无效的,黑客可以轻松绕过。这使得此Java高危漏洞可以被再度利用,击运行最新版本 Java 的个人计算机及服务器。甲骨文…

不断演进的 Chrome 安全标识

文 / Chrome Security 产品经理 Emily Schechter 此前,我们曾发布一项提议,建议将所有 HTTP 网页标记为确定 “不安全” 并移除 HTTPS 网页的安全标识。自从我们在 Chrome 中引入安全标识以来,网络上的 HTTPS 使用量迅速增加。今年晚些时候&a…

gcc -E 选项

-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面.例子用法:gcc -E hello.c > pianoapan.txtgcc -E hello.c | more慢慢看吧,一个hello word 也要与处理成800行的代码 -E选项,表示让gcc只进行“预处理”就行了。 所谓的预处理,就是…

剑指offer青蛙跳台阶问题

&#xff08;1&#xff09;一只青蛙一次可以跳上 1 级台阶&#xff0c;也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。//递归方式 public static int f(int n) { //参数合法性验证 if (n < 1) { System.out.println("参数必须大于1&#xff01;&quo…

mysql 亿级表count_码云社 | 砺锋科技-MySQL的count(*)的优化,获取千万级数据表的总行数 - 用代码改变世界...

专注于Java领域优质技术号&#xff0c;欢迎关注作者&#xff1a;李长念一、前言这个问题是今天朋友提出来的&#xff0c;关于查询一个1200w的数据表的总行数&#xff0c;用count(*)的速度一直提不上去。找了很多优化方案&#xff0c;最后另辟蹊径&#xff0c;选择了用explain来…

使用mysql内连接查询年龄_Mysql的连表查询

若一个查询同时涉及到两个以上的表&#xff0c;称为连表查询准备表create table department(id int auto_increment PRIMARY KEY,name varchar(20));departmentcreate table employee(id int primary key auto_increment,name varchar(20),sex enum(male,female) not null defa…

FastDFS安装与使用

安装注意要修改&#xff1a;/etc/fdfs/client.confvim /etc/fdfs/client.confbase_path/home/yuqing/fastdfs 修改为&#xff1a; base_path/home/fastdfstracker_server192.168.209.121:22122 修改为&#xff1a; tracker_server10.201.20.237:22122##include http.conf 修改…

angular组合preact

preact 大小3kb&#xff0c;可以当做angular的一个dom库&#xff0c;而且可以对接使用preact生态系统&#xff0c;react组件修改成preact还是蛮简单的&#xff0c;这样就可以解决angular中用render2操作dom的繁琐问题了!O(∩_∩)O哈哈~&#xff0c;异想天开&#xff0c;动工! t…

大型网站系统架构系列:分布式消息队列(二)

四、JMS消息服务 讲消息队列就不得不提JMS 。JMS&#xff08;JAVA Message Service,java消息服务&#xff09;API是一个消息服务的标准/规范&#xff0c;允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低&#xff0c;消息服务更加可靠以及…

Linux环境编译安装Mysql以及PHP中文乱码解决

mysql安装 5.6以后可能会收费&#xff0c;所以选择5.1以下从台湾中山大学镜像下载1.首先要安装C编译环境 # yum install gcc-c2.下载解压# wget http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-5.1/mysql-5.1.73.tar.gz # tar zxvf mysql-5.1.73.tar.gz # cd mysql-5.1.7…

mysql noinstall_windows mysql noinstall

最近在想做mysql 主,从备份.在一台windows下安装多个mysql server , 发现用安装版的会覆盖前一安装程序,所以就用noinstall版本的mysql server,在此记录下安装过程的步骤.可主,从备份最终没能跑起来........这只是其中方法之一而已windows 下安装mysql-noinstall so easy!!!步骤…

[十九]JavaIO之PipedReader 和 PipedWriter

功能简介还记得PipedInputStream 和 PipedOutputStream么 我们之前是这么说的: 使用管道通信时&#xff0c;必须将PipedOutputStream和PipedInputStream配套使用 大致流程&#xff1a; 我们在线程A中向PipedOutputStream中写入数据&#xff0c;这些数据会自动的发送到与PipedO…

Linux环境HBase安装与使用

原文出自本人另一个Linux博客 http://blog.csdn.net/unix21/article/details/18776073 Linux环境&#xff1a;CentOS6.5 HBase版本&#xff1a;hbase-0.94.16 HBase官网&#xff1a;http://hbase.apache.org 1.下载解压安装文件 # wget http://mirror.bit.edu.cn/apache/hbase/…

Oracle定时执行存储过程

首先查看SQL> show parameter job NAME TYPE VALUE------------------------------------ ----------- ------------------------------job_queue_processes integer 10如果值是 0 需要修改&#xff08;如果为…

mysql8.0取消授权_mysql8创建用户、删除用户、授权、取消授权

注意&#xff0c;以下命令均在数据库mysql中操作use mysql;mysql有密码设置规范,这里修改仅密码长度为4位,仅本次登录有效set global validate_password.policy0;set global validate_password.length4;创建用户格式CREATE USER usernamehost IDENTIFIED WITH mysql_native_pas…

Azure编配器简化有状态无服务器工作流的创建

Azure Durable Functions旨在通过引入编排器function概念来定义更复杂的工作流&#xff0c;以此来扩展无服务器计算范式。如果你曾经想过要使用它们&#xff0c;微软刚刚发布了一个示例&#xff0c;帮助开发人员开始他们的无服务器计算和编排器function之旅。\\Azure Functions…

ZooKeeper集群环境安装与配置

原文&#xff1a;出自本人的Linux博客http://blog.csdn.net/unix21/ ZooKeeper版本&#xff1a;3.4.5 约定&#xff1a;3台虚拟机 前提&#xff1a;需要安装JDK&#xff0c;关于Linux环境JDK安装配置参考我的另一帖Linux环境安装卸载JDK以及安装Tomcat和发布Java的web程序ZooKe…

thinkphp5 mysql长连接_tp5(thinkPHP5)框架连接数据库的方法示例

本文实例讲述了thinkPHP5框架连接数据库的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1、配置文件目录 tp5applicationdatabase.php通过配置文件来连接。。也可以通过方法链接在控制器里方法链接数据库 &#xff1b;查询时写法 和使用系统的DB类方法略有差异/…

学习笔记之Linux Shell脚本教程:30分钟玩转Shell脚本编程

Linux Shell脚本教程&#xff1a;30分钟玩转Shell脚本编程 http://c.biancheng.net/cpp/shell/转载于:https://www.cnblogs.com/pegasus923/p/5304025.html

tomcat的startup.bat闪退问题解决

从官网下载一个免安装的tomcat&#xff0c;我把它解压在E盘&#xff0c;配置了环境变量&#xff1a;CATALINA_HOME、CATALINA_BASE、TOMCAT_HOME 为 tomcat的解压路径 进入解压tomcat的bin目录&#xff0c;执行startup.bat&#xff0c;出现闪退。 然后winR 输入cmd 进入解压tom…

使用Netbeans创建java Web项目

&#xfeff;&#xfeff;使用Netbeans创建java Web项目需要先搭建JDK参考&#xff1a; Java开发环境的搭建以及使用eclipse创建项目 Linux环境安装卸载JDK1.安装Tomcat 去官网下载最新的Tomcat:http://tomcat.apache.org/ 目前最新的windows环境的Tomcat是 http://mirrors.hus…

Linux内核设计第五周学习总结 分析system_call中断处理过程

陈巧然原创作品 转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000使用gdb跟踪分析一个系统调用中断处理过程&#xff0c;分析系统调用从system_call开始到iret结束之间的整个过程。 实验过程&#xff1a; 登陆实验楼虚拟机http://w…

mysql data ibdata1_database - 如何在MySQL中收缩/清除ibdata1文件

database - 如何在MySQL中收缩/清除ibdata1文件我在localhost中使用MySQL作为在R中执行统计的“查询工具”&#xff0c;也就是说&#xff0c;每次运行R脚本时&#xff0c;我创建一个新数据库(A)&#xff0c;创建一个新表(B)&#xff0c;将数据导入B &#xff0c;提交查询以获得…

MySQL学习----各种字符的长度总结

数字型 类型大小范围&#xff08;有符号&#xff09;范围&#xff08;无符号&#xff09;用途TINYINT1 字节(-128&#xff0c;127)(0&#xff0c;255)小整数值SMALLINT2 字节(-32 768&#xff0c;32 767)(0&#xff0c;65 535)大整数值MEDIUMINT3 字节(-8 388 608&#xff0c;8…

分布式消息队列Kafka集群安装

kafka是LinkedIn开发并开源的一个分布式MQ系统&#xff0c;现在是Apache的一个孵化项目。在它的主页描述kafka为一个高吞吐量的分布式&#xff08;能将消息分散到不同的节点上&#xff09;MQ。在这片博文中&#xff0c;作者简单提到了开发kafka而不选择已有MQ系统的原因。两个原…

[na]pc加入域认证细节

这也是以前好奇,因为学生时候,经常机房上网, 对一些譬如.. 现在看来很low了. 是小作坊式的技术, 真正上不了台面的.扛不住生产的压力. ftp共享计算机统一管理等无盘/网克等特别好奇 计算机组织的两种形式 加入办公网络里有200多台pc,如果各个独立的上网互不干扰. 这种也挺方便,…

react 树形菜单_关于React 使用antd组件递归实现左侧菜单导航树(MenusTree)的示例...

一、菜单组件Demo这里本人采用的是蚂蚁金服(antd)组件库里的{Menu}组件写的一个左侧菜单树的小Demo(整套开发环境是ReactReduxwebpack)import React from react;import { Menu, Icon } from antd;import {WeaScroll} from ecCom;import {bindActionCreators} from redux;import…

SQL快速入门 ( MySQL快速入门, MySQL参考, MySQL快速回顾 )

SQL 先说点废话&#xff0c;很久没发文了&#xff0c;整理了下自己当时入门 SQL 的笔记&#xff0c;无论用于入门&#xff0c;回顾&#xff0c;参考查询&#xff0c;应该都是有一定价值的&#xff0c;可以按照目录各取所需。SQL数据库有很多&#xff0c;MySQL是一种&#xff0c…

MyEclipse2014配置Tomcat开发JavaWeb程序JSP以及Servlet

1.安装准备 1).下载安装MyEclipse2014&#xff0c;这已经是最新版本。2).下载Tomcat 官网&#xff1a;http://tomcat.apache.org/ 我们选择8.0&#xff1a; http://tomcat.apache.org/download-80.cgi 在windows下选择64位解压版&#xff1a;http://mirror.bit.edu.cn/apache/t…