Ajax异步(7)前端

1 Ajax概述

  AJAX 即“Asynchronous Javascript And XML”(异步 JavaScript和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

  • AJAX关键技术
    (1)使用CSS构建用户界面样式,负责页面排版和美工
    (2)使用DOM进行动态显示和交互,对页面进行局部修改
    (3)使用XMLHttpRequest异步获取数据
    (4)使用JavaScript将所有的元素绑定在一起
  • 特点:异步访问,局部刷新

2 同步和异步交互(前置知识)

2.1 什么是同步交互

  举个同步的例子,用户在使用浏览器访问某个页面的时候,首先用户会向HTTP服务器提交一个处理请求。接着服务器端接收到请求后,按照预先编写好的程序中的业务逻辑进行处理(比如和数据库服务器进行数据信息交换)。最后,服务器对请求进行响应,将结果返回给客户端,返回一个HTML等文件在浏览器中解析显示。
  为什么说是同步呢?因为在服务器返回结果之前,用户不能进行其他操作,必须要等到服务器返回了结果才能进行其他操作。这就是同步。

  • 优点
      可以保留浏览器后退按钮的正常功能。在动态更新页面的情况下,用户可以回到前一个页面状态,浏览器能记下历史记录中的静态页面,用户通常都希望单击后退按钮时,就能够取消他们的前一次操作,同步交互可以实现这个需求.
  • 缺点
    (1)同步交互的不足之处,会给用户一种不连贯的体验,当服务器处理请求时,用户只能等待状态,页面中的显示内容只能是空白。
    (2)因为已经跳转到新的页面,原本在页面上的信息无法保存,好多信息需要重新填写。

2.2 什么是异步交互

  指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。异步不用等所有操作等做完,就响应用户请求。即先响应用户请求,然后慢慢去写数据库,用户体验较好。

  • 优点
    (1)前端用户操作和后台服务器运算可以同时进行,可以充分利用用户操作的间隔时间完成运算
    (2)页面没有跳转,响应回来的数据直接就在原页面上,页面原有信息得以保留
  • 缺点
      可能破坏浏览器后退按钮的正常行为。在动态更新页面的情况下,用户无法回到前一个页面状态,这是因为浏览器仅能记录的始终是当前一个的静态页面。用户通常都希望单击后退按钮,就能够取消他们的前一次操作,但是在AJAX这样异步的程序,却无法这样做。

3 案例1:异步验证用户名是否被占用

案例内容:验证用户名是否被占用。JS表单验证只能校验格式是否正确,但是无法验证用户名是否已经存在,这个就需要后台程序接受到数据后通过查询才能够完成的,那么这里就非常适用于使用异步方式校验,保证用于数据提交后,业务完成的成功率,提升用于体验感。

3.1 页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>$Title%sSourceCode%lt;</title>

    <script>
        var xhr ;
        function checkUname(){
            // 获取输入框中的内容
            var unameDOM=document.getElementById("unameI");
            var unameText =unameDOM.value;
            var unameInfoDom =document.getElementById("unameInfo");
            if(null == unameText || unameText == ''){
                unameInfoDom.innerText="用户名不能为空";
                return;
            }
            unameInfoDom.innerText="";
            // 发送异步请求
            // 获取一个 XMLHttpRequest对象 ,对象可以帮助我们发送异步请求
            xhr =new XMLHttpRequest();
            // 使用xhr对象设置打开链接,设置请求方式和参数xhr.open("请求方式","请求的URL",是否使用异步方式);
            xhr.open("GET","unameCheckServlet.do?uname="+unameText,true);
            // 设置回调函数
            xhr.onreadystatechange=showReturnInfo;
            // 正式发送请求
            xhr.send(null);
        }
        function showReturnInfo(){
            if(xhr.readyState==4 && xhr.status==200){
                var returnInfo =xhr.responseText;
                var unameInfoDom =document.getElementById("unameInfo");
                unameInfoDom.innerText=returnInfo;
            }
        }
    </script>
</head>
<body>
<form action="myServlet1.do" >
    用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit">
</form>
</body>
</html>

3.2 servlet代码

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;

@WebServlet("/unameCheckServlet.do")
public class NameCheckServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("uname");
        String info = "";
        if ("jayden".equals(uname)){
            info = "用户名已被注册";
        }else{
            info = "用户名可以用";
        }
        //想浏览器返回结果
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().print(info);
    }
}

