Ajax的使用

本文意在通过小demo来理解如何利用jQuery实现Ajax。
案例1是之前在eclipse上做的还没有使用maven管理。
案例2是后来在idea上做的,使用了maven管理。

案例1——检查员工编号

1. 案例描述:

通过异步处理,检查员工编号是否冲突。点击输入框,如果输入框的内容是1001,则说明编号冲突,则输出编号冲突的提示信息。否则,可以添加此员工编号。

2. 业务需求

在实际信息提交过程中,我们想不是全部提交表单信息后,才能得到后台的处理响应。而是,当输入某一内容后,就立刻对该内容进行判断处理。这时,我们就需要用到Ajax异步处理

3. 前提准备

lib文件下添加三个Ajax的jar包
  js文件夹下添加jQuery的jar包
  js文件夹下创建script.js,用来写脚本
  将jQuery的jar包和script.js引入Register.jsp文件中

4. 实现逻辑

首先运行Register.jsp页面,输入框先获取焦点,并输入员工编号。输入框失去焦点后,执行script.js,将数据异步传送给后台 CheckEmpIdServlet.java。后台对数据进行处理,若该员工编号存在则返回错误提示信息,若该数据不存在,说明可以添加,就不用返回提示信息了。 如果后台有错误,则在alert中显示状态码。

4.1 Register.jsp

前端登录页面Register.jsp,输入员工编号,通过jQuery对象向后台进行传递,接受后台传过来的数据进行显示。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
	<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-3.2.1.min.js" ></script>
	<script src="${pageContext.request.contextPath }/js/script.js"></script>
</head>
<body>
	<h1>员工注册</h1>
	// 传入员工编号
	员工编号:<input type="text" name="empid">
	// 显示错误信息
	<span style="color:red; font-weight:bold;"></span>
	// 隐藏项目路径,发送向后台发送请求时需要该路径
	<input type="hidden" id="path" value="${pageContext.request.contextPath }"/>
</body>
</html>

4.2 script.js

通过jQuery调用 ajax方法,向后台传递异步请求。这里对异步请求代码做一个简单的介绍。我们要向后台传递异步数据:

  1. 我们要明白要向哪里传,需要知道后台地址 url
  2. 传递数据时的请求方式,get 还是 post
  3. 是不是异步请求 async (true or false),这个是默认的,可以不写
  4. 发送到服务器的数据 data,数据类型是 JSON 对象,没有就不写
  5. 后台响应的数据类型 dataType,如果是 text 就是字符串,如果是 json 就是 JSON对象
  6. 响应成功后,要执行什么操作 success。需要已经接受到响应结果readyState=4;并且是正确接收的,状态码status=200。data 参数是后台的响应结果。
  7. 响应出错后,要执行什么操作 error。状态码status=400或status=404或500。出错的方法的参数 xmlHttpRequest 就是我们传递的请求对象。
// 页面加载后,要执行的功能
$(function(){
	// 输入框失去焦点后要执行的功能
	$('input[name=empno]').blur(function(){
		// 向后台发送异步请求,接受响应结果进行局部判断
		$.ajax({
			// 访问的后台地址
			url:$('#path').val()+"/CheckEmpnoServlet",
			//url:${pageContext.request.contextPath}+"/CheckEmpnoServlet",
			type:'get',
			// 为后台传递的请求参数,以json对象的方式传递,如果不传请求参数,可以省略
			data:{empno:$('input[name=empno]').val()},
			// 后台响应的数据类型
			dataType:'text',
			// 响应成功后,要执行的功能
			success:function(data){
				// 请求对象的readyState等于4并且status等于200是执行该方法
				$('span').html(data);
			},
			// error的function参数就是请求对象XMLHttpRequest
			error:function(xmlHttpRequest){
				alert(xmlHttpRequest.status);
			}
		});
	});
});

4.3 CheckEmpIdServlet.java

接受前端请求参数,并判断结果。将响应结果返回给前端。

  1. 接受请求参数,并处理请求参数
  2. 设置响应的「数据类型」、「编码类型」。如果不设置的话,前台可能无法正常显示。如果数据类型为 text/html 则向前台传递的是字符串;如果数据类型为 application/json 则向前台传递的是 JSON对象。编码就设置为 utf-8
package com.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class CheckEmpIdServlet
 */
@WebServlet("/CheckEmpIdServlet")
public class CheckEmpIdServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CheckEmpIdServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		
		if(request.getParameter("empid") != null) {
			int empId = Integer.parseInt(request.getParameter("empid"));
			String msg = "";
			if(empId == 1001) {
				msg = "该编号已经创建!";
			}
			response.setContentType("text/html;charset=utf-8");
			PrintWriter writer = response.getWriter();
			writer.print(msg);
			writer.flush();
			writer.close();
		}
	}

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

5. 运行结果

  • 如果输入的员工编号为1001,则输出提示信息
  • 如果输入的员工编号不为1001,则说明该编号可以被创建,就不需要任何提示信息

6. 自己遇到的问题

  1. script.js 里的 dataType:'text' 写错,alert 提示框输出的 readyState=4status=200 这里 readyState=4 说明接受到了后台的请求数据,status=200 这个说明后台数据是正确的。这里的 dataType:'text' 写错是前台的问题。

  2. CheckEmpIdServlet.java 里的 response.setContentType(“text/html;charset=utf-8”); 不写或者写错的话,会导致前端页面无法正常显示,像这样:
  3. idea中jquery怎么打断点 idea使用jquery_ajax

