[TOC]

0x00 简述

前面我们说过JavaEE的结构,下面我们又来说说三层结构以及与MVC模式的关联;

  • JavaEE结构:客户端-Web端-业务逻辑层-数据访问层
  • 三层结构:Web层(Servlet/JSP) - 业务逻辑层(Ejb 、JavaBean) - 数据访问层(Dao)

什么是MVC模式?

  • M(Model):模型层主要封装数据采用JavaBean (如:EJB)
  • V(View):视图层JSP负责显示
  • C(Controller):控制层 Serlvet 接受页面请求,然后采用模型层的方法,然后将返回的数据给视图层;


开发模式种类:
开发模式1:JavaBean + JSP

  • 优点:直接在jsp中写java代码
  • 缺点: 后期维护困难代码臃肿
    开发模式2:Servlet + JavaBean + JSP
  • 优点: 对于大型项目分层、逻辑比较清楚、便于维护、扩展方便.
  • 缺点: 小型项目如果严格准守MVC代码量增加了.


三层结构与MVC模式的关系:

WeiyiGeek.

WeiyiGeek.


三层结构的实现操作:

环境基础设置:

  • JDBC
  • commons-dbutils : 对JDBC进行简单的CURDS封装
  • c3p0 : JDBC 连接池

思路原理是最重要的:我们在Dao的前面加入一个业务逻辑服务层(Service),这是由于Dao在实际开发中只做一件事情那就是数据库CURD,而我们为了开发的规范将服务层放置于Servlet与Dao之间,比如下图所示(重点);

WeiyiGeek.三层结构原理

WeiyiGeek.三层结构原理


测试数据表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE DATABASE works;
use works;
CREATE TABLE `person` (
`sid` INT PRIMARY KEY AUTO_INCREMENT,
`sname` VARCHAR(20) NOT NULL,
`gender` VARCHAR(5) DEFAULT '未知' COMMENT '性别',
`telephone` VARCHAR(15) NOT NULL,
`job` VARCHAR(200) NOT NULL,
`info` VARCHAR(200),
`jointime` DATE NOT NULL
);

CREATE TABLE `record` (
`sid` INT COMMENT '用户ID',
`type` NOT NULL COMMENT '类型1加班调休调休、2.加班费申请、3.调休申请、4.请假申请、5.年假申请',
`day` DATE NOT NULL,
CONSTRAINT fk_person FOREIGN KEY (`sid`) REFERENCES person(`sid`)
);