3.3 总结

  • AJAX异步提交请求的步骤为
    (1)获取XMLHTTPRequest对象xhr=new XMLHttpRequest();
    (2)打开链接xhr.open(“GET”,“loginServlet?uname=”+uname,true);
    (3)设置回调函数xhr.onreadystatechange=showRnturnInfo;
    (4)提交数据 xhr.send(data)
  • 目前存在的问题:
      原生js提交AJAX异步请求代码比较繁琐,处理复杂数据比较麻烦,后续可以使用jQuery解决

4 JSON格式

4.1 JSON介绍

  如果服务器给我们响应的数据非常简答,那么直接使用字符串就好了。但是,AJAX异步返回的数据如果有很多,那么就不好处理了,所以我们使用一个名叫JSON的文件格式来封装多个数据。
  JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

  • 优点
    (1)轻量级,在这里用它不是为了厉害的功能代码,而是为了实现数据转换
    (2)Json 格式既能考虑到前端对象的特点 同时也能兼顾后台对象信息的特点
    (3)Json 格式可以被前端直接识别并解析成对象
    (4)jQuery形式实现AJAX默认前后端传递数据的格式就是JSON

例子:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script>
        /*
        * JSON格式创建对象
        * {"属性名":"属性值","属性名":属性值 ... ... }
        * */
        var person ={"name":"zhangsan","age":10}
        alert(person.name)
        alert(person.age)
        var persons =[{"name":"zhangsan","age":10},{"name":"lisi","age":10},{"name":"wangwu","age":10}];
        for (var i = 0; i <persons.length ; i++) {
            var person =persons[i];
            console.log(person.name)
            console.log(person.age)
        }
        var personStr='{"name":"zhangsan","age":10}';// 是一个字符串
        // 可以直接把上面这种格式的字符串直接转换成对象
        var p =JSON.parse(personStr);
        console.log(p.name)
        console.log(p.age)
    </script>
</head>
<body>
</body>
</html>

4.2 JSON 与 JS 对象的关系

  很多人搞不清楚 JSON 和 JS 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b":   "World"}'; //这是一个 JSON 字符串,本质是一个字符串

4.3 JSON 和 JS 对象转化方法

  要实现从JSON字符串转换为JS对象,使用 JSON.parse() 方法:

var obj = JSON.parse('{"a": "Hello", "b":   "World"}'); //结果是 {a: 'Hello', b: 'World'}

  要实现从JS对象转换为JSON字符串,使用 JSON.stringify() 方法:

var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是  '{"a": "Hello", "b": "World"}'

4.4 GSON工具类的使用

  JSON格式字符串,拼接比较麻烦,可以修改toString方法但是就破坏了toString原有的格式,而且一旦字段如果太多修改工作量大,所以后续可以使用JSON工具类来转换。
  gson工具类中已经给我们封装好了json格式和java对象之间转换的API,我们直接使用即可,再也不用手动去转换项目中。

  • 需要添加gson-2.2.4.jar(在web项目的web目录下,用一个自定义lib然后把包复制进去,然后右键加入到库即可)

例子:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title%sSourceCode%lt;/title>
    <script>
      var xhr ;
      function testData(){
        xhr =new XMLHttpRequest();
        xhr.open("GET","testServlet.do",true);
        xhr.onreadystatechange=showReturnInfo;
        xhr.send(null);
      }
      function showReturnInfo(){
        if(xhr.readyState==4 && xhr.status==200){
          var info =xhr.responseText;
          var users=JSON.parse(info)
          for (var i = 0; i <users.length ; i++) {
            var user =users[i];
            console.log(user.uname)
            console.log(user.age)
            console.log(user.gender)
            console.log(user.birthday)
          }
        }
      }
    </script>
  </head>
  <body>
  <input type="button" value="测试" onclick="testData()">
  </body>
</html>

后台代码:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.msb.pojo.User;
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.util.ArrayList;
import java.util.Collections;
import java.util.Date;
/**
 * @Author: Ma HaiYang
 * @Description: MircoMessage:Mark_7001
 */
@WebServlet("/testServlet.do")
public class TestServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user1 =new User("jayden",11,"男",new Date());
        User user2 =new User("11",12,"男",new Date());
        User user3 =new User("kim",22,"男",new Date());
        User user4 =new User("晓明4",125,"男",new Date());
        User user5 =new User("晓明5",10,"男",new Date());
        ArrayList<User> list =new ArrayList<>();
        Collections.addAll(list,user1,user2,user3,user4,user5);
        // 响应普通文本数据
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss");
        Gson gson = gsonBuilder.create();
        String str = gson.toJson(list);
        System.out.println(str);
        resp.getWriter().print(str);
    }
}

5 AJAX结合JQuery实现