案例2——查找省市

1. 案例描述

要求页面加载后自动获取到省的全部信息。点击省,获取到对应的市的信息。

2. 环境准备

使用的mvc架构,使用了jstl标签库,EL表达式。

1. 数据库

这里只给出数据库字段:
省:省id、省名称
市:市id、市名称、省id

2. 前端准备

在webapp下的js文件夹下添加jquery包
在webapp下的js文件夹下创建script.js文件,用来写js代码

3. pom.xml

<!--sql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version><!--$NO-MVN-MAN-VER$ -->
        </dependency>
        <!--jstl标签库依赖-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--将字符串转化为JSON对象的依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.2.2</version>
        </dependency>

4. MVC

省市的 vo层、dao层、service层

3. 前端页面的实现

一个select下拉列表,用来显示省的信息;一个select下拉列表,用来显示市的信息。

3.1 index.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set value="${pageContext.request.contextPath}" var="path"></c:set>
<!DOCTYPE html>
<html>
<head>
    <title>JSP - Hello World</title>
    <%--引入jquery包和script.js文件--%>
    <script src="${path}/js/jquery.js"></script>
    <script src="${path}/js/script.js"></script>

</head>
<body>
    <%--隐藏当前项目的根目录--%>
    <input id="path" type="hidden" value="${path }" />

    <label>省:</label>
    <select name="provinceId" style="width: 150px"></select>

    <label>市:</label>
    <select name="cityId" style="width: 150px"></select>

</body>
</html>

4. 获取省信息的实现

页面加载后,向后台发送异步请求,并将获取到的数据在前台进行显示。

4.1 script.js

向SearchProvinceServlet发送请求。用data对象接收后台传过来的数据,并进行处理。

/*为省添加异步请求*/
$(function () {
    $.ajax({
        url: $('#path').val() + "/SearchProvinceServlet",
        type: "get",
        dataType: "json",
        success: function (data) {
            var provinceNode = $('select[name=provinceId]');
            provinceNode.empty();
            provinceNode.append("<option value='0'>--请选择--</option>");
            /*data 是一个JSON数组,对JSON数组进行循环*/
            $.each(data, function (i, province) {
                var optionNode = '<option value="'+province.provinceId+'">'+province.provinceName+'</option>';
                provinceNode.append(optionNode);
            });
        },
        error: function (xmlHttpRequest) {
            alert(xmlHttpRequest.status);
        }
    });
});

4.2 SearchProvinceServlet

获取到省的全部信息,存放在集合中。将集合对象转化为JSON对象,发送给前端。

package servlets;

import com.fasterxml.jackson.databind.ObjectMapper;
import service.ProvinceService;
import vo.Province;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet("/SearchProvinceServlet")
public class SearchProvinceServlet extends HttpServlet {
    private ProvinceService provinceService = new ProvinceService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 查询到所有的省的信息
        List<Province> provinces = provinceService.selectByProvinceName("");
        // 创建ObjectMapper对象,将集合对象转化为JSON字符串
        ObjectMapper mapper = new ObjectMapper();
        String provinceJson = mapper.writeValueAsString(provinces);
        // 设置响应的数据类型,编码方式
        response.setContentType("application/json;charset=utf-8");
        // 创建writer对象,返回异步信息
        PrintWriter writer = response.getWriter();
        writer.print(provinceJson);
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

5. 获取市信息的实现

5.1 script.js

向后台发送请求信息,通过省id获取到对应的市的信息,用data接收。通过循环data对象,来显示所有的市的数据。

/*为市添加异步请求*/
$(function () {
    $("select[name=provinceId]").change(function () {
        $.ajax({
            url: $('#path').val() + "/SearchCityServlet",
            type: "post",
            async:true,
            data: {provinceId:$("select[name=provinceId]").val()},
            dataType: "json",
            success: function (data) {
                var cityNode = $("select[name=cityId]");
                cityNode.empty();
                cityNode.append('<option value="0">--请选择--</option>');
                $.each(data, function (i, city) {
                    var optionNode = "<option value='"+city.cityId+"'>"+city.cityName+"</option>";
                    cityNode.append(optionNode);
                });
            },
            error: function (xmlHttpRequest) {
                alert(xmlHttpRequest.status);
            }
        });
    });
});

5.2 SearchCityServlet

这里我没有使用注解,而是配置了web.xml文件。通过省id获取到对应的市的信息,发送给前端。

package servlets;

import com.fasterxml.jackson.databind.ObjectMapper;
import service.CityService;
import vo.City;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

//@WebServlet("/SearchCityServlet")
public class SearchCityServlet extends HttpServlet {
    private CityService cityService = new CityService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int provinceId = Integer.parseInt(request.getParameter("provinceId"));
        List<City> cities = cityService.selectByProvinceId(provinceId);

        ObjectMapper mapper = new ObjectMapper();
        String cityJson = mapper.writeValueAsString(cities);

        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print(cityJson);
        writer.flush();
        writer.close();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

5. 运行结果

idea中jquery怎么打断点 idea使用jquery_html_02


idea中jquery怎么打断点 idea使用jquery_ajax_03

自己遇到的问题

  1. $.ajax(JSON对象)
    传递的是JSON对象。JSON对象:{键:“值”}
  2. dataType: “json”,
    json需要用 “” 引用起来,JSON对象里不同的键值是用 ,来分割的
  3. response.setContentType(“text/html;charset=utf-8”);
    charset写错
  4. 404、500问题