JavaWeb基础总结学习笔记(下)

JavaWeb过滤器Filter、jQuery、Ajax、JSON的使用详解


计算机网络:https://www.nowcoder.com/discuss/342320
MySQL:https://www.nowcoder.com/discuss/353707
Java并发上:https://www.nowcoder.com/discuss/355081
Java并发下:https://www.nowcoder.com/discuss/355876
JDBC:https://www.nowcoder.com/discuss/356804
Linux:https://www.nowcoder.com/discuss/357410
JavaWeb上:https://www.nowcoder.com/discuss/358423
JavaWeb中:https://www.nowcoder.com/discuss/358741
JavaWeb下本篇内容原址:https://blog.csdn.net/qq_41112238/article/details/103751092


Filter:过滤器

概念

web中的过滤器:
当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
过滤器的作用:
一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤...

快速入门

@WebFilter("/index.jsp")//拦截index.jsp
public class Filter1 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) 
throws ServletException, IOException {
        System.out.println("过滤器执行了");
        //chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }
}

访问index.jsp,可以看到页面并无输出

在这里插入图片描述
打开doFilter方法中的注释,再次访问index.jsp

在这里插入图片描述

XML配置方式

去掉过滤器类的注解
在WEB-INF下的xml文件进行配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <filter>
        <filter-name>filter1</filter-name>
        <filter-class>filter.Filter1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter1</filter-name>
        <url-pattern>/index.jsp</url-pattern>
    </filter-mapping>

</web-app>

过滤器执行流程

  1. 执行过滤器
  2. 执行放行后的资源
  3. 回来执行过滤器放行代码下边的代码

过滤器生命周期方法

  1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
  2. doFilter:每一次请求被拦截资源时,会执行。执行多次
  3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
    在这里插入图片描述