5.1 JQuery.ajax()的简单使用

  每次书写AJAX代码比较繁琐,步骤都是一样的,数据回显使用原生js代码也比较繁琐,所以可以使用jQuery对上述问题进行优化,jQuery不仅仅对dom操作进行了封装,同时也对AJAX提交和回显已经进行了封装,可大大简化AJAX的操作步骤。

  • 案例1
    (1)首先创建一个javaWeb项目,然后将需要的JQuery包导入进去。(注意:一定要放在web目录包下,这样编译时才能把这个包集成到服务器项目中,另外服务器端的包要放在web目录的WEB-INF目录下。)
    (2)编写html代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery.min.js"></script>
    <script>
        function checkName(){
            // 获取输入框中的内容
            if(null == $("#name").val() || '' == $("#name").val()){
                $("#nameInfo").text("用户名不能为空");
                return;
            }
            $("#nameInfo").text("");
            // 通过jQuery.ajax() 发送异步请求
            $.ajax(
                {
                    type:"GET",// 请求的方式 GET  POST
                    url:"nameCheckServlet.do?", // 请求的后台服务的路径
                    data:"name="+$("#name").val(),// 提交的参数
                    success:function(info){ // 响应成功执行的函数
                        $("#nameInfo").text(info)
                    }
                }
            )
        }
    </script>
</head>
<body>
<form action="myServlet.do" >
    用户名:<input id="name" type="text" name="name" onblur="checkName()">
    <span id="nameInfo" style="color: red"></span><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="提交按钮">
</form>
</body>
</html>

(3)后端Servlet代码

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;

/**
 * @Auther: jayden
 * @Date: 2022-05-05 - 05 - 05 - 9:11
 * @Description: demo
 * @version: 1.0
 */
@WebServlet("/nameCheckServlet.do")
public class nameCheckServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("name");
        String info="";
        if("jayden".equals(uname)){
            info="用户名已经占用";
        }else{
            info="用户名可用";
        }
        // 向浏览器响应数据
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().print(info);
    }
}

demo

  • 案例2
    (1)导包。(注意:一定要放在web目录包下,这样编译时才能把这个包集成到服务器项目中,另外服务器端的包要放在web目录的WEB-INF目录下。)
    (2)编写html前端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery.min.js"></script>
    <script>
        function testAjax(){
            // 向后台发送一个ajax异步请求
            // 接收响应的数据
            $.ajax(
                {
                    type:"GET",
                    url:"jsonServlet.do",
                    data:{"username":"zhangsan","password":"123456"},// key=value&key=value  {"属性名":"属性值"}
                    dataType:"json",//以什么格式接收后端响应给我们的信息
                    success:function(list){
                        $.each(list,function(i,e){
                            console.log(e)
                        })
                    }
                }
            )
        }
    </script>
</head>
<body>
	<input type="button" value="测试" onclick="testAjax()">
</body>
</html>

(3)编写Servlet后端代码

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

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.util.ArrayList;
import java.util.Collections;
import java.util.Date;

/**
 * @Auther: jayden
 * @Date: 2022-05-05 - 05 - 05 - 9:19
 * @Description: demo
 * @version: 1.0
 */
@WebServlet("/jsonServlet.do")
public class JsonServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        Student stu1=new Student("小黑","男",10,new Date());
        Student stu2=new Student("小白","男",10,new Date());
        Student stu3=new Student("小黄","男",10,new Date());
        Student stu4=new Student("小花","男",10,new Date());
        ArrayList<Student> list =new ArrayList<>();
        Collections.addAll(list,stu1,stu2,stu3,stu4);
        GsonBuilder gb =new GsonBuilder();
        gb.setDateFormat("yyyy-MM-dd");
        Gson gson = gb.create();
        String json = gson.toJson(list);
        resp.setContentType("text/html;charset=UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().print(json);
    }
}

5.2 JQuery.ajax()属性介绍

  $.ajax()方法中有很多属性可以供我们使用,其中很多属性都有默认值,那么这些属性都有哪些,处理的是什么事情?接下来给大家一一介绍一下

1.url:
  要求为String类型的参数,(默认为当前页地址)发送请求的地址。

2.type:
  要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

3.timeout:
  要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。

4.async:
  要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。

5.cache:
  要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。

6.data:
  要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看  processData选项。对象必须为key/value格式,例如{foo1:“bar1”,foo2:“bar2”}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:[“bar1”,“bar2”]}转换为&foo=bar1&foo=bar2。

7.dataType:
  要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:

xml:返回XML文档,可用JQuery处理。

html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。

script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。

json:返回JSON数据。

jsonp:JSONP格式。使用JSONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。

text:返回纯文本字符串。

8.beforeSend

  要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。

