Jsp开发模式及MVC模型的使用

2020-10-23 15:38:11 浏览数 (1)

[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.

三层结构的实现操作:

环境基础设置:

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

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

WeiyiGeek.三层结构原理

测试数据表:

代码语言:javascript复制
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,以及异常抛出
代码语言:javascript复制
//常常是接口的实现类
public class UserDao {
  public boolean find() throw SQLException{
    try{
      //执行的SQL
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
  • 2.Service 根据业务校验数据并进行异常抛出;
代码语言:javascript复制
public class LoginUserService() throw Exception,SQLException {
  try {
  //数据效验
  } catch (Exception e){
    throw new Exception("数据校验说明");
  }
}
  • 3.每一个servlet中接收产生的异常处理并打印
代码语言:javascript复制
public class UserLoginServlet extends Servlet{
  void doGet(request,response){
    try {
      //功能处理
    } catch (Exception e) {
      //错误处理以及错误打印
    }
  }
}
0x01 实例

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

WeiyiGeek.

Person 数据类:

代码语言:javascript复制
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 方法略去 (自动生成即可)
}
更新信息

文件结构:

代码语言:javascript复制
#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

主要代码:

代码语言:javascript复制
<%@ 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 层

代码语言:javascript复制
//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 层: 实现

代码语言:javascript复制
@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 层: 实现

代码语言:javascript复制
/**
	 * @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.

模糊查询

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

/Web/WebContent/findlist.jsp

代码语言:javascript复制
<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 实现:

代码语言:javascript复制
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 层:

代码语言:javascript复制
@Override
  public List<Person> searchPerson(String sname, String gender) throws SQLException {
    return new PersonDaoImpl().searchPerson(sname,gender);
  }

Dao 层:

代码语言:javascript复制
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.

分页实现

常用的分页方式有两种:

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

项目文件结构:

代码语言:javascript复制
#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

公共类:

代码语言:javascript复制
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 数据库操作实现

代码语言:javascript复制
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 业务逻辑层实现

代码语言:javascript复制
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

代码语言:javascript复制
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) 展示层:

代码语言:javascript复制
<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.


0x02 Ajax & JQuery

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

常用的JS框架:

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

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

代码语言:javascript复制
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集成请求示例:

代码语言:javascript复制
//执行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 使用案例

代码语言:javascript复制
* 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

代码语言:javascript复制
<%@ 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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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.

异步关键字搜寻

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

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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
<%@ 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

代码语言:javascript复制
<%@ 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.搜索模仿

0x03 XML
省市联动

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

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

案例SQL:

代码语言:javascript复制
--省市
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
<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>

执行结果:

代码语言:javascript复制
收到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.

0x04 JSON

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

代码语言:javascript复制
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.

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

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

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

Servelet:

代码语言:javascript复制
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:

代码语言:javascript复制
<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>

执行结果:

代码语言:javascript复制
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.

0 人点赞