你打电话问书店老板有没有《分布式系统》这本书,若是是同步通讯机制,书店老板会说,你稍等,”我查一下",而后开始查啊查,等查好了(多是5秒,也多是一天)告诉你结果(返回结果)。 而异步通讯机制,书店老板直接告诉你我查一下啊,查好了打电话给你,而后直接挂电话了(不返回结果)。而后查好了,他会主动打电话给你。在这里老板经过“回电”这种方式来回调。^1javascript
"异步模式"很是重要。在浏览器端,耗时很长的操做都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操做。在服务器端,"异步模式"甚至是惟一的模式,由于执行环境是单线程的,若是容许同步执行全部http请求,服务器性能会急剧降低,很快就会失去响应。^2css
Asynchronous Javascript And XML ----异步的javascript和xml。 页面发起请求,会将请求发送给浏览器内核中的Ajax引擎,Ajax引擎会提交请求到服务器,在这段时间里,客户端能够任意进行任意操做,直到服务器端将数据返回给Ajax引擎后,Ajax引擎再将数据给浏览器解析。 html
模拟帐号注册:注册页面中,若是用户名文本框失去焦点,则进行异步校验;若是用户名已经存在,则在右侧用红色字体提示用户用户名不可用,而且禁用注册按钮,不然提示可用,并解除注册按钮禁用。 java
<div class="form-group">
<label for="inputname1" class="col-sm-2 col-sm-offset-2 control-label">用户名:</label>
<div class="col-sm-3">
<input type="text" name="remitter" class="form-control" id="inputname1" placeholder="请填写全称">
</div>
<div class="col-sm-3" id = "msg" style="vertical-align: middle;">
</div>
</div>
复制代码
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
<script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
复制代码
<script type="text/javascript">
// 页面加载
$(function(){
// 触发文本框失去焦点事件
$("#inputname1").blur(function(){
// 初步判断文本框非空和去掉空格后仍然非空
if($(this).val() != "" && $.trim($(this).val()) != "") {
// 使用post请求方式传输数据
var url = "${pageContext.request.contextPath}/CheckServlet"; // 访问服务器地址
var params = "remitter=" + $(this).val(); // 检验参数
$.post(url, params, function(d) { //post请求方式
if(d > 0) { // 若是查询到1条记录,则提示用户从新选择用户名
$("#msg").html("<font color='red'>该用户名太受欢迎,请从新输入</font>");
$("#submit").prop("disabled", true);
}else{ //不然提示可使用该用户名
$("#msg").html("用户名可使用").css("color", "blue");
$("#submit").prop("disabled", false);
}
});
}else{ // 若是文本框没有有用的信息则将提示内容清空,并禁用注册键
$("#msg").html("");
$("#submit").prop("disabled", true);
}
});
});
</script>
复制代码
try {
// post请求解决乱码问题
request.setCharacterEncoding("UTF-8");
// 获取请求数据
String remitter = request.getParameter("remitter");
// 调用service层
CheckService cs = new CheckService();
// 返回查询参数
int count = cs.find(remitter);
// 传递到客户端
response.getWriter().print(count);
} catch (SQLException e) {
e.printStackTrace();
}
复制代码
public int find(String remitter) throws SQLException {
// 使用QueryRunner工具类
QueryRunner qr = new QueryRunner(C3p0Utils.getDataSource());
// 编写sql语句
String sql = "select count(*) from searchkey where username = ?";
// 因为ScalarHandler返回的Object只能强转成Long类型,必须再次调用intValue()方法才能返回int类型
return ((Long)qr.query(sql, new ScalarHandler(), remitter)).intValue();
}
复制代码
public class C3p0Utils {
private static DataSource ds = new ComboPooledDataSource("nefu");
public static DataSource getDataSource() {
return ds;
}
}
复制代码
配置文件c3p0-config.xml存放在src目录下mysql
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<named-config name="nefu">
<!-- 链接数据库的4项基本参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/searchkey_db
</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 若是池中数据链接不够时一次增加多少个 -->
<property name="acquireIncrement">5</property>
<!-- 初始化链接数 -->
<property name="initialPoolSize">20</property>
<!-- 最小链接受 -->
<property name="minPoolSize">10</property>
<!-- 最大链接数 -->
<property name="maxPoolSize">40</property>
<!-- -JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量 -->
<property name="maxStatements">0</property>
<!-- 链接池内单个链接所拥有的最大缓存statements数 -->
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
复制代码
模拟搜索引擎:输入关键字,查询数据库,并将查询结果返回到浏览器展现。 jquery
<div class="form-group dropdown">
<input type="text" class="form-control dropdown-toggle" id="key" style="width: 300px"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" />
<ul id="list" class="dropdown-menu"
style="width: 100%; display: none;" aria-labelledby="dropdownMenu"></ul>
</div>
复制代码
<script>
// 当单击备选条是文本框输入内容
function selected(obj) {
$("#key").val($(obj).text());
$("#list").hide();
}
// 页面加载
$(function(){
// 当按键弹起事件
$("#key").keyup(function() {
// 先将下拉列表清空,并隐藏列表
$("#list").html("");
$("#list").hide();
if($(this).val() != "" && $.trim($(this).val()) != "") {
url = "${pageContext.request.contextPath}/SearchingServlet";
params = "keyword=" + $(this).val();
// post请求
$.post(url, params, function(d) {
if(d != null) {
$(d).each(function(a,b) { // 遍历d,并将结果追加到列表后面
$("#list").append("<li onclick='selected(this)'><a>" + b + "</a></li>");
$("#list").show(); // 展现列表内容
})
}
}, "json") // 使用json的数据形式返回数据
}
})
})
</script>
复制代码
try {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String keyword = request.getParameter("keyword");
SearchingService ss = new SearchingService();
List<Object> list = ss.find(keyword);
// 随机选择集合中的前10个选项
Collections.shuffle(list);
ArrayList<Object> temp = new ArrayList<Object>();
for (Object object : list) {
if(temp.size() < 10) {
temp.add(object);
}
}
// 将temp集合转换成json格式
JSONArray jsonarray = JSONArray.fromObject(temp);
String json = jsonarray.toString();
// 传递给浏览器
response.getWriter().print(json);
} catch (SQLException e) {
e.printStackTrace();
}
复制代码
public List<Object> find(String keyword) throws SQLException {
QueryRunner qr = new QueryRunner(C3p0Utils.getDataSource());
// 将关键字拆分单个字符
char[] array = keyword.toCharArray();
StringBuilder sql = new StringBuilder();
// where 1 = 1 拼接字符串过程当中,避免没法肯定and的开始位置
sql.append("select distinct username from searchkey where 1 = 1");
// 创建一个list集合存储参数 注意空格
List<String> params = new ArrayList<>();
if(array != null) {
for (char c : array) {
if(c != ' ') {
sql.append( " and username like ?");
params.add("%" + c + "%");
}
}
}
List<Object> list = qr.query(sql.toString(), new ColumnListHandler(), params.toArray());
return list;
}
复制代码
因为html没有语法检查功能(HBuilder好像有,可是加载半天你能忍),因此事件触发后没有响应的错误很难排查,根据笔者的经验给出几点建议ajax
$("inputname1")
没有#号,var url=
写成了val url=
(我好像暴露了什么dog脸)$.get(url,[params],[fn],[type]):发送了一个get请求
复制代码
$.post(url,[params],[fn],[type]):发送一个post请求
复制代码
$.ajax({选项});
常见的选项:
url:路径,
data:发送的参数,
type:请求的方式,
success:成功时候的回调,
error:错误时候的回调,
async:是否异步 默认就是异步的方式,
dataType:返回内容的格式 默认字符串
复制代码
{"key":value,"key1":value1}
、[e1,e2]
,可使用jsonlib
调用方法直接将数组、集合等转成json
数据类型。