XMLHttpRequest对象是惟一的参数。
function(XMLHttpRequest){
this; //调用本次ajax请求时传递的options参数
}

9.complete
  要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。

function(XMLHttpRequest, textStatus){
this; //调用本次ajax请求时传递的options参数
}

10.success
  要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。

function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //调用本次ajax请求时传递的options参数
}

11.error:
  要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:

function(XMLHttpRequest, textStatus, errorThrown){
//通常情况下textStatus和errorThrown只有其中一个包含信息
this; //调用本次ajax请求时传递的options参数
}

12.contentType
  要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

13.dataFilter
  要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。

function(data, type){
//返回处理后的数据
return data;
}

14.global
  要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。

15.ifModified
  要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。

16.jsonp
  要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:‘onJsonPLoad’}会导致将"onJsonPLoad=?"传给服务器。

17.username
  要求为String类型的参数,用于响应HTTP访问认证请求的用户名。

18.password
  要求为String类型的参数,用于响应HTTP访问认证请求的密码。

19.processData
  要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。

20.scriptCharset
  要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。

一个ajax方法中,可用的属性和方法大致如下

<script>
  
  
      function testAjax(){
         $.ajax({
             url:"servlet1",
             /*post get  部分浏览器可使用put delete*/
             type:"get",
             /*请求超时的时间设置*/
             timeout:2000,
             /*是否发送异步请求,默认值为true,如需同步请求,改为false*/
             async:true,
             /*是否从浏览器的缓存中加载信息,默认为true,false则不读取浏览器缓存*/
             cache:true,
             /*向服务器发送的数据,可以是key/value格式,也可以是对象格式
             * get方式下,会将信息附加在url后,如果数据不是字符串,会转换成字符串格式
             * */
             data:{username:"bjmsb",password:"bjmsb"},
             /*
             * 默认值为true 默认情况下,发送的数据将被转换为对象以配合
             *   content-type:application/x-www-form-urlencoded
             * 如果发送信息不希望被转换,设置为false即可
             * */
             proccessData:true,
             /*发送到服务器的数据为String类型时,默认值为
             *   application/x-www-form-urlencoded
             * 该值适合大多数应用场景
             * */
             contentType:"application/x-www-form-urlencoded",
              /*
              * 预期服务器返回值类型,
              * 如果不指定 jQuery根据http响应mime信息返回xml或者text
              * 并作为返回值传递,可选类型如下
              * xml 返回xml数据(基本淘汰)
              * html:返回纯文本HTML信息
              * script:返回JS脚本,
              * json:返回json数据
              * jsonp:jsonp格式
              * text:返回纯文本,也是默认格式
              * */
             dataType:"json",
             /*
             * 指定跨域回调函数名
             * */
             //jsonp:"fun1",
  
             /*只有当请求参数为dataType为jsonp或者script,并且是get方式请求时
             * 才能强制修改字符集,通常在跨域编码不同时使用
             * */
            //  scriptCharset:"utf-8",
  
             beforeSend:function(XMLHttpRequest){
               /*
                * 请求发送前可以通过该方法修改XMLHttpRequest对象函数
                * 如听见请求头
                * 如果该方法返回false,则会取消ajax请求
                * */
             },
             success:function(data,textStatus){
                 /*
                 *一般请求成功后会调用的函数,有两个可选参数
                 * data,数据 根据dataType的配置处理之后的数据 可能是xml text json 等
                 * testStatus ,描述响应状态的字符串
                 *  */
             },
             error:function(XMLHttpRequest,textStatus,errorThrown){
                 /*
                 * 请求失败时调用的函数,可选参数有
                 * XMLHttpRequest对象
                 * 错误信息
                 * 捕获的异常对象
                 * */
             },
             complete:function(XMLHttpRequest,textStatus){
                 /*
                 * 无论请求是否成功都睡调用的回调函数
                 * 可选参数有
                 * XMLHttpRequest对象
                 * textStatus 描述成功请求的类型的字符串
                 * */
             },
             dataFilter:function(data,type){
                 /*
                 * 数据过滤方法
                 * 给Ajax返回的原始数据进行预处理的函数。
                 * 提供data和type两个参数。
                 * data是Ajax返回的原始数据,
                 * type是调用jQuery.ajax时提供的dataType参数。
                 * 函数返回的值将由jQuery进一步处理
                 * */
             }
  
         })
      }
  </script>

注意:
  ajax异步提交的可选属性和方法较多,实际研发我们没必要写这么多,一般可以使用默认值的属性就可以省略不写,一些业务逻辑或者功能上不需要的方法也可以省略不写,由于属性太多,针对于一些特殊情况,jQuery也给我们提供了一些专用的方法,这样可以简化$.ajax的写法,每一种简化写法都相当于已经指定了$.ajax一些属性的值.