拦截路径配置:

  1. 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
  2. 拦截目录:/user/* 访问/user下的所有资源时,过滤器都会被执行
  3. 后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
  4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行

拦截方式配置:资源被访问的方式

  • 注解配置:
    • 设置dispatcherTypes属性
      1. REQUEST:默认值。浏览器直接请求资源
      2. FORWARD:转发访问资源
      3. INCLUDE:包含访问资源
      4. ERROR:错误跳转资源
      5. ASYNC:异步访问资源
  • web.xml配置
    • 设置标签即可

例1:拦截请求
过滤器:

@WebFilter(value = "/index.jsp",dispatcherTypes = {DispatcherType.REQUEST})
public class Filter1 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("过滤器执行了");
    }

    public void init(FilterConfig config) throws ServletException {
    }

}

通过转发访问index.jsp的servlet

@WebServlet("/filterServlet")
public class FilterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

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

直接请求index.jsp被拦截

在这里插入图片描述

转发访问index.jsp正常

在这里插入图片描述

例2:拦截转发

过滤器:

@WebFilter(value = "/index.jsp",dispatcherTypes = {DispatcherType.FORWARD})
public class Filter1 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("过滤器执行了");
    }

    public void init(FilterConfig config) throws ServletException {
    }

}

转发访问index.jsp被拦截

在这里插入图片描述

直接请求index.jsp正常

在这里插入图片描述

例3:拦截请求和转发
过滤器:

@WebFilter(value = "/*",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})
public class Filter1 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("过滤器执行了");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
    }

}

访问servlet将被拦截两次,因为拦截了请求和转发

在这里插入图片描述

过滤器链(配置多个过滤器)

执行顺序:

如果有两个过滤器:过滤器1和过滤器2

  1. 过滤器1
  2. 过滤器2
  3. 资源执行
  4. 过滤器2
  5. 过滤器1

过滤器先后顺序问题:

  1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
    如: AFilter 和 BFilter,AFilter就先执行了。
@WebFilter( "/*")
public class TestFilter implements javax.servlet.Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("过滤器1执行了");
        chain.doFilter(req, resp);
        System.out.println("过滤器1执行结束");
    }

    public void init(FilterConfig config) throws ServletException {
    }

}

@WebFilter( "/*")
public class TestFilter1 implements javax.servlet.Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("过滤器2执行了");
        chain.doFilter(req, resp);
        System.out.println("过滤器2执行结束");
    }

    public void init(FilterConfig config) throws ServletException {
    }

}

在这里插入图片描述
2. web.xml配置: <filter-mapping>谁定义在上边,谁先执行

敏感词过滤案例

首先先了解一下动态***设计模式
实现步骤:

  1. ***对象和真实对象实现相同的接口
  2. ***对象 = Proxy.newProxyInstance();
  3. 使用***对象调用方法。
  4. 增强方法

增强方式:

  1. 增强参数列表
  2. 增强返回值类型
  3. 增强方法体执行逻辑

通过一个例子来说明:
一个卖老婆的接口:

public interface SaleWife {
    //花钱买了一个老婆
    String sale(double money);
}

一个卖老婆的实现类,即真实对象

public class SaleWifeImpl implements SaleWife {

    @Override
    public String sale(double money) {
        System.out.println("buy a wife by $"+money);
        return "a wife";
    }
}

测试类

public class ProxyTest {
    public static void main(String[] args) {
        SaleWife saleWife=new SaleWifeImpl();

        String gift = saleWife.sale(8000);
        System.out.println(gift);
    }
}

结果:

buy a wife by $8000.0
a wife

使用动态***:

public class ProxyTest {
    public static void main(String[] args) {
        //真实对象
        SaleWife saleWife=new SaleWifeImpl();
        /*
            ***对象
            参数1:真实对象的类加载器
            参数2:真实对象实现的接口
            参数3:具体***逻辑
         */
        SaleWife proxy_sale = (SaleWife) Proxy.newProxyInstance(SaleWifeImpl.class.getClassLoader(),
                SaleWifeImpl.class.getInterfaces(), new InvocationHandler() {
            /*
            具体***逻辑
            参数1:***对象
            参数2:***对象调用的方法
            参数3:***对象调用方法时传递的实际参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //如果是sale方法
                if(method.getName().equals("sale")){
                    //增强参数
                    double money=(double)args[0]*0.8;
                    //使用真实对象调用方法
                    String gift = (String) method.invoke(saleWife, money);
                    //增强逻辑
                    System.out.println("送货上门:");
                    //增强返回值
                    return gift+" with 36D";
                }
                //用真实对象调用方法
                return method.invoke(saleWife,args);
            }
        });
        //不使用***
        String gift = saleWife.sale(8000);
        System.out.println(gift);
        System.out.println("----------------------");
        //使用***
        String gift2 = proxy_sale.sale(8000);
        System.out.println(gift2);
    }
}

结果:

buy a wife by 6400.0
送货上门:
a wife with 36D

接下来用动态***实现敏感词过滤
过滤器:

@WebFilter("/*")
public class WordFilter implements Filter {
    //敏感词集合
    private List<String> words=new ArrayList<>();

    public void init(FilterConfig config) throws ServletException {
        try {
            //读取敏感词汇文件
            //1.获取真实路径
            String realPath = config.getServletContext().getRealPath("/WEB-INF/classes/word.txt");
            //2.创建输入流
            BufferedReader reader=new BufferedReader(new FileReader(realPath));
            //3.读取数据
            String line;
            while((line=reader.readLine())!=null){
                //存入敏感词集合
                words.add(line);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        ServletRequest newReq = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(),req.getClass().getInterfaces(), (proxy, method, args) -> {
            //如果是getParameter方法
            if(method.getName().equals("getParameter")){
                //获取原有字符串
                String str = (String) method.invoke(req, args);
                System.out.println(words);
                //遍历敏感词汇集合,存在则替换
                if(str!=null){
                    for(String word:words){
                        if(str.contains(word)){
                            str=str.replaceAll(word,"***");
                        }
                    }
                }
                //返回处理后的字符串
                System.out.println("已过滤敏感词");
                return str;
            }
            return method.invoke(req,args);
        });
        chain.doFilter(newReq, resp);
    }

    public void destroy() {
    }

}

测试的Servlet

@WebServlet("/filterServlet")
public class FilterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String player=request.getParameter("player");
        String word = request.getParameter("word");
        System.out.println("玩家 :"+player);
        System.out.println("发言 : "+word);
    }

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

在src下新建一个敏感词文件,注意用GBK编码

在这里插入图片描述
启动服务器测试

在这里插入图片描述

结果:

在这里插入图片描述

Listener:***

概念:web的三大组件之一。
事件监听机制

  • 事件 :一件事情
  • 事件源 :事件发生的地方
  • *** :一个对象
  • 注册监听:将事件、事件源、***绑定在一起。 当事件源上发生某个事件后,执行***代码

ServletContextListener

监听ServletContext对象的创建和销毁
方法:
void contextDestroyed(ServletContextEvent sce)
ServletContext对象被销毁之前会调用该方法
void contextInitialized(ServletContextEvent sce)
ServletContext对象创建后会调用该方法

步骤

  1. 定义一个类,实现ServletContextListener接口
  2. 复写方法
  3. 配置
    • 可以在xml中配置
      指定初始化参数<context-param>
            <listener>
                <listener-class>Listener</listener-class>
            </listener>
            <context-param>
                <param-name>config</param-name>
                <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
            </context-param>
    • 直接使用注解@WebListener

一般用于加载资源

public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        String config = servletContext.getInitParameter("config");
        String realPath = servletContext.getRealPath(config);
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(realPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(fileInputStream);
    }

启动tomcat服务器时输出
在这里插入图片描述


JQuery

概念

  • 一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。
  • JQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。
  • 它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
  • JavaScript框架:本质上就是一些js文件,封装了js的原生代码
  • 目前jQuery有三个大版本:
              1.x:兼容ie678,使用最为广泛的,官方只做BUG维护,
                   功能不再新增。因此一般项目来说,使用1.x版本就可以了,
                   最终版本:1.12.4 (2016年5月20日)
              2.x:不兼容ie678,很少有人使用,官方只做BUG维护,
                   功能不再新增。如果不考虑兼容低版本的浏览器可以使用2.x,
                   最终版本:2.2.4 (2016年5月20日)
              3.x:不兼容ie678,只支持最新的浏览器。除非特殊要求,
                   一般不会使用3.x版本的,很多老的jQuery插件不支持这个版本。
                   目前该版本是官方主要更新维护的版本。最新版本:3.2.1(2017年3月20日)

入门示例

引入jQuery
在这里插入图片描述
$("#标签id名")获取对象 html()方法获取内容

<html>
<head>
    <title>Title</title>
    <script src="js/jquery-3.3.1.min.js"></script>
</head>
<body>
    <div id="tag1">aaa</div>

    <script>
        var tag1 = $("#tag1");
        alert(tag1.html());
    </script>
</body>
</html>

结果:
在这里插入图片描述

JQuery对象和JS对象区别与转换

  • JQuery对象在操作时,更加方便。
  • JQuery对象和js对象方法不通用的.
  • 两者相互转换
    • jq -- > js : jq对象[索引] 或者 jq对象.get(索引)
    • js -- > jq : $(js对象)
 <div id="tag1">aaa</div>
    <div id="tag2">aaa</div>
    <script>
        //通过js方式获取所有叫div的所有html对象
        var divs = document.getElementsByTagName("div");
        //改变所有标签体内容
        for (var i=0;i<divs.length;i++){
            divs[i].innerHTML="bbb";
            //js对象转换为jQuery使用
            // $(divs[i]).html("bbb");
        }
        //通过jQuery方式
        var $divs = $("div");
        $divs.html("ccc");
        //jquery对象转换为js使用
        //$divs[0].innerHTML="ddd";
        //$divs.get(1).innerHTML="eee";

    </script>

基本语法

事件绑定

    <script>
        $("#btn").click(function () {
            alert("我被点了");
        });
    </script>

在这里插入图片描述
在这里插入图片描述

入口函数

 $(function () {
         //....
             });

window.onload 和 $(function) 区别

  • window.onload 只能定义一次,如果定义多次,后边的会将前边的覆盖掉
    • $(function)可以定义多次的。

样式控制:css方法

方式一:$("#div1").css("background-color","red");

方式二:$("#div1").css("backgroundColor","pink");
html代码:

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-3.3.1.min.js"></script>
    <script>
        $(function () {
            $("#div1").css("background-color","red");
            $("#div2").css("backgroundColor","yellow");
        });
    </script>
</head>
<body>
        <div id="div1">区域1</div>
        <div id="div2">区域2</div>
</body>
</html>

结果:
在这里插入图片描述

选择器

基本选择器

  1. 标签选择器(元素选择器)
    $("html标签名")获得所有匹配标签名称的元素
  2. id选择器
    $("#id的属性值") 获得与指定id属性值匹配的元素
  3. 类选择器
    $(".class的属性值")获得与指定的class属性值匹配的元素
  4. 并集选择器:
    $("选择器1,选择器2....")获取多个选择器选中的所有元素
            //按钮1:改变 id 为 one 的元素的背景色为 红色"
            $("#b1").click(function () {
                $("#one").css("backgroundColor","red");
            });
            //按钮2: 改变元素名为 <div> 的所有元素的背景色为 红色"
            $("#b2").click(function () {
                $("div").css("backgroundColor","red");
            });
            //按钮3:改变 class 为 mini 的所有元素的背景色为 红色"
            $("#b3").click(function () {
                $(".mini").css("backgroundColor","red");
            });
            //按钮4: 改变所有的<span>元素和 id 为 two 的元素的背景色为红色
            $("#b4").click(function () {
                $("span,#two").css("backgroundColor","red");
            });

层级选择器

  1. 后代选择器
    $("A B ")选择A元素内部的所有B元素
  2. 子选择器
    $("A > B")选择A元素内部的所有B子元素
            //<input type="button" value=" 改变 <body> 内所有 <div> 的背景色为红色"  id="b1"/>
            $("#b1").click(function () {
                $("body div").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变 <body> 内子 <div> 的背景色为 红色"  id="b2"/>
            $("#b2").click(function () {
                $("body > div").css("backgroundColor","red");
            });

属性选择器

  1. 属性名称选择器
    $("A[属性名]")包含指定属性的选择器
  2. 属性选择器
    $("A[属性名='值']")包含指定属性等于指定值的选择器
  3. 复合属性选择器
    $("A[属性名='值'][]...") 包含多个属性条件的选择器
        //<input type="button" value=" 含有属性title 的div元素背景色为红色"  id="b1"/>
        $("#b1").click(function () {
            $("div[title]").css("backgroundColor","red");
        });
        //<input type="button" value=" 属性title值等于test的div元素背景色为红色"  id="b2"/>
        $("#b2").click(function () {
            $("div[title='test']").css("backgroundColor","red");
        });
        //<input type="button" value=" 属性title值不等于test的div元素(没有属性title的也将被选中)背景色为红色"  id="b3"/>
        $("#b3").click(function () {
            $("div[title!='test']").css("backgroundColor","red");
        });
        //<input type="button" value=" 属性title值 以te开始 的div元素背景色为红色"  id="b4"/>
        $("#b4").click(function () {
            $("div[title^='te']").css("backgroundColor","red");
        });
        //<input type="button" value=" 属性title值 以est结束 的div元素背景色为红色"  id="b5"/>
        $("#b5").click(function () {
            $("div[title$='est']").css("backgroundColor","red");
        });
        //<input type="button" value="属性title值 含有es的div元素背景色为红色"  id="b6"/>
        $("#b6").click(function () {
            $("div[title*='es']").css("backgroundColor","red");
        });
        //<input type="button" value="选取有属性id的div元素,然后在结果中选取属性title值含有“es”的 div 元素背景色为红色"  id="b7"/>
        $("#b7").click(function () {
            $("div[id][title*='es']").css("backgroundColor","red");
        });

过滤选择器

  1. 首元素选择器
    :first 获得选择的元素中的第一个元素
  2. 尾元素选择器
    :last 获得选择的元素中的最后一个元素
  3. 非元素选择器
    :not(selector) 不包括指定内容的元素
  4. 偶数选择器
    :even 偶数,从 0 开始计数
  5. 奇数选择器
    :odd奇数,从 0 开始计数
  6. 等于索引选择器
    :eq(index) 指定索引元素
  7. 大于索引选择器
    :gt(index) 大于指定索引元素
  8. 小于索引选择器
    :lt(index)小于指定索引元素
  9. 标题选择器
    :header获得标题(h1~h6)元素,固定写法
            //<input type="button" value=" 改变第一个 div 元素的背景色为 红色"  id="b1"/>
            $("#b1").click(function () {
                $("div:first").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变最后一个 div 元素的背景色为 红色"  id="b2"/>
            $("#b2").click(function () {
                $("div:last").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变class不为 one 的所有 div 元素的背景色为 红色"  id="b3"/>
            $("#b3").click(function () {
                $("div:not(.one)").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变索引值为偶数的 div 元素的背景色为 红色"  id="b4"/>
            $("#b4").click(function () {
                $("div:even").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变索引值为奇数的 div 元素的背景色为 红色"  id="b5"/>
            $("#b5").click(function () {
                $("div:odd").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变索引值为大于 3 的 div 元素的背景色为 红色"  id="b6"/>
            $("#b6").click(function () {
                $("div:gt(3)").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变索引值为等于 3 的 div 元素的背景色为 红色"  id="b7"/>
            $("#b7").click(function () {
                $("div:eq(3)").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变索引值为小于 3 的 div 元素的背景色为 红色"  id="b8"/>
            $("#b8").click(function () {
                $("div:lt(3)").css("backgroundColor","red");
            });
            //<input type="button" value=" 改变所有的标题元素的背景色为 红色"  id="b9"/>
            $("#b9").click(function () {
                $(":header").css("backgroundColor","red");
            });

表单过滤选择器

  1. 可用元素选择器
    :enabled获得可用元素
  2. 不可用元素选择器
    :disabled获得不可用元素
  3. 选中选择器
    :checked获得单选/复选框选中的元素
  4. 选中选择器
    :selected 获得下拉框选中的元素
              //<input type="button" value=" 利用 jQuery 对象的 val() 方法改变表单内可用 <input> 元素的值"  id="b1"/>
              $("#b1").click(function () {
                  $("input[type='text']:enabled").val("aaa");
              });
              //<input type="button" value=" 利用 jQuery 对象的 val() 方法改变表单内不可用 <input> 元素的值"  id="b2"/>
              $("#b2").click(function () {
                  $("input[type='text']:disabled").val("bbb");
              });
              //<input type="button" value=" 利用 jQuery 对象的 length 属性获取复选框选中的个数"  id="b3"/>
              $("#b3").click(function () {
                  var length = $("input[type='checkbox']:checked").length;
                  alert(length)
              });
              //<input type="button" value=" 利用 jQuery 对象的 length 属性获取下拉框选中的个数"  id="b4"/>
              $("#b4").click(function () {
                  var length = $("#job > option:selected").length;
                  alert(length)
              });

DOM操作

内容操作

  1. html()获取/设置元素的标签体内容 <a><font>内容</font></a> --> <font>内容</font>
  2. text() 获取/设置元素的标签体纯文本内容 <a><font>内容</font></a> --> 内容
  3. val() 获取/设置元素的value属性值

属性操作

  • 通用属性操作
- `attr()`: 获取/设置元素的属性
- `removeAttr()`:删除属性
- `prop()`:获取/设置元素的属性
- `removeProp()`:删除属性

- attr和prop区别?
    - 如果操作的是元素的固有属性,则建议使用prop
    - 如果操作的是元素自定义的属性,则建议使用attr
            //获取北京节点的name属性值
            var name = $("#bj").attr("name");
            alert(name);
            //设置北京节点的name属性的值为dabeijing
            $("#bj").attr("name","dabeijing");
            //新增北京节点的discription属性 属性值是didu
            $("#bj").attr("discription","didu");
            //删除北京节点的name属性并检验name属性是否存在
            $("#bj").removeAttr("name");
            //获得hobby的的选中状态
            var prop = $("#hobby").prop("checked");
            alert(prop);
  • 对class属性操作
  • addClass():添加class属性值
  • removeClass():删除class属性值
  • toggleClass():切换class属性 toggleClass("one"): 判断如果元素对象上存在class="one",则将属性值one删除掉。 如果元素对象上不存在class="one",则添加
             //<input type="button" value="采用属性增加样式(改变id=one的样式)"  id="b1"/>
             $("#b1").click(function () {
                 $("#one").prop("class","second");
             });
             //<input type="button" value=" addClass"  id="b2"/>
             $("#b2").click(function () {
                 $("#one").addClass("second");
             });
             //<input type="button" value="removeClass"  id="b3"/>
             $("#b3").click(function () {
                 $("#one").removeClass("second");
             });
             //<input type="button" value=" 切换样式"  id="b4"/>
             $("#b4").click(function () {
                 $("#one").toggleClass("second");
             });
             //<input type="button" value=" 通过css()获得id为one背景颜色"  id="b5"/>
             $("#b5").click(function () {
                 var color = $("#one").css("backgroundColor");
             });
             //<input type="button" value=" 通过css()设置id为one背景颜色为绿色"  id="b6"/>
             $("#b6").click(function () {
                 $("#one").css("backgroundColor","green");
             });

Ajax

概念

ASynchronous JavaScript And XML 异步的JavaScript 和 XML

  • 异步和同步:客户端和服务器端相互通信的基础上
  • 同步:客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。
  • 异步:客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。
  • Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
    • 通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。
      • 这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
    • 传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
      • 提升用户的体验

实现

原生JS(了解)

            //1.创建核心对象
            var xmlhttp;
            if (window.XMLHttpRequest)// code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp=new XMLHttpRequest();
            else
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");// code for IE6, IE5
            //2. 建立连接
            /*
                参数:
                    1. 请求方式:GET、POST
                        * get方式,请求参数在URL后边拼接。send方法为空参
                        * post方式,请求参数在send方法中定义
                    2. 请求的URL
                    3. 同步或异步请求:true(异步)或 false(同步)
             */
            xmlhttp.open("GET","../ajaxServlet?username=tom",true);
            //3.发送请求
            xmlhttp.send();
            //4.接受并处理来自服务器的响应结果
            //获取方式 :xmlhttp.responseText
            //什么时候获取?当服务器响应成功后再获取
            //当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
            xmlhttp.onreadystatechange=function()
            {
                //判断readyState就绪状态是否为4,判断status响应状态码是否为200
                if (xmlhttp.readyState==4 && xmlhttp.status==200)
                {
                    //获取服务器的响应结果
                    var responseText = xmlhttp.responseText;
                    alert(responseText);
                }
            }

jQuery实现

  • $.ajax()
    语法:$.ajax({键值对});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/jquery-3.3.1.min.js"></script>
    <script>
        function f() {
            $.ajax({
               url:"../ajaxServlet",//请求url
               type:"POST",//请求方式
               data:{"username":"james"},//请求数据
               success:function (data) {//响应成功的回调函数
                   alert(data);
               } ,
               error:function () {//响应失败的回调函数
                   alert("error happened");
               } ,
               dataType:"text" //响应数据格式
            });
        }
    </script>
</head>
<body>
    <input id="test" type="button" value="ajax提交数据" onclick="f()">
    <input>
</body>
</html>

结果:
在这里插入图片描述
在这里插入图片描述

  • $.get():发送get请求
    语法:$.get(url, [data], [callback], [type])
    参数:

    * url:请求路径     
    • data:请求参数
    • callback:回调函数
    • type:响应结果的类型

    只需改动上例代码中的$.ajax()部分,运行结果不变

      $.get("../ajaxServlet",{"username":"james"},function (data) {
                  alert(data);
              },"text");
  • $.post():发送post请求
    语法:$.post(url, [data], [callback], [type])

      $.post("../ajaxServlet",{"username":"james"},function (data) {
                  alert(data);
              },"text");

JSON

概念

JavaScript Object Notation JavaScript对象表示法

  • JSON现在多用于存储和交换文本信息的语法
  • 进行数据的传输
  • JSON 比 XML 更小、更快,更易解析。

基本规则

  • 数据在名称/值对中:json数据是由键值对构成的

  • 键用引号(单双都行)引起来,也可以不使用引号

  • 值的取值类型:

    数字(整数或浮点数)
    字符串(在双引号中)
    逻辑值(true 或 false)
    数组(在方括号中) {"persons":[{},{}]}
    对象(在花括号中) {"address":{"province":"陕西"....}}
    null

  • 数据由逗号分隔:多个键值对由逗号分隔

  • 花括号保存对象:使用{}定义json 格式

  • 方括号保存数组:[]

        //普通格式
        var person={name:"james",age:35,gender:"male"};
        //{}嵌套[]
        var persons={
            persons: [
                {name:"james",age:35,gender:"male"},
                {name:"kobe",age:38,gender:"male"},
                {name:"kuzma",age:24,gender:"male"}
                ]
        };
        //[]嵌套{}
        var persons1=[
            {name:"james",age:35,gender:"male"},
            {name:"kobe",age:38,gender:"male"},
            {name:"kuzma",age:24,gender:"male"}
            ];

获取数据:

1.json对象.键名
2. json对象["键名"]
3. 数组对象[索引]

        var person={name:"james",age:35,gender:"male"};
        var name2 = person.name;//james
        var name3 = person["name"];//james
        var persons={
            persons: [
                {name:"james",age:35,gender:"male"},
                {name:"kobe",age:38,gender:"male"},
                {name:"kuzma",age:24,gender:"male"}
                ]
        };
        var name1 = persons.persons[1].name;//kobe
        var persons1=[
            {name:"james",age:35,gender:"male"},
            {name:"kobe",age:38,gender:"male"},
            {name:"kuzma",age:24,gender:"male"}
            ];
        var name = persons1[0].name;//james

4.遍历

        //普通格式
        var person={name:"james",age:35,gender:"male"};
        for (var key in person){
            //alert(key+person.key);不能用这个方式 相当于person."name"
            //alert(key+person[key]);
            alert(key);
        }
        //遍历数组
        var persons=[
            {name:"james",age:35,gender:"male"},
            {name:"kobe",age:38,gender:"male"},
            {name:"kuzma",age:24,gender:"male"}
            ];
        for(var i=0;i<persons.length;i++){
            var person = persons[i];
            for (var key in person){
                alert(key+person[key]);
            }
        }

Java对象转换JSON

  1. 导入jackson的相关jar包
    在这里插入图片描述
  2. 创建Jackson核心对象 ObjectMapper
  3. 调用ObjectMapper的相关方法进行转换

转换方法

  • writeValue(参数1,obj)
    参数1:
    File:将obj对象转换为JSON字符串,并保存到指定的文件中
    Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
    OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
  • writeValueAsString(obj):将对象转为json字符串

封装数据的Person类

public class Person {
    private String name;
    private int age;
    private String gender;

    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

测试类:

public class JsonTest {

    @Test
    public void test() throws IOException {
        ObjectMapper mapper=new ObjectMapper();
        Person p=new Person("james",35,"male");
        String string = mapper.writeValueAsString(p);
        System.out.println(string);//{"name":"james","age":35,"gender":"male"}
        mapper.writeValue(new File("d://a.txt"),p);
        mapper.writeValue(new FileWriter("d://b.txt"),p);
        mapper.writeValue(new FileOutputStream("d://c.txt"),p);
    }
}

在d盘下生成3个文件:
在这里插入图片描述
文件内容:
在这里插入图片描述

注解

  1. @JsonIgnore:排除属性。
  2. @JsonFormat:属性值得格式化
  • 给Person类添加一个Date属性

      private Date date;
    
          public Date getDate() {
              return date;
          }
    
          public void setDate(Date date) {
              this.date = date;
          }
  • 不添加注解时:

       public void test() throws IOException {
              ObjectMapper mapper=new ObjectMapper();
              Person p=new Person("james",35,"male");
              p.setDate(new Date());
              String string = mapper.writeValueAsString(p);
              System.out.println(string);
          }

    结果:

    {"name":"james","age":35,"gender":"male","date":1577762339613}

  • 添加 @JsonIgnore

      @JsonIgnore
          private Date date;

    结果:

    {"name":"james","age":35,"gender":"male"}

  • 添加 @JsonFormat

      @JsonFormat(pattern = "yyyy-MM-dd")
          private Date date;

    结果:

    {"name":"james","age":35,"gender":"male","date":"2019-12-31"}

复杂java对象转换

List:数组

    public void test() throws IOException {
        ObjectMapper mapper=new ObjectMapper();
        Person p=new Person("james",35,"male");
        List<Person> list=new ArrayList<>();
        list.add(p);
        String string = mapper.writeValueAsString(list);
        System.out.println(string);
        //输出:[{"name":"james","age":35,"gender":"male","date":null}]
    }

Map:对象格式一致

    public void test() throws IOException {
        ObjectMapper mapper=new ObjectMapper();
        Map<String,Object> map=new HashMap<>();
        map.put("name","james");
        map.put("age",35);
        map.put("gender","male");
        String string = mapper.writeValueAsString(map);
        System.out.println(string);
        //输出:{"gender":"male","name":"james","age":35}
    }

JSON转为Java对象

readValue(json字符串数据,Class)

    @Test
    public void test() throws IOException {
        ObjectMapper mapper=new ObjectMapper();
        String json_data="{\"name\":\"james\",\"age\":35,\"gender\":\"male\"}";
        Person person = mapper.readValue(json_data, Person.class);
        System.out.println(person);
        //输出:json.Person@4cf777e8
    }

Ajax和json综合案例:校验用户名是否存在

服务器响应的数据,在客户端使用时,要想当做json数据格式使用。
有两种解决方案:

  1. $.get(type):将最后一个参数type指定为"json"
  2. 在服务器端设置MIME类型
    response.setContentType("application/json;charset=utf-8");

注册页:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-3.3.1.min.js"></script>
    <script>
        $(function () {
            //给用户名输入框绑定离焦事件
            $("#username").blur(function () {
                var $username = $(this).val();
                //ajax方式发送get请求
                $.get("ajaxServlet",{username:$username},function (data) {
                    //如果exist为true,说明用户存在,错误提示,设置为红色
                    var $span = $("#span");
                    if(data.exist){
                        $span.css("color","red");
                    }else {//成功提示 设置为绿色
                        $span.css("color","green");
                    }
                    $span.html(data.msg);//设置提示信息为msg内容
                });
            });

        });
    </script>
</head>
<body>
        用户名:<input type="text" name="username" id="username" >
        <span id="span"></span><br>
        密码:<input type="text" name="password" ><br>
        <input type="button" value="登陆">
</body>
</html>

ajax处理请求servlet

@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        response.setContentType("application/json;charset=utf-8");//设置响应格式为json
        HashMap<String,Object> map=new HashMap<>();
        ObjectMapper mapper = new ObjectMapper();
        try {
            UserDao userDao=new UserDao();
            if(userDao.exist(username)){//若存在
                map.put("exist",true);
                map.put("msg","用户名已存在,请更换");
            }else {
                map.put("exist",false);//若不存在
                map.put("msg","用户名可用");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        mapper.writeValue(response.getWriter(),map);
    }

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

UserDao类

class UserDao {

    private Connection conn;

    UserDao() throws Exception {
    }

    boolean exist(String username) {
        try{
            conn=JDBCUtils.getConnection();
            //1.编写sql
            String sql = "select * from user where username = ?";
            //2.调用query方法
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1,username);
            ResultSet resultSet = ps.executeQuery();
            return resultSet.next();
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }
}

结果:
在这里插入图片描述
在这里插入图片描述

#Java##学习路径##笔记##JavaScript#
全部评论

相关推荐

投递拼多多等公司10个岗位
点赞 评论 收藏
转发
点赞 21 评论
分享
牛客网
牛客企业服务