今天我要将json和ajax引入到我所写的框架,不过今天用到的技术有部分不是我框架最终使用到的技术,比如ajax技术,我用到的是最为原始的ajax技术,这次算是对老技术的回顾,不过不管技术如何演进,对技术的本质的掌握都是十分重要的。

  首先我简单介绍下json的基础知识。

  json的定义是:基于JavaScript语言的轻量级的数据交换格式(JavaScript Object Notiation)。(摘录于有道)

  JSON建构于两种结构:

  1. “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),记录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

  2. 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

  在我写到的架构里,前端和服务端的交互统一通过json来进行,这个做法符合我的观点,所有逻辑层的通讯都是通过键值对的方式进行,,参见我以前的博文:《系统设计与架构笔记:键值对在架构设计里的应用》

  下面我们继续写框架,首先我新建一张表,它的结构如下图:

  下面我将为这张表建立dao、service以及action,下面我将代码贴在下面(按我开发的过程):

  首先看看工程新的结构目录,如下图:

  1.首先是/ssiprj/src/cn/com/sharpxiajun/dao/sqlmap包下的映射文件PRODUCT.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"><sqlMap namespace="PRODUCT"><select id="queryProductList" parameterClass="java.util.Map" resultClass="java.util.HashMap">        select t.id,t.name,t.desc,t.create_date,t.modify_date,t.status from product t<dynamic prepend="where"><isNotEmpty prepend="and" property="name">                t.name = #name:VARCHAR#</isNotEmpty>    </dynamic></select></sqlMap>

  2.在/ssiprj/conf包的SqlMapConfig.xml文件里添加PRODUCT.xml路径,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"><sqlMapConfig><settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" errorTracingEnabled="true"                 maxRequests="64" maxSessions="20" maxTransactions="10"                 useStatementNamespaces="true"/><sqlMap resource="cn/com/sharpxiajun/dao/sqlmap/USERS.xml"/><sqlMap resource="cn/com/sharpxiajun/dao/sqlmap/PRODUCT.xml"/></sqlMapConfig>

  3.在cn.com.sharpxiajun.dao包下建立接口ProductDao,代码如下:

package cn.com.sharpxiajun.dao;

import java.util.List;import java.util.Map;

public interface ProductDao {

public static final String QUERY_PRODUCT_LIST_SQL = "PRODUCT.queryProductList";

public List<Map<String, Object>> queryProductList(Map<String, Object> params) throws Exception;

}

  4.在cn.com.sharpxiajun.dao.impl包下实现接口ProductDao的类ProductDaoImpl,代码如下:

package cn.com.sharpxiajun.dao.impl;

import java.util.List;import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Scope;import org.springframework.orm.ibatis.SqlMapClientTemplate;import org.springframework.stereotype.Repository;

import cn.com.sharpxiajun.dao.ProductDao;

@SuppressWarnings("unchecked")@Scope("prototype")@Repository("productDao")public class ProductDaoImpl implements ProductDao {

    @Autowired    @Qualifier("sqlMapClientTemplate")private SqlMapClientTemplate sqlMapClientTemplate = null;

    @Overridepublic List<Map<String, Object>> queryProductList(Map<String, Object> params)throws Exception {return this.sqlMapClientTemplate.queryForList(QUERY_PRODUCT_LIST_SQL, params);    }

}

  5.在cn.com.sharpxiajun.service包下建立接口ProductService,代码如下:

package cn.com.sharpxiajun.service;

import java.util.List;import java.util.Map;

public interface ProductService {

public List<Map<String, Object>> queryProductList(Map<String, Object> params) throws Exception;

}

  6.在cn.com.sharpxiajun.service.impl包下建立ProductServiceImpl,他实现ProductService接口,代码如下:

package cn.com.sharpxiajun.service.impl;

import java.util.List;import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;

import cn.com.sharpxiajun.dao.ProductDao;import cn.com.sharpxiajun.service.ProductService;

@SuppressWarnings("unchecked")@Scope("prototype")@Transactional@Service("productService")public class ProductServiceImpl implements ProductService {

    @Autowired    @Qualifier("productDao")private ProductDao productDao = null;

    @Overridepublic List<Map<String, Object>> queryProductList(Map<String, Object> params)throws Exception {return this.productDao.queryProductList(params);    }

}

  7.在cn.com.sharpxiajun.action包下建立ProductAction,代码如下:

package cn.com.sharpxiajun.action;

import java.sql.Date;import java.util.HashMap;import java.util.List;import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;

import cn.com.sharpxiajun.common.action.BaseAction;import cn.com.sharpxiajun.service.ProductService;