5.3 JQuery实现ajax的其他写法

1.$.load()
  jQuery load() 方法是简单但强大的 AJAX 方法,load() 方法从服务器加载数据,并把返回的数据放入被选元素中。默认使用 GET 方式 - 传递附加参数时自动转换为 POST 方式,
语法为:$(selector).load(URL,data,callback);
参数的含义为:
url: URL地址
data:待发送参数。
callback:载入成功时回调函数。
案例:(准备两个HTML页面和一个Servlet)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery.min.js"></script>
    <script>
        function testLoad(){
            //$("#d1").load("servlet2.do","username=aaa&password=bbb",function(){alert("响应结束")})
            $("#d1").load("loadPage.html #a")
        }
    </script>
</head>
<body>
<div id="d1" style="width: 100px;height: 100px;border: 1px solid black">
</div>
<input type="button" value="测试" onclick="testLoad()">
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="a">
    <li>JAVA</li>
    <li>HTML</li>
    <li>CSS</li>
    <li>Mysql</li>
    <li>python</li>
</div>
</body>
</html>
  1. $.get()
      这是一个简单的 GET 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用$.ajax
    语法为:$.get(url,[data],[callback],[type])
    参数的含义为:
    url: URL地址
    data:待发送参数。
    callback:载入成功时回调函数。
    type:返回内容格式,xml, html, script, json, text, _default

该函数是简写的 Ajax 函数,等价于:

$.ajax({
 type:   'GET',
  url: url,
  data: data,
  success: success,
  dataType: dataType
});
  1. $.getJSON()
      JSON是一种较为理想的数据传输格式,它能够很好的融合与JavaScript或其他宿主语言,并且可以被JS直接使用。使用JSON相比传统的通过 GET、POST直接发送“裸体”数据,在结构上更为合理,也更为安全。至于jQuery的getJSON()函数,只是设置了JSON参数的ajax()函数的一个简化版本。
    语法为:
$.getJSON(
      url,             //请求URL
      [data],          //传参,可选参数
      [callback]       //回调函数,可选参数
    );

该函数是简写的 Ajax 函数,等价于:

$.ajax({
  url: url,
  data: data,
  success: callback,
  dataType: json
});

仅仅是等效于上述函数,但是除此之外这个函数也是可以跨域使用的,相比get()、post()有一定优势。另外这个函数可以通过把请求url写 成"myurl?callback=X"这种格式,让程序执行回调函数X。

4.$.post()
注意:$.getJSON是以GET方式提交数据,如果需要提交很大的数据量,可选$.post
这是一个简单的 POST 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用$.ajax
语法为:$.post(url,[data],[callback],[type])
参数的含义为:
url: URL地址
data:待发送参数。
callback:载入成功时回调函数。
type:返回内容格式,xml, html, script, json, text, _default

该函数是简写的 Ajax 函数,等价于:

$.ajax({
  type:   'POST',
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery.min.js"></script>
    <script>
        function testAjax(){
            $.get(
                "servlet1.do",
                {"username":"zhangsan","password":"123456"},
                function(list){
                    $.each(list,function(i,e){
                        console.log(e)
                    })
                },
                "json")
            console.log("------------------------------")
            $.getJSON(
                "servlet1.do",
                {"username":"zhangsan","password":"123456"},
                function(list){
                    $.each(list,function(i,e){
                        console.log(e)
                    })
                })
            console.log("------------------------------")
            $.post(
                "servlet1.do",
                {"username":"zhangsan","password":"123456"},
                function(list){
                    $.each(list,function(i,e){
                        console.log(e)
                    })
                },
                "json")
        }
    </script>
</head>
<body>
<input type="button" value="测试" onclick="testAjax()">
</body>
</html>
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

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.util.ArrayList;
import java.util.Collections;
import java.util.Date;

/**
 * @Auther: jayden
 * @Date: 2022-05-05 - 05 - 05 - 10:42
 * @Description: demo
 * @version: 1.0
 */
@WebServlet("/servlet1.do")
public class Servlet3 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        Student stu1=new Student("小黑","男",10,new Date());
        Student stu2=new Student("小白","男",10,new Date());
        Student stu3=new Student("小黄","男",10,new Date());
        Student stu4=new Student("小花","男",10,new Date());
        ArrayList<Student> list =new ArrayList<>();
        Collections.addAll(list,stu1,stu2,stu3,stu4);
        GsonBuilder gb =new GsonBuilder();
        gb.setDateFormat("yyyy-MM-dd");
        Gson gson = gb.create();
        String json = gson.toJson(list);
        resp.setContentType("text/html;charset=UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().print(json);
    }
}

5.4 jsonp跨域处理

  • 什么是跨域
      跨域问题是出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
    以下是不同源的一些例子
    本地路径地址:http://127.0.0.1:8080/msb/index.jsp
    https://127.0.0.1:8080/msb/index.jsp 协议不一样
    http://192.168.24.11:8080/msb/index.jsp IP不一致
    http://127.0.0.1:8888/msb/index.jsp 端口不一致
    http://localhost:8080/msb/index.jsp IP不一致

  • 实现跨域的原理是什么
      我们发现Web页面上调用js文件时则不受是否跨域的影响,拥有”src”这个属性的标签都却拥有跨域的能力,比如<\script><\img><\iframe>。那么跨域访问数据就有了一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理。就好比使用一个<script>,让其src属性指向我们要访问的跨域资源,然后以接收js文件的形式接收数据。

  • 通过:dataType:'jsonp'属性实现跨域请求。

  • 通过 jsonp:'callback'属性简化回调函数处理。
      通过 jsonp:’callback’,实现自动处理回调函数名,相当于在url地址栏最后后拼接一个callback=函数名,后台自动根据这个函数名处理JS脚本,jQuery也会根据这函数名自动在前端处理回调函数,这样我们直接在success方法中接收返回的数据即可,可以不用自己去自己定义回调函数.后台获取参数时,参数名要要和jsonp:后面的函数名保持一致。

  • 案例
    (1)HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://localhost:8080/Ajax_test_war_exploded/js/jquery.min.js"></script>
    <script>
        function checkUname(){
            // 获取输入框中的内容
            if(null == $("#unameI").val() || '' == $("#unameI").val()){
                $("#unameInfo").text("用户名不能为空");
                return;
            }
            $("#unameInfo").text("");
            // 通过jQuery.ajax() 发送异步请求
            $.ajax(
                {
                    type:"GET",// 请求的方式 GET  POST
                    url:"http://localhost:8080/Ajax_test_war_exploded/unameCheckServlet.do?", // 请求的后台服务的路径
                    data:{uname:$("#unameI").val()},// 提交的参数
                    dataType:"jsonp",
                    jsonp:"aaa",
                    success:function(info){
                        $("#unameInfo").text(info)
                    }

                }
            )
        }
    </script>
</head>
<body>
<form action="myServlet1.do" >
    用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()">
    <span id="unameInfo" style="color: red"></span><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="提交按钮">
</form>
</body>
</html>

(2)Servlet后端代码

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;

@WebServlet("/unameCheckServlet.do")
public class UnameCheckServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("uname");
        String callBack = req.getParameter("aaa");
        System.out.println(uname);
        String info="";
        if("jayden".equals(uname)){
            info="用户名已经占用";
        }else{
            info="用户名可用";
        }
        // 向浏览器响应数据
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/javaScript;charset=UTF-8");
        resp.getWriter().print(callBack+"('"+info+"')");
    }
}
  • 通过getJson方实现跨域请求
      getJSON方法是可以实现跨域请求的,在用该方法实现跨域请求时,在传递参数上应该注意在url后拼接一个jsoncallback=?,jQuery会自动替换?为正确的回调函数名,我们就可以不用单独定义回调函数了
<html>
<head>
    <title>$Title%sSourceCode%lt;/title>
    <meta charset="UTF-8"/>
    <script src="http://localhost:8080/ajaxDemo3_war_exploded/js/jquery.min.js"></script>
    <script>
    	
    	
        function checkUname(){
            // 获取输入框中的内容
            if(null == $("#unameI").val() || '' == $("#unameI").val()){
                $("#unameInfo").text("用户名不能为空");
                return;
            }
            $("#unameInfo").text("");
         
           $.getJSON(
           	"http://localhost:8080/ajaxDemo3_war_exploded/unameCheckServlet.do?jsoncallback=?",
           	{uname:$("#unameI").val()},
           	function(info){
           		$("#unameInfo").text(info)
           	}
           )
        }
    </script>
</head>
<body>
<form action="myServlet1.do" >
    用户名:<input id="unameI" type="text" name="uname" onblur="checkUname()">
    <span id="unameInfo" style="color: red"></span><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="提交按钮">
</form>
</body>
</html>
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;