总结:
描述:利用MVC的设计理念,建立一个servlet单独处理数据库流程

  • 1.Dao 利用 数据库 连接的jar包进行数据库相关的CURD,以及异常抛出
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //常常是接口的实现类
    public class UserDao {
    public boolean find() throw SQLException{
    try{
    //执行的SQL
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
  • 2.Service 根据业务校验数据并进行异常抛出;
    1
    2
    3
    4
    5
    6
    7
    public class LoginUserService() throw Exception,SQLException {
    try {
    //数据效验
    } catch (Exception e){
    throw new Exception("数据校验说明");
    }
    }
  • 3.每一个servlet中接收产生的异常处理并打印
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class UserLoginServlet extends Servlet{
    void doGet(request,response){
    try {
    //功能处理
    } catch (Exception e) {
    //错误处理以及错误打印
    }
    }
    }

0x01 实例

项目文件结构以及依赖的jar库:

WeiyiGeek.

WeiyiGeek.

Person 数据类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Person {
private int sid;
private String sname;
private String gender;
private String telephone;
private String job;
private String info;
private Date jointime;

//构造方法
public Person() {
super();
// TODO Auto-generated constructor stub
}
//插入指定的sid
public Person(int sid, String sname, String gender, String telephone, String job, String info, Date jointime) {
super();
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.telephone = telephone;
this.job = job;
this.info = info;
this.jointime = jointime;
}
//重写
public Person(String sname, String gender, String telephone, String job, String info, Date jointime) {
super();
this.sname = sname;
this.gender = gender;
this.telephone = telephone;
this.job = job;
this.info = info;
this.jointime = jointime;
}
...... //get / set 方法略去 (自动生成即可)
}


更新信息

文件结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#Dao
/Web/src/top/weiyigeek/dao/PersonDao.java #Dao 层接口
/Web/src/top/weiyigeek/dao/impl/PersonDaoImpl.java # Dao 层实现

#Service
/Web/src/top/weiyigeek/service/PersonService.java #Service 层接口
/Web/src/top/weiyigeek/service/impl/pagePersonServiceImp.java #Dervice 层接口

#Servlet
/Web/src/top/weiyigeek/servlet/editPersonServlet.java #编辑
/Web/src/top/weiyigeek/servlet/updatePersonServlet.java #更新

#JSP
/Web/WebContent/edit.jsp

主要代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 使用jstl内置函数 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<script>
function submit_check(){
if ( confirm("您是否进行更新提交?") ) {
return true;
}else{
return false;
}
}
</script>
<form action="updatePersonServlet" method="POST" onsubmit="return submit_check()">
<input type="hidden" name="sid" value="${person.sid }">
<!-- 采用表格会更好看一点 -->
<table border="1" width="auto" cellpadding="1" cellspacing="0">
<tr>
<td>姓名</td>
<td><input type="text" name="name" value="${person.sname }"></td>
</tr>
<tr>
<td>性别</td>
<td>
<input type="radio"
name="gender" value="男"
<c:if test="${person.gender == '男'}">checked</c:if>>男 <input
type="radio" name="gender" value="女"
<c:if test="${person.gender == '女'}">checked</c:if>>女
</td>
</tr>
<tr>
<td>电话</td>
<td><input type="text" name="telephone" value="${person.telephone }"></td>
</tr>
<tr>
<td>加入时间</td>
<td><input type="text" name="jointime" value="${person.jointime }"></td>
</tr>
<tr>
<td>job</td>
<td>
<input type="checkbox" name="job"value=安全
<c:if test="${fn:contains(person.job,'安全') }">checked</c:if>>安全
<input type="checkbox" name="job" value="运维"
<c:if test="${fn:contains(person.job,'运维') }">checked</c:if>>运维
<input type="checkbox" name="job" value="开发"
<c:if test="${fn:contains(person.job,'开发') }">checked</c:if>>开发
<input type="checkbox" name="job" value="测试"
<c:if test="${fn:contains(person.job,'测试') }">checked</c:if>>测试
<input type="checkbox" name="job" value="主管"
<c:if test="${fn:contains(person.job,'主管') }">checked</c:if>>主管
</td>
</tr>
<tr>
<td>简介</td>
<td><textarea name="info" rows="3" cols="20">${person.info }</textarea></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="更新"></td>
</tr>
</table>
</form>

Servlet 层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//editPersonServlet.java  
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取要更新资料的sid
int sid = Integer.parseInt(request.getParameter("sid"));

try {
//2.根据id获取其个人信息并返还对象给person(注意这里不是List集合)
PersonService ps = new PersonServiceImpl();
Person person = ps.getInfoById(sid);

//3.将数据存入内置作用域对象属性之中并进行跳转到edit.jsp取值
request.setAttribute("person", person);
request.getRequestDispatcher("edit.jsp").forward(request, response);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


//updatePersonServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//实际开发中能代码复用的时候一定要代码复用(减少体积)
//设置编码
request.setCharacterEncoding("utf-8");

try {
//获取收到的参数(实际开发中一定要过滤)
int sid = Integer.parseInt(request.getParameter("sid"));
String sname = request.getParameter("name");
String gender = request.getParameter("gender");
String telephone = request.getParameter("telephone");
String info = request.getParameter("info");
String jointime = request.getParameter("jointime");
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(jointime);

String [] j = request.getParameterValues("job");
String sj = Arrays.toString(j);
String job = sj.substring(1, sj.length()-1);

//将数据装载进对象
Person person = new Person(sid,sname,gender,telephone,job,info,date);

//利用服务层进行修改更新员工修改
PersonService ps = new PersonServiceImpl();
ps.updatePerson(person);

//重新跳转到全部员工信息页面(这里直接指定的是servlet而不是jsp文件由于这里插入了数据就要重新获取数据然后存入作用域之中)
request.getRequestDispatcher("findall").forward(request, response);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

service 层: 实现

1
2
3
4
5
6
7
8
9
10
11
@Override
public Person getInfoById(int sid) throws SQLException {
PersonDao delps = new PersonDaoImpl();
return delps.getInfoById(sid);
}

@Override
public void updatePerson(Person person) throws SQLException {
PersonDao delps = new PersonDaoImpl();
delps.updatePerson(person);
}

dao 层: 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* @throws SQLException
* @Desc : 以ID为条件进行查找
*/
@Override
public Person getInfoById(int sid) throws SQLException {
QueryRunner runner = new QueryRunner(DB.getConn());
return runner.query("SELECT * FROM person WHERE sid = ?", new BeanHandler<Person>(Person.class) ,sid);
}

/**
* @throws SQLException
* @Desc:更新人员的修改
*/
@Override
public void updatePerson(Person person) throws SQLException {
QueryRunner runner = new QueryRunner(DB.getConn());
int flag = runner.update("UPDATE person SET sname = ?,gender = ?,telephone = ?, job = ? , jointime = ?, info = ? WHERE sid = ?", person.getSname(), person.getGender(),person.getTelephone(),person.getJob(),person.getJointime(),person.getInfo(),person.getSid());
if(flag > 0) {
System.out.println("#更新成功");
}else {
System.out.println("#更新失败");
}
}

WeiyiGeek.

WeiyiGeek.


模糊查询

描述:结构与上面大致相同不同的是实现的JSP文件,直接上主要部分代码;

/Web/WebContent/findlist.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<form action="SearchPersonServlet" method="post">
<table border="1" width="auto" cellpadding="1" cellspacing="0">
<tr>
<td colspan="8">
按姓名查询:<input type="text" name="sname"/>
&nbsp;
按性别查询:<select name="sgender">
<option value="">--请选择--
<option value="男">男
<option value="女">女
</select>
&nbsp;&nbsp;&nbsp;
<input type="submit" value="查询">
&nbsp;&nbsp;&nbsp;
<a href="add.jsp">添加</a>
</td>
</tr>
<tr><th>SID</th><th>姓名</th><th>性别</th><th>电话号码</th><th>工作职位</th><th>加入时间</th><th>备注</th><th>操作</th></tr>
<!-- jstl 表达式 -->
<c:forEach items="${ PersonList }" var="person">
<tr>
<td>${person.sid}</td>
<td>${person.sname}</td>
<td>${person.gender}</td>
<td>${person.telephone}</td>
<td>${person.job}</td>
<td>${person.jointime}</td>
<td>${person.info}</td>
<td><a href="editPersonServlet?sid=${ person.sid }">修改</a> | <a href="#" onclick="doDelete(${person.sid})">删除</a></td>
</tr>
</c:forEach>
</table>
</form>

servlet 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1.获取参数的编码设置
request.setCharacterEncoding("utf-8");

//2.获取查询参数并传递给service层进行进一步的调用dao
String sname = request.getParameter("sname");
String gender = request.getParameter("sgender");
PersonService ps = new PersonServiceImpl();
List<Person> list = ps.searchPerson(sname, gender); //返回一个包含Person对象的List集合

//3.将获取的集合对象放入在作用域属性中
request.setAttribute("PersonList", list);

//4.跳转页面
request.getRequestDispatcher("findlist.jsp").forward(request, response);;

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Service 层:

1
2
3
4
@Override
public List<Person> searchPerson(String sname, String gender) throws SQLException {
return new PersonDaoImpl().searchPerson(sname,gender);
}

Dao 层:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public List<Person> searchPerson(String sname, String gender) throws SQLException {
QueryRunner runner = new QueryRunner(DB.getConn());
//情况1.如果姓名和性别都没选择时候默认显示全部
String sql = "SELECT * FROM person WHERE 1 = 1"; //值得学习
List<String> param = new ArrayList<String> (); //采用数组集合

// 判断传入的参数是否为空;
// public static boolean isEmpty(CharSequence s){
// return s==null || s.length() == 0;
// }

//判断有没有姓名, 如果有就组拼到sql语句里面 (重点了解)
if(sname.length()>0){
sql = sql + " and sname like ?";
param.add("%"+sname+"%"); //模糊查询精妙之处
}

//判断有没有性别,有的话,就组拼到sql语句里面。
if(gender.length()>0){
sql = sql + " and gender = ?";
param.add(gender);
}
System.out.println("执行的SQL: " + sql);
runner.getDataSource().getLogWriter();
return runner.query(sql , new BeanListHandler<Person>(Person.class) ,param.toArray());
}

执行效果:

WeiyiGeek.

WeiyiGeek.


分页实现

常用的分页方式有两种:

  • 1.物理分页:在进行SQL查询的时候加上获取的条数限制,优点:减少数据库访问负载;
  • 2.逻辑分页:将数据库中的数据读取到内存数据库中比如redis然后采用进行读取,优点:访问速度快;

项目文件结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
#Dao 数据库连接层
/Web/src/top/weiyigeek/dao/pagePersonDao.java #接口
/Web/src/top/weiyigeek/dao/impl/pagePersonDaoImp.java #实现

#Service 业务逻辑层
/Web/src/top/weiyigeek/service/pagePersonService.java #接口
/Web/src/top/weiyigeek/service/impl/pagePersonServiceImp.java #实现

#Servlet 网页请求处理
/Web/src/top/weiyigeek/servlet/pageList.java

#JSP 显示层
/Web/WebContent/pageShow.jsp

公共类:

1
2
3
4
5
6
7
8
9
10
11
12
package top.weiyigeek.main;

import java.util.List;

public class pagePerson {
private int currentPage; //显示第几页
private int showCount; //每页显示几条
private int pageTotal; //一共几页
private int total; //信息总条数
private List<Person> lp; //查询到的的数据
..... //此处忽略自动get 、 set 生成的代码
}

Dao 数据库操作实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package top.weiyigeek.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import top.weiyigeek.dao.pagePersonDao;
import top.weiyigeek.main.Person;
import top.weiyigeek.utils.DB;

public class pagePersonDaoImp implements pagePersonDao {

@Override
public List<Person> pagePersonData(int page, int count) throws SQLException {
QueryRunner runner = new QueryRunner(DB.getConn());
//参数1.显示的条数,参数2,显示第几页的数据(即offset不显示前面多少条)
return runner.query("SELECT * FROM person Limit ? offset ?", new BeanListHandler<Person>(Person.class),count, (page - 1) * count);
}

@Override
public int dataCount() throws SQLException {
QueryRunner runner = new QueryRunner(DB.getConn());
Long count = (Long)runner.query("SELECT COUNT(*) FROM person",new ScalarHandler());
return count.intValue();
}
}

Service 业务逻辑层实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package top.weiyigeek.service.impl;

import java.sql.SQLException;
import java.util.List;

import top.weiyigeek.dao.pagePersonDao;
import top.weiyigeek.dao.impl.pagePersonDaoImp;
import top.weiyigeek.main.Person;
import top.weiyigeek.main.pagePerson;
import top.weiyigeek.service.pagePersonService;

public class pagePersonServiceImp implements pagePersonService{

@Override
public pagePerson pageShow(int page, int count) throws SQLException {
//实例化对象(父类引用指向子类对象)
pagePersonDao ppd = new pagePersonDaoImp();
pagePerson pp = new pagePerson();

//存储从Dao模型中实现数据库查询的所返回的信息
List<Person> person = ppd.pagePersonData(page,count);
int resultCount = ppd.dataCount();

//将值存储进分页自定义类中
pp.setLp(person); //查询到数据(List 集合)
pp.setCurrentPage(page); //查询第几页
pp.setShowCount(count); //每页显示多少条
pp.setTotal(resultCount); //数据总条数
pp.setPageTotal(resultCount % count == 0 ? resultCount / count : (resultCount / count) + 1 ); //总页数 (看是否可以除尽,否则+1)
return pp;
}
}

Servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1.获取显示的页数以及每页显示好多条
int page = Integer.parseInt(request.getParameter("page"));
int count = Integer.parseInt(request.getParameter("count"));

//2.调用服务类并返回查询到数据包括条数 当前页数 、总页数
pagePersonService pps = new pagePersonServiceImp();
pagePerson pp = pps.pageShow(page, count);

//3.将对象存进作用域之中
request.setAttribute("page", pp);

//4.跳转分页显示页面
request.getRequestDispatcher("pageShow.jsp").forward(request, response);

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

JSP(采用jstl) 展示层:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<table border="1" width="auto" cellpadding="1" cellspacing="0">
<tr><th>SID</th><th>姓名</th><th>性别</th><th>电话号码</th><th>工作职位</th><th>加入时间</th><th>备注</th><th>操作</th></tr>
<!-- jstl 表达式 -->
<c:forEach items="${page.lp }" var="person">
<tr>
<td>${person.sid}</td>
<td>${person.sname}</td>
<td>${person.gender}</td>
<td>${person.telephone}</td>
<td>${person.job}</td>
<td>${person.jointime}</td>
<td>${person.info}</td>
<td><a href="editPersonServlet?sid=${person.sid }">修改</a> | <a href="#" onclick="doDelete(${person.sid})">删除</a></td>
</tr>
</c:forEach>
<tr>
<!--
private int currentPage; //显示第几页
private int showCount; //每页显示几条
private int pageTotal; //一共几页
private int total; //信息总条数
private List<Person> lp; //查询到的的数据
-->
<td colspan="8">
第 ${page.currentPage} / ${page.pageTotal} 页 &nbsp; &nbsp;
每页显示:${page.showCount} 条 &nbsp;&nbsp;
总共有:${page.total} 条 &nbsp; &nbsp;
<c:if test="${ page.currentPage != 1 }">
<a href="pageList?page=1&count=${page.showCount}">首页</a> &nbsp;
<a href="pageList?page=${page.currentPage - 1}&count=${page.showCount}">上一页 </a> &nbsp; |
</c:if>

<!-- 遍历显示页数(坑呀-值得学习),实际情况下采用Bootstrap直接生成即可 -->
<c:forEach begin="1" end="${page.pageTotal}" var="i">
<c:if test="${page.currentPage == i}">
<span style="color:red">${page.currentPage}</span> &nbsp;
</c:if>
<c:if test="${page.currentPage != i}">
<a href="pageList?page=${i}&count=${page.showCount}">${i}</a> &nbsp;
</c:if>
</c:forEach>


<c:if test="${ page.currentPage != page.pageTotal }">
| <a href="pageList?page=${page.currentPage + 1}&count=${page.showCount}">下一页 </a> &nbsp;
<a href="pageList?page=${page.pageTotal}&count=${page.showCount}">末页 </a>
</c:if>

</td>
<tr>
</table>

执行效果:

WeiyiGeek.

WeiyiGeek.


0x02 Ajax & JQuery

描述:补充复习前端知识(详细请看Javascript以及jQuery):

常用的JS框架:

  • JQuery:轻量级,众多的插件
  • Prototype
  • dojo
  • dwr
  • Extjs:表格功能强大;
  • YUI

Q:Ajax是什么?有什么用?
A: “Asynchronous Javascript And XML”(异步JavaScript和XML),可以让网页局部进行更新;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function getXMLHttpRequest() {
var xmlHttpReq=null;
if (window.XMLHttpRequest) {//Mozilla 浏览器
xmlHttpReq = new XMLHttpRequest();
}else {
if (window.ActiveXObject) {//IE 浏览器
try {
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
try {//IE 浏览器
xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
}
}
}
}
return xmlHttpReq;
}

GET/POST集成请求示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//执行get请求
function get() {
//1. 创建xmlhttprequest 对象
var request = ajaxFunction();
//2. 发送请求
request.open("GET" ,"/day16/DemoServlet01?name=aa&age=18" ,true );
//3. 获取响应数据 注册监听的意思。 一会准备的状态发生了改变,那么就执行 = 号右边的方法
request.onreadystatechange = function(){
//前半段表示 已经能够正常处理。 再判断状态码是否是200
if(request.readyState == 4 && request.status == 200){
alert(request.responseText); //弹出响应的信息
}
}
request.send();
}


//post数据请求
function post() {
//1. 创建对象
var request = ajaxFunction();
//2. 发送请求
request.open( "POST", "/day16/DemoServlet01", true );
//想获取服务器传送过来的数据, 加一个状态的监听。
request.onreadystatechange=function(){
if(request.readyState==4 && request.status == 200){

alert("post:"+request.responseText);
}
}
//如果使用的是post方式带数据,那么 这里要添加头, 说明提交的数据类型是一个经过url编码的form表单数据
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//带数据过去 , 在send方法里面写表单数据。
request.send("name=aobama&age=19");
}

Q:JQuery 是什么?有什么用?
A:javascript 的代码框架,目的简化代码提高效率write less do more , 写得更少,做的更多

load & get & post 使用案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
* load
$("#元素id").load(url地址);
$("#div1").load(serlvet); ---> 使用的get请求,回来赋值的时候,使用text() ;去赋值

* get
语法格式:$.get(URL,callback);
使用案例:$.get("/day16/DemoServlet02" , function(data ,status) {
$("#div01").text(data);
});

* post
语法格式:$.post(URL,data,callback);
function post() {
$.post("/day16/DemoServlet02", {name:"zhangsan",age:18},function(data,status) {
$("#div01").html(data); //想要放数据到div里面去。 --- 找到div
$(data).each(function(index,c){
console.log("索引:"+index,"值:"+c.name);
});
});
}

数据在服务端与客户端数据传输方式

  • xml:节点清晰,传输大文本字段
  • json:阅读性更好,容量更小;


异步查询

描述:采用原生的Ajax与JQuery封装过后的Ajax进行实现;

(1) View 层展现 : /Web/WebContent/syncRequest.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>异步查询用户名称是否存在</title>
<!-- Jquery 引入外部 JS -->
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
//## (1)原生JS实现Ajax异步请求
function checkUser(){
//1.创建ajax请求对象
var request = window.XMLHttpRequest ? new XMLHttpRequest():new ActiveXObject("msxml2.XMLHTTP") ? new ActiveXObject("msxml2.XMLHTTP"):new ActiveXObject("Microsoft.XMLHTTP");

//2.获取输入的用户名
var user = document.getElementById("username").value;

//3.ajax请求
request.open("POST","CheckUserServlet",true);
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.onreadystatechange = function(){
if(request.readyState == 4 && request.status == 200){
//解析返回得JSON字符串
var jsondata=eval("("+request.responseText+")");
if(!jsondata.status){
document.getElementById("msg").innerHTML = "<font color='red'>用户名已存在!</font>";
}else{
document.getElementById("msg").innerHTML = "<font color='green'>用户名可用!</font>";
}
}
}
request.send("checkuser="+user);
}

//## (2)JQuery实现Ajax异步请求(文档加载完毕时候进行)
$("document").ready(function(){
$("#name").blur(function(){
var user = $(this).val();
console.log(user);
$.post("CheckUserServlet",{checkuser:user},function(data,status){
if (status == "success"){
//Jquery 直接解析 json
if(data.status){
$("#msg1").html("<font color='green'>姓名可用!</font>");
}else{
$("#msg1").html("<font color='red'>姓名已存在!</font>");
}
}
});
});
});

</script>
<div align="center">
<form action="RegisterServlet">
<label for="username">用户名:</label>
<input type="text" name="username" id="username" onblur="checkUser()"/> &nbsp; <span id="msg"></span><br>
<label for="name">真实姓名:</label>
<input type="text" name="username" id="name"/> &nbsp; <span id="msg1"></span> <br>
<input type="submit" value="注册"/>
</form>
</div>
<br>
</body>
</html>

(2) Dao 层实现: /Web/src/top/weiyigeek/dao/impl/UserDaoimpl.java

1
2
3
4
5
6
7
8
9
10
public class UserDaoimpl implements UserDao {
@Override
public int checkUser(String name) throws SQLException {
//1.建立数据连接、
QueryRunner runner = new QueryRunner(DB.getConn());
Long result = (Long) runner.query("SELECT COUNT(*) FROM user WHERE name = ?",new ScalarHandler(), name);
System.out.println("查询完成");
return result.intValue();
}
}

(3) Service 层实现: /Web/src/top/weiyigeek/service/impl/UserServiceImpl.java

1
2
3
4
5
6
7
public class UserServiceImpl implements UserService {
@Override
public int checkUser(String name) throws SQLException {
UserDao ud = new UserDaoimpl();
return ud.checkUser(name);
}
}

(4) Service 层实现:/Web/src/top/weiyigeek/servlet/CheckUserServlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1.设置编码并获取传入的值
request.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
String name = request.getParameter("checkuser");

//2.调用Service层中的方法进行实现验证
UserService service = new UserServiceImpl();
int res = service.checkUser(name);
System.out.println(name+ " = " + res);

//3.返还数据
if (res == 0 ) {
//(1)文本数据
//response.getWriter().println(1);

//(2)json数据(这里采用手动设置,后面采用专门得json库进行设置)
response.getWriter().write("{ \"status\": true }");
}else {
response.getWriter().write("{ \"status\": false }");
}

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

示例结果:

WeiyiGeek.

WeiyiGeek.


异步关键字搜寻

描述:采用Servlet 与 JQuery实现模仿百度搜索,以下为关键代码;

(1) Dao接口实现:/Web/src/top/weiyigeek/dao/impl/SearchDaoimpl.java

1
2
3
4
5
6
7
public class SearchDaoimpl implements SearchDao {
@Override
public List<SearchBean> findWords(String key) throws SQLException {
QueryRunner runner = new QueryRunner(DB.getConn());
return runner.query("SELECT * FROM page WHERE title like ? limit ?", new BeanListHandler<SearchBean>(SearchBean.class), key+"%",5);
}
}

(2) Service实现:/Web/src/top/weiyigeek/service/impl/SearchServiceImpl.java

1
2
3
4
5
6
7
public class SearchServiceImpl implements SearchService {
@Override
public List<SearchBean> findWords(String keys) throws SQLException {
SearchDao sd = new SearchDaoimpl();
return sd.findWords(keys);
}
}

(3) Servlet:/Web/src/top/weiyigeek/servlet/SearchServlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class SearchServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//编码与参数获取
request.setCharacterEncoding("UTF-8");
String keys = request.getParameter("words");

//调用service层执行数据库Dao
SearchService ss = new SearchServiceImpl();
List<SearchBean> result = ss.findWords(keys);

System.out.println("--------- 查询到的数据 ------------");
for(SearchBean word: result) {
System.out.println("#"+word.toString());
}
//返回查询到的数据
request.setAttribute("words", result);
request.getRequestDispatcher("listSearch.jsp").forward(request, response);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}

(4) JSP View页面: /Web/WebContent/baidu.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>极客搜索</title>
<!-- Jquery 引入外部 JS -->
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
//Jquery使用方式之一
$(function(){
$("#key").keyup(function(){
$.post("SearchServlet",{words:$(this).val()},function(data,status){
$("#result").show();
$("#result").html(data);
});
});
});

//设置搜索关键字为查询得关键字
function setting(x){
$("#key").val(x.innerText);
}

</script>
<div class="main" align="center">
<h3>极客搜索</h3> <br>
<input type="text" placeholder="搜索您想要的" id="key" name="key" style="width:600px;height:25px"/> &nbsp; &nbsp;
<input type="submit" value="极客搜索"/>
<br>
<div id="result" align="left" style="position:relative;left: -56px;border:1px solid black;display: none;width:600px;"></div>
</div>
</body>
</html>

(5) 数据存放页面:/Web/WebContent/listSearch.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:forEach items="${words}" var="word">
<span style="font-size:x-small;" align="left" onclick="setting(this)">${word.title }</span>
<span style="width: 100%;display: block;border: 0.1px solid black"></span>
</c:forEach>
</body>
</html>

示例结果:

WeiyiGeek.搜索模仿

WeiyiGeek.搜索模仿


0x03 XML

省市联动

描述:通过xstream将获取到的对象装换成为XML,并且响应给客户端然后jQuery解析xml在页面添加数据;

lib库依赖导包:xpp3_min-1.1.4c.jar / xstream-1.4.4.jar

案例SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
--省市
create table province (
`pid` smallint primary key COMMENT '省市id',
`pname` varchar(16) not null COMMENT '省市名称'
);

--城市
create table city (
`cid` smallint primary key COMMENT '城市区县',
`cname` varchar(32) not null COMMENT '市区名称',
`pid` smallint not null COMMENT '外键省市id,必须字段',
CONSTRAINT fk_id FOREIGN KEY(pid)
REFERENCES province(pid)
);


insert into province values (1,"北京"),(2,"上海"),(3,"重庆"),(4,"四川"),(5,"西藏");
insert into city values (1,'东城区',1),(2,'西城区',1),(3,'朝阳区',1),(4,'丰台区',1),(5,"石景山区",1);
insert into city values (6,'黄浦区',2),(7,'徐汇区',2),(8,'长宁区',2),(9,'静安区',2),(10,"杨浦区",2);
insert into city values (11,'江北区',3),(12,'渝北区',3),(13,'南岸区',3),(14,'九龙坡区',3),(15,"沙坪坝区",3);
insert into city values (16,'武侯区',4),(17,'武侯区',4),(18,'武侯区',4),(19,'金牛区',4),(20,"成华区",4);

基础实例:

Dao层接口实现:/Web/src/top/weiyigeek/dao/impl/CityDaoImpl.java

1
2
3
4
5
6
7
public class CityDaoImpl implements CityDao {
@Override
public List<CityBean> findCity(int pid) throws SQLException {
QueryRunner qr = new QueryRunner(DB.getConn());
return qr.query("SELECT * FROM city WHERE pid = ? ", new BeanListHandler<CityBean>(CityBean.class), pid);
}
}

Service层接口实现:/Web/src/top/weiyigeek/service/impl/CityServiceImpl.java

1
2
3
4
5
6
7
public class CityServiceImpl implements CityService {
@Override
public List<CityBean> findCity(int pid) throws SQLException {
CityDao cd = new CityDaoImpl();
return cd.findCity(pid);
}
}

Servlet层:/Web/src/top/weiyigeek/servlet/CityServlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1.参数获取
request.setCharacterEncoding("utf-8");
int pid = Integer.parseInt(request.getParameter("pid"));

//2.从数据库找出省份的城市
CityService cs = new CityServiceImpl();
List<CityBean> list = cs.findCity(pid);
for (CityBean cityBean : list) {
System.out.println(cityBean.toString());
}

//3.实例化XML处理的库
XStream xStream = new XStream();
xStream.useAttributeFor(CityBean.class, "cid"); //想把id做成属性
xStream.alias("city", CityBean.class); //设置别名
String xml = xStream.toXML(list); //转化一个对象成xml字符串(当然也可以将xml转化成为一个对象)

//4.返回数据
response.setContentType("text/xml;charset=utf-8");
response.getWriter().write(xml);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Jsp层:/Web/WebContent/province.jsp

l
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script type="text/javascript">
//jQuery
$(function(){
//1.省份元素
$("#province").change(function() {
//2.选择的值进行请求该省份的城市数据
var pid = $(this).val();
$.post("CityServlet",{pid:pid} ,function(data,status){
console.log(data.children.contentType);
$("#msg").html("<pre>"+data.children[0].innerHTML+"</pre>");
$("#city").html("<option value=''>-请选择-"); //先清空以前的值
//遍历:从data数据里面找出所有的city,每次遍历就执行一次function方法;
$(data).find("city").each(function() {
//console.log($(this));
//遍历出来的每一个city,取它的孩子id+cname
var id = $(this).children("cid").text();
var cname = $(this).children("cname").text();
$("#city").append("<option value='"+id+"' >"+cname)
});
});
});

});
</script>

省份: <select name="province" id ="province">
<option value="" >-请选择 -
<option value="1" >北京
<option value="2" >上海
<option value="3" >重庆
<option value="4" >四川
<option value="5" >西藏
</select> &nbsp;
城市:
<select name="city" id="city">
<option value="" >-请选择 -
</select>


执行结果:

1
2
3
4
5
6
收到Post请求.....
CityBean [cid=11, pid=3, cname=江北区]
CityBean [cid=12, pid=3, cname=渝北区]
CityBean [cid=13, pid=3, cname=南岸区]
CityBean [cid=14, pid=3, cname=九龙坡区]
CityBean [cid=15, pid=3, cname=沙坪坝区]

WeiyiGeek.

WeiyiGeek.


0x04 JSON

描述:JSON转换程序需要依赖jar说明,开发时候需要进行导包;

1
2
3
commons-beanutils-1.8.3.jar    commons-logging-1.1.1.jar
commons-collections-3.2.1.jar ezmorph-1.0.6.jar
commons-lang-2.5.jar json-lib-2.4-jdk15.jar

WeiyiGeek.

WeiyiGeek.

json-lib-2.4 把javaBean 转化成 json数据(包下的常用两个类):

  • JSONArray —> 变成数组 , 集合 []
  • JSONObject —> 变成简单的数据 { name : zhangsan , age:18}

返回JSON数据格式操作唯一于上面不同得是在进行JSON数据封装以及在JQuery中对数据得解析,在Service层以及Dao数据接口层是没有代码上都改变得的;


Servelet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1.参数获取
request.setCharacterEncoding("utf-8");
int pid = Integer.parseInt(request.getParameter("pid"));

//2.从数据库找出省份的城市
CityService cs = new CityServiceImpl();
List<CityBean> list = cs.findCity(pid);

//3.进行JSON数据封装
JSONArray json = JSONArray.fromObject(list);
String res = json.toString();
System.out.println("JSON:" + res);

//4.返回数据
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(res);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

JSP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script type="text/javascript">
//jQuery
$(function(){
//1.省份元素
$("#province").change(function() {
//2.选择的值进行请求该省份的城市数据
var pid = $(this).val();
$.post("CityServlet",{pid:pid} ,function(data,status){
$("#msg").html("<pre>"+data+"</pre>");
$("#city").html("<option value=''>-请选择-"); //先清空以前的值
//遍历:从data数据里面找出所有的city,每次遍历就执行一次function方法;
$(data).each(function(index,c){
console.log("Index:"+index+", id:" + c.id + ", name" + c.cname);
$("#city").append("<option value='"+c.id+"' >"+c.cname)
});
},"json");
});

});
</script>

执行结果:

1
JSON:[{"cid":6,"cname":"黄浦区","pid":2},{"cid":7,"cname":"徐汇区","pid":2},{"cid":8,"cname":"长宁区","pid":2},{"cid":9,"cname":"静安区","pid":2},{"cid":10,"cname":"杨浦区","pid":2}]

WeiyiGeek.

WeiyiGeek.