@SuppressWarnings("serial")@Scope("prototype")@Controller("productAction")public class ProductAction extends BaseAction {

    @Autowired    @Qualifier("productService")private ProductService productService = null;

//输入值    private String namequery = null;

private Integer id = 0;private String name = null;private String desc = null;private Date createDate = null;private Date modifyDate = null;private Boolean status = null;

//输出值    private List<Map<String, Object>> results = null;//返回查询的列表    private String msg = null;//系统运行信息    private String flag = null;//操作状态标记    private String welcome = null;//欢迎语

public String productinit() throws Exception    {        welcome = "欢迎使用本系统!";

return SUCCESS;    }

public String queryProductList() throws Exception    {        Map<String, Object> map = new HashMap<String, Object>();        map.put("name", namequery);

        results = this.productService.queryProductList(map);

        flag = "success";        msg = "查询操作成功!";        welcome = "你的查询操作已经完成!";

return SUCCESS;    }

public Integer getId() {return id;    }public void setId(Integer id) {this.id = id;    }public String getName() {return name;    }public void setName(String name) {this.name = name;    }public String getDesc() {return desc;    }public void setDesc(String desc) {this.desc = desc;    }public Date getCreateDate() {return createDate;    }public void setCreateDate(Date createDate) {this.createDate = createDate;    }public Date getModifyDate() {return modifyDate;    }public void setModifyDate(Date modifyDate) {this.modifyDate = modifyDate;    }public Boolean getStatus() {return status;    }public void setStatus(Boolean status) {this.status = status;    }public List<Map<String, Object>> getResults() {return results;    }public void setResults(List<Map<String, Object>> results) {this.results = results;    }public String getMsg() {return msg;    }public void setMsg(String msg) {this.msg = msg;    }public String getFlag() {return flag;    }public void setFlag(String flag) {this.flag = flag;    }public String getWelcome() {return welcome;    }public void setWelcome(String welcome) {this.welcome = welcome;    }

public String getNamequery() {return namequery;    }

public void setNamequery(String namequery) {this.namequery = namequery;    }

}

  8.在WEB-INF\jsp包下,建立product.jsp文件,代码如下:

  要在struts2程序里使用json,首先http://code.google.com/p/jsonplugin/downloads/list下载JSON插件的JAR包,我下载的版本是jsonplugin-0.34.jar,把jar包加入到工程的lib里,修改conf包下的struts-action.xml文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"    "http://struts.apache.org/dtds/struts-2.1.dtd"><struts><package name="action" extends ="struts-default"><action name="queryUsersList" class="usersAction" method="queryUsersList"><result name="success">/WEB-INF/jsp/users.jsp</result></action>    <action name="usersinit" class="usersAction" method="usersinit"><result name="success">/WEB-INF/jsp/users.jsp</result></action><action name="addUsers" class="usersAction" method="addUsers"><result name="success">/WEB-INF/jsp/users.jsp</result><result name="error">/WEB-INF/common/error.jsp</result></action></package><package name="json" extends ="json-default"><action name="productinit" class="productAction" method="productinit"><result name="success">/WEB-INF/jsp/product.jsp</result></action><action name="queryProductList" class="productAction" method="queryProductList"><result name="success" type="json"></result></action>    </package></struts>

  上面配置文件的“package”元素和以往不同的是,它扩展了“json-default”而不是“struts-default”。“json-default”是在jsonplugin-0.34.jar包里的struts-plugin.xml中定义的。该文件同时定义了“json”的结果类型,有兴趣的朋友可以打开此文件看看。

  下面我们启动tomcat服务器,在浏览器地址栏里填入下面地址:http://localhost:8080/ssiprj/productinit.action

  页面如下图:

  点击按钮query,结果是:

  选择用记事本打开,显示结果如下:

{"createDate":null,"desc":null,"flag":"success","id":0,"modifyDate":null,"msg":"查询操作成功!","name":null,"namequery":"","results":

[{"id":1,"desc":"apple","create_date":"2011-10-28T00:00:00","status":true,"modify_date":"2011-10-28T00:00:00","name":"ipad"},

{"id":2,"desc":"google","create_date":"2011-10-28T00:00:00","status":true,"modify_date":"2011-10-28T00:00:00","name":"android"}],"status":null,"welcome":"你的查询操作

已经完成!"}

  结果居然是一个下载的文本文件,这个不符合我们的要求,下面我用ajax技术来处理这些返回结果。

  AJAX技术:服务端返回客户端JSON数据

  上面的例子里,我们服务端程序返回到前端页面的数据格式是json方式,下面的程序就是使用ajax来访问服务端程序并且展示页面如何处理json对象,这里我们只需要修改product.jsp代码,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>JSON</title></head><body>名称:<input type="text" id="namequery" name="namequery"/> &nbsp;&nbsp;<input type="button" onClick="queryBtnClick();" value="query"/><div id="datashow"></div></body></html><script src="<%= request.getContextPath()%>/js/json.js"/></script><script type="text/javascript">var xmlHttp;//XMLHttpRequest对象

//创建XMLHttpRequest对象function createXMLHttpRequest(){if (window.ActiveXobject)    {        xmlHttp =new ActiveXOject('Microsoft.XMLHTTP');    }elseif (window.XMLHttpRequest)    {        xmlHttp =new XMLHttpRequest();    }}

//查询操作function queryBtnClick(){var url ="queryProductList.action";    createXMLHttpRequest();    xmlHttp.open("POST",url,true);    xmlHttp.onreadystatechange = jsonCallBack;    xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");//使用POST传递信息时候用到的    xmlHttp.send(null);}

//处理返回数据的回调函数function jsonCallBack(){if (xmlHttp.readyState ==4)    {if (xmlHttp.status ==200)        {            parseResults();        }    }}

//处理返回数据的方法function parseResults(){var product = eval('('+ xmlHttp.responseText +')');var showstr ="<table border='1'>";for (var i =0;i < product.results.length;i++)    {        obj = product.results[i];        showstr +='<tr>';        showstr +='<td>'+ obj.id +'</td>';        showstr +='<td>'+ obj.name +'</td>';        showstr +='<td>'+ obj.desc +'</td>';        showstr +='<td>'+ obj.create_date +'</td>';        showstr +='<td>'+ obj.modify_date +'</td>';        showstr +='<td>'+ obj.status +'</td>';        showstr +='</tr>';    }    showstr +='</table>';    document.getElementById('datashow').innerHTML = showstr;}

</script>

  这次提交服务端请求里没有放入任何参数,也就是说前端没有传参数到服务端,因此这个测试代码就是展示ajax是如何调用的以及如何处理返回数据是json格式的数据,我们点击页面的query按钮,结果如下:

  大家看到了数据成功返回并且被正确处理。

  AJAX技术:客户端传给服务端JSON数据

  大家在http://www.json.org/网站里下载json.js脚本以及json在java里的操作类,我下载了这些文件,把他们放到我写的工程里,结果如下:

  (我发现我的jsp文件夹放的位置不对了,导致最后在struts-action.xml里面放回页面前还要加/WEB-INF/,哎,算了,将错就错吧!)

  我们修改ProductAction.java文件,代码如下:

package cn.com.sharpxiajun.action;

import java.sql.Date;import java.util.HashMap;import java.util.List;import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;

import cn.com.sharpxiajun.common.action.BaseAction;import cn.com.sharpxiajun.common.util.JSONObject;import cn.com.sharpxiajun.service.ProductService;

@SuppressWarnings("serial")@Scope("prototype")@Controller("productAction")public class ProductAction extends BaseAction {

    @Autowired    @Qualifier("productService")private ProductService productService = null;

//输入值    private String namequery = null;

private Integer id = 0;private String name = null;private String desc = null;private Date createDate = null;private Date modifyDate = null;private Boolean status = null;

private String jsonQuery = null;//获得json格式的参数

//输出值    private List<Map<String, Object>> results = null;//返回查询的列表    private String msg = null;//系统运行信息    private String flag = null;//操作状态标记    private String welcome = null;//欢迎语

public String productinit() throws Exception    {        welcome = "欢迎使用本系统!";

return SUCCESS;    }

public String queryProductList() throws Exception    {        Map<String, Object> map = new HashMap<String, Object>();//map.put("name", namequery);

        JSONObject jsonObject = new JSONObject(jsonQuery);//把查询参数转化为json对象

        map.put("name", jsonObject.get("namequery"));

        results = this.productService.queryProductList(map);

        flag = "success";        msg = "查询操作成功!";        welcome = "你的查询操作已经完成!";

return SUCCESS;    }

public Integer getId() {return id;    }public void setId(Integer id) {this.id = id;    }public String getName() {return name;    }public void setName(String name) {this.name = name;    }public String getDesc() {return desc;    }public void setDesc(String desc) {this.desc = desc;    }public Date getCreateDate() {return createDate;    }public void setCreateDate(Date createDate) {this.createDate = createDate;    }public Date getModifyDate() {return modifyDate;    }public void setModifyDate(Date modifyDate) {this.modifyDate = modifyDate;    }public Boolean getStatus() {return status;    }public void setStatus(Boolean status) {this.status = status;    }public List<Map<String, Object>> getResults() {return results;    }public void setResults(List<Map<String, Object>> results) {this.results = results;    }public String getMsg() {return msg;    }public void setMsg(String msg) {this.msg = msg;    }public String getFlag() {return flag;    }public void setFlag(String flag) {this.flag = flag;    }public String getWelcome() {return welcome;    }public void setWelcome(String welcome) {this.welcome = welcome;    }

public String getNamequery() {return namequery;    }

public void setNamequery(String namequery) {this.namequery = namequery;    }

public String getJsonQuery() {return jsonQuery;    }

public void setJsonQuery(String jsonQuery) {this.jsonQuery = jsonQuery;    }

}

  修改页面product.jsp,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>JSON</title></head><body>名称:<input type="text" id="namequery" name="namequery"/> &nbsp;&nbsp;<input type="button" onClick="queryBtnClick();" value="query"/><div id="datashow"></div></body></html><script src="<%= request.getContextPath()%>/js/json.js"/></script><script type="text/javascript">var xmlHttp;//XMLHttpRequest对象

//创建XMLHttpRequest对象function createXMLHttpRequest(){if (window.ActiveXobject)    {        xmlHttp =new ActiveXOject('Microsoft.XMLHTTP');    }elseif (window.XMLHttpRequest)    {        xmlHttp =new XMLHttpRequest();    }}

//查询操作function queryBtnClick(){var url ="queryProductList.action";    createXMLHttpRequest();    xmlHttp.open("POST",url,true);    xmlHttp.onreadystatechange = jsonCallBack;var obj = getQueryParams();//获取查询参数对象var queryJson ="jsonQuery="+ JSON.stringify(obj);//构建查询参数    xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");//使用POST传递信息时候用到的    xmlHttp.send(queryJson);//将参数发送到服务端}

//处理返回数据的回调函数function jsonCallBack(){if (xmlHttp.readyState ==4)    {if (xmlHttp.status ==200)        {            parseResults();        }    }}

//处理返回数据的方法function parseResults(){var product = eval('('+ xmlHttp.responseText +')');var showstr ="<table border='1'>";for (var i =0;i < product.results.length;i++)    {        obj = product.results[i];        showstr +='<tr>';        showstr +='<td>'+ obj.id +'</td>';        showstr +='<td>'+ obj.name +'</td>';        showstr +='<td>'+ obj.desc +'</td>';        showstr +='<td>'+ obj.create_date +'</td>';        showstr +='<td>'+ obj.modify_date +'</td>';        showstr +='<td>'+ obj.status +'</td>';        showstr +='</tr>';    }    showstr +='</table>';    document.getElementById('datashow').innerHTML = showstr;}

//获取查询参数对象function getQueryParams(){returnnew queryObj();}

//构建查询参数类function queryObj(){this.namequery = document.getElementById('namequery').value;}</script>

  代码里面我写了注释,这里就不做过多解释了。

  我们在浏览器地址栏里录入:http://localhost:8080/ssiprj/productinit.action,在名称框里录入ipad,点击query查询按钮,结果如下:

  控制台打印日志:

|statement| select t.id,t.name,t.desc,t.create_date,t.modify_date,t.status from product t where t.name = 'ipad' |resultset||commit|返回结果是:[{id=1, desc=apple, create_date=2011-10-28, status=true, modify_date=2011-10-28, name=ipad}]拦截器执行结束!!

  操作成功了!!!!

  最后总结下了:struts2把返回给客户端的数据封装成json格式,前端再处理,这个做起来很自然,也带来了编写代码的便利,但是从客户端到服务端这种做法就有点奇怪了,至少没有看到便利之处,当然今天写的代码都很简单,没有把许多功能抽象出来,不管怎样,让action把返回值封装成json,前端的参数也封装成json格式这就是我的框架里面所追求的。下一篇文章我将引入jquery了,为了展示数据我会使用到jqgrid,下一个阶段我将着重写写前端技术。

转载于:https://www.cnblogs.com/sharpxiajun/archive/2011/10/29/2228290.html

java笔记:自己动手写javaEE框架(七)--使用JSON和Ajax技术相关推荐

  1. java笔记:自己动手写javaEE

    写这篇博客前,我有个技术难题想请教大家,不知道谁有很好的建议,做过互联网的童鞋应该都知道,有点规模的大公司都会做用户行为分析系统,而且有些大公司还会提供专业的用户行为分析解决方案例如:百度分析,goo ...

  2. 自己动手写ORM框架

    自己动手写ORM框架(九):实现删除功能Remove方法 奋斗 2010-07-03 19:29 阅读:1962 评论:6   自己动手写ORM框架(八):实现修改功能Update方法 奋斗 2010 ...

  3. php怎么自己写框架,PHP学习笔记,自己动手写个MVC的框架

    最新在大家自己的博客的过程中,发现各种开源的博客系统都或多或少的用起来别扭.于是想动手自己写个博客系统.既然写,就想好好写.那就先写个MVC框架.一点一点来.写的过程中有很多想法.还希望大家能够多多指 ...

  4. iOS学习笔记-自己动手写RESideMenu

    代码地址如下: http://www.demodashi.com/demo/11683.html 很多app都实现了类似RESideMenu的效果,RESideMenu是Github上面一个stars ...

  5. 【Java ORM】手写ORM框架:源代码、jar、生成JavaDoc文档

    SORMSourceCode 把这个手写框架取名为SORM. (1)源代码(Eclipse项目文件):GitHub地址 (2)jar包.源代码.JavaDoc文档.使用说明:Github地址 一个简单 ...

  6. 核心技术靠化缘是要不来的——自己动手写ORM框架

    开源市场上的Java的ORM框架一个都不好用,所以花了几天时间自己撸了一个 OrmKids,欢迎大家下载学习.遇到问题请关注公众号进群大家一起讨论. OrmKids 支持分库分表的MySQL单表ORM ...

  7. 自己动手写ORM框架(六):实现查询功能FindById方法

    通过配置实体与表的关系映射后,就可以实现对表的操作了,接下来实现简单对象的新增功能.下面代码1-1是定义的操作数据对象方法的接口: using System; using System.Collect ...

  8. 《JavaEE框架整合开发入门到实战——Spring+SpringMVC+MyBatis》读书笔记

    加油生活,嗯,希望假期可以把这本书刷完,新年快乐,嘻嘻,今天是旧的一年里最后的一天,嗯,除夕一过,就25岁啦.希望新的一年里,学更多的东西,认识优秀的人,希望家人健康平安,希望自己少一些烦恼,总之先学 ...

  9. 深入理解JDK动态代理原理,使用javassist动手写一个动态代理框架

    文章目录 系列文章索引 一.动手实现一个动态代理框架 1.初识javassist 2.使用javassist实现一个动态代理框架 二.JDK动态代理 1.编码实现 2.基本原理 (1)getProxy ...

最新文章

  1. mysql 实现yyyyww_java – LocalDate无法使用’yyyy’解析’ww’
  2. P1082-扩欧模板同余方程【扩欧,数论】
  3. JavaScript 中的string 方法
  4. 微信开发者工具(deepin linux 还是建议使用deppin深度商店安装此软件)
  5. 自行更换iPhone 13屏幕会导致Face ID失效?苹果将发布软件更新解除限制
  6. Session优缺点
  7. LOJ#3083. 「GXOI / GZOI2019」与或和(单调栈)
  8. 翻译:《CSS权威指南》(第3版)-概览和目录部分
  9. 【Java视频教程等百度云资源分享】
  10. 车机没有carlife可以自己下载吗_论互联哪家强 Carlife/Carplay针尖对麦芒
  11. CSAPP第八章家庭作业参考答案
  12. C++ STL 思维导图,脑图,树形图。
  13. 摸鱼:窗口最小化等快捷键
  14. 计算机与打印机怎么连接,如何连接打印机,教您电脑如何与打印机连接
  15. pdf文件怎么拆分页面为多个pdf
  16. python实现千牛客服自动回复语_千牛客服自动回复话术
  17. unity地形模块学习
  18. 申探社:深入互联网广告中的出价模式(上)— 基础出价模式
  19. 中国文化概论名词解释题
  20. halcon sobel 边缘检测 sobel_dir

热门文章

  1. 持续集成之Jenkins安装部署
  2. IS环境下配置PHP5+MySql+PHPMyAdmin
  3. rollup学习小记
  4. CentOS 7 使用 ACL 设置文件权限
  5. 计算机视觉-自定义对象检测器
  6. Python Configparser模块读取、写入配置文件
  7. 美国Palmbeach大学服务器整合改造案例
  8. oracle解析儒略日,利用to_char获取当前日期准确的周数!
  9. 数据多重共线性_多重共线性对您的数据科学项目的影响比您所知道的要多
  10. 1893. 检查是否区域内所有整数都被覆盖