@WebServlet("/unameCheckServlet.do")
public class UnameCheckServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("uname");
        String callBack = req.getParameter("jsoncallback");
        System.out.println(uname);
        String info="";
        if("jayden".equals(uname)){
            info="用户名已经占用";
        }else{
            info="用户名可用";
        }
        // 向浏览器响应数据
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/javaScript;charset=UTF-8");
        resp.getWriter().print(callBack+"('"+info+"')");
    }
}
  • 通过后台代码也可以实现跨域,一般在过滤器中添加如下代码,那么前端在请求时就不用考虑跨域问题了
  /*请求地址白名单 *代表所有    */
  resp.setHeader("Access-Control-Allow-Origin", "*");
  /*请求方式白名单      */
  resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
  resp.setHeader("Access-Control-Max-Age", "3600");
  resp.setHeader("Access-Control-Allow-Headers", "x-requested-with");

6 案例2:三级联动

  • 效果:
  • 创建一个web项目,项目结构如下
  • 各个类的代码
    (1)JSP代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>$Title%sSourceCode%lt;</title>
    <script src="js/jquery.min.js"></script>
    <script>
      $(function(){
        // 获取所有的省份信息
        showArea(0,"#provience")
      })
      function showArea(val,selectID){
        $.ajax({
          type:"GET",
          url:"areaController.do",
          data:{parentID:val},
          dataType:"json",
          success:function(areas){
            // 清除上一次选择省份时,遗留的城市
            $(selectID).html('<option>-请选择-</option>');
            $.each(areas,function(i,e){
              $(selectID).append('<option value="'+e.areaid+'">'+e.areaname+'</option>')
            })
            if(selectID== "#city"){
              $("#qu").html('<option>-请选择-</option>');
            }
          }
        })
      }
    </script>
    </head>
<body>
籍贯:
<select id="provience" onchange="showArea(this.value,'#city')">
  <option>-请选择-</option>
</select>
<select id="city" onchange="showArea(this.value,'#qu')">
  <option>-请选择-</option>
</select>
<select id="qu">
  <option>-请选择-</option>
</select>
</body>
</html>

(2)Controller代码

package com.jayden.controller;

import com.google.gson.Gson;
import com.jayden.pojo.Area;
import com.jayden.service.AreaService;
import com.jayden.service.impl.AreaServiceImpl;

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.util.List;

@WebServlet("/areaController.do")
public class AreaController extends HttpServlet {
    private AreaService areaService = new AreaServiceImpl();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer parentID=0;
        try {
            parentID= Integer.parseInt(req.getParameter("parentID"));
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        List<Area> areas=areaService.findByParentID(parentID);
        String json = new Gson().toJson(areas);
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().print(json);

    }
}

(3)Service代码

package com.jayden.service.impl;

import com.jayden.dao.AreaDao;
import com.jayden.dao.impl.AreaDaoImpl;
import com.jayden.pojo.Area;
import com.jayden.service.AreaService;

import java.util.List;

public class AreaServiceImpl implements AreaService {
    private AreaDao areaDao =new AreaDaoImpl();
    @Override
    public List<Area> findByParentID(Integer parentID) {
        List<Area> areas = areaDao.findByParentID(parentID);
        return areas;
    }
}

(4)Dao层代码

package com.jayden.dao.impl;

import com.jayden.dao.AreaDao;
import com.jayden.dao.BaseDao;
import com.jayden.pojo.Area;


import java.util.List;

public class AreaDaoImpl extends BaseDao implements AreaDao {
    @Override
    public List<Area> findByParentID(int parentID) {
        String sql="select * from area where parentid= ?";
        return baseQuery(Area.class, sql, parentID);
    }
}

(5)辅助类代码
BaseDao

package com.jayden.dao;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;


public abstract class BaseDao {
    public  int baseUpdate(String sql,Object ... args){
        // 向 Emp表中增加一条数据
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        int rows=0;

        try{

            connection = MyConnectionPool.getConnection();

            preparedStatement = connection.prepareStatement(sql);
            //设置参数
            for (int i = 0; i <args.length ; i++) {
                preparedStatement.setObject(i+1, args[i]);
            }

            //执行CURD
            rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
        }catch (Exception e){
            e.printStackTrace();
        }finally {

            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            MyConnectionPool.returnConnection(connection);
        }

        return rows;
    }


    public  List baseQuery(Class clazz,String sql,Object ... args) {
        // 查询名字中包含字母A的员工信息
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

        List list =null;
        try{

            connection = MyConnectionPool.getConnection();
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            for (int i = 0; i <args.length ; i++) {
                preparedStatement.setObject(i+1, args[i]);
            }


            //执行CURD
            resultSet = preparedStatement.executeQuery();// 这里不需要再传入SQL语句
            list=new ArrayList() ;
            // 根据字节码获取所有 的属性
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);// 设置属性可以 访问
            }

            while(resultSet.next()){
                // 通过反射创建对象
                Object obj = clazz.newInstance();//默认在通过反射调用对象的空参构造方法
                for (Field field : fields) {// 临时用Field设置属性
                    String fieldName = field.getName();// empno  ename job .... ...
                    Object data = resultSet.getObject(fieldName);
                    field.set(obj,data);
                }
                list.add(obj);

            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != resultSet){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();

                }

            }
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            MyConnectionPool.returnConnection(connection);
        }
        return list;
    }

}

MyConnectionPool

package com.jayden.dao;

import com.jayden.util.PropertiesUtil;
import org.apache.log4j.Logger;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

public class MyConnectionPool {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;
    private static int initSize;
    private static int maxSize;
    private static Logger logger;
    private static LinkedList<Connection> pool;

    static{
        logger=Logger.getLogger(MyConnectionPool.class);
        // 初始化参数
        PropertiesUtil propertiesUtil=new PropertiesUtil("/jdbc.properties");
        driver=propertiesUtil.getProperties("driver");
        url=propertiesUtil.getProperties("url");
        user=propertiesUtil.getProperties("user");
        password=propertiesUtil.getProperties("password");
        initSize=Integer.parseInt(propertiesUtil.getProperties("initSize"));
        maxSize=Integer.parseInt(propertiesUtil.getProperties("maxSize"));
        // 加载驱动
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            logger.fatal("找不到数据库驱动类"+driver,e);
        }
        // 初始化pool
        pool=new LinkedList<Connection>();
        // 创建5个链接对象
        for (int i = 0; i <initSize ; i++) {
            Connection connection = initConnection();
            if(null != connection){
                pool.add(connection);
                logger.info("初始化连接"+connection.hashCode()+"放入连接池");

            }
        }
    }

    // 私有的初始化一个链接对象的方法
    private static Connection initConnection(){
        try {
            return DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            logger.fatal("初始化连接异常",e);
        }
        return null;
    }
    // 共有的向外界提供链接对象的
    public static Connection getConnection(){
        Connection connection =null;
        if(pool.size()>0){
            connection= pool.removeFirst();// 移除集合中的第一个元素
            logger.info("连接池中还有连接:"+connection.hashCode());
        }else{
            connection = initConnection();
            logger.info("连接池空,创建新连接:"+connection.hashCode());
        }
        return connection;
    }

    // 共有的向连接池归还连接对象的方法
    public static void returnConnection(Connection connection){
        if(null != connection){
            try {
                if(!connection.isClosed()){

                    if(pool.size()<maxSize){
                        try {
                            connection.setAutoCommit(true);// 调整事务状态
                            logger.debug("设置连接:"+connection.hashCode()+"自动提交为true");
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                        pool.addLast(connection);
                        logger.info("连接池未满,归还连接:"+connection.hashCode());
                    }else{
                        try {
                            connection.close();
                           logger.info("连接池满了,关闭连接:"+connection.hashCode());
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }else{
                   logger.info("连接:"+connection.hashCode()+"已经关闭,无需归还");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }else{
           logger.warn("传入的连接为null,不可归还");
        }
    }

}

PropertiesUtil

package com.jayden.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertiesUtil {
    private Properties properties;

    public PropertiesUtil(String path){
        properties=new Properties();
        InputStream inputStream = this.getClass().getResourceAsStream(path);
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getProperties(String key){
        return properties.getProperty(key);
    }

}

(6)pojo类

package com.jayden.pojo;
import java.io.Serializable;

public class Area implements Serializable {
    private Integer areaid;
    private String areaname;
    private Integer parentid;
    private Integer arealevel;
    private Integer status;

    public Integer getAreaid() {
        return areaid;
    }

    public void setAreaid(Integer areaid) {
        this.areaid = areaid;
    }

    public String getAreaname() {
        return areaname;
    }

    public void setAreaname(String areaname) {
        this.areaname = areaname;
    }

    public Integer getParentid() {
        return parentid;
    }

    public void setParentid(Integer parentid) {
        this.parentid = parentid;
    }

    public Integer getArealevel() {
        return arealevel;
    }

    public void setArealevel(Integer arealevel) {
        this.arealevel = arealevel;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Area() {
    }

    public Area(Integer areaid, String areaname, Integer parentid, Integer arealevel, Integer status) {
        this.areaid = areaid;
        this.areaname = areaname;
        this.parentid = parentid;
        this.arealevel = arealevel;
        this.status = status;
    }
}

(7)配置类XML
jdbc.properties

## key=value
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
user=root
password=root
initSize=1
maxSize=1

log4j.properties

log4j.rootLogger=debug,stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=d:/msb.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd   HH:mm:ss} %l %F %p %m%n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jayden-leo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值