IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Ajax技术详解(二)JSON 详解 -> 正文阅读

[JavaScript知识库]Ajax技术详解(二)JSON 详解

目录

一.JSON 简介

1.介绍

2.为什么要使用 JSON

二.JSON 格式的特征

1.JSON 的语法规则

2. JOSN 的 6 种数据类型

三.Jackson

1.Jackson 的使用

2.Jackson 简介

3.在响应中通过 JSON 格式传递数据

四.通过 JSON 格式在响应中传递单个对象

五.通过 JSON 格式在响应中传递多个对象

?六.在 JSON 中通过 Map 传递数据

七.在请求中通过 JSON 格式传递数据

?八.Jackson 的常用注解

1.@JsonProperty

2.@JsonIgnore

3.@JsonFormat

九.Jackson 工具类的使用


一.JSON 简介

1.介绍

JSON(JavaScript Object Notation) 是一种基于字符串的轻量级的数据交换格式。易于人阅
读和编写,同时也易于机器解析和生成。 JSON JavaScript 数据类型的子集。

2.为什么要使用 JSON

JSON 未出现之前在 Ajax 中对于数据传递方式,会使用 XML 作为主要数据格式来传输数据。直到 JSON 出现后逐渐放弃使用 XML 作为数据传输格式。 JSON XML 更小、更快,更易解析。

二.JSON 格式的特征

1.JSON 的语法规则

JSON 是按照特定的语法规则所生成的字符串结构。
  • 大括号表示 JSON 的字符串对象。{ }
  • 属性和值用冒号分割。{"属性":"value"}
  • 属性和属性之间用逗号分割。{"属性":"value","属性":"value",...}
  • 中括号表示数组。[{"属性":"value"...},{"属性":"value"...}]

JSON 字符串对象:

{"userid":1,"username":"admin","sex":"male"}
数组:

[{"userid":1,"username":"admin"},{"userid":2,"username":"oldlu"}]?

2. JOSN 的 6 种数据类型

  1. string:字符串,必须要用双引号引起来。
  2. number:数值,与 JavaScript number 一致,
  3. objectJavaScript 的对象形式,{ key:value }表示方式,可嵌套。
  4. array:数组,JavaScript Array 表示方式[ value ],可嵌套。
  5. true/false:布尔类型,JavaScript boolean 类型。
  6. null:空值,JavaScript null

三.Jackson

1.Jackson 的使用

JDK 中并没有内置操作 JSON 格式数据的 API ,因此使用处理 JSON 格式的数据需要借
助第三方类库。
几个常用的 JSON 解析类库:
Gson: 谷歌开发的 JSON 库,功能十分全面。
FastJson: 阿里巴巴开发的 JSON 库,性能十分优秀。
Jackson: 社区十分活跃且更新速度很快。被称为“最好的 Json 解析器”

2.Jackson 简介

Jackson 是一种解析 JSON 格式数据的 API ,也是最流行,速度最快的 JSON API 。在
SpringMVC 中默认使用 Jackson API 处理 JSON 格式的数据。
Jackson 下载地址:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind

上面三个都要下载,以第一个为例,输入网址,红框处选择版本

然后点击View All

下载相应jar包:

3.在响应中通过 JSON 格式传递数据

在响应中使用 Jackson 处理 JSON 格式数据的步骤:
  • 添加 jackson-annotations.jarjackson-core.jarjackson-databind.jar
  • 通过 jackson API Java 对象转换 JSON 格式
  • 修改响应头,响应类型为 application/json
  • 将结果基于字符输出流推回客户端浏览器
  • 在页面的中通过 JavaScript JSON.parse()函数将 JSON 格式的数据转换为 JavaScript对象

四.通过 JSON 格式在响应中传递单个对象

需求:
定义一个 Users 类,包含 userid username 属性。
实例化一个 Users 对象,通过 JSON 格式将 Users 对象响应到客户端浏览器。
Users 对象中的数据插入到页面中。

还是上篇文章中导入servlet-api.jar的操作,导入jackson的三个jar包

然后再像下图一样,右键ajaxTest,点击 Put into Output Root,然后点击Apply,再点OK

项目结构:

Users.java:

右键--》Generate--》Getter and Setter-->选择属性,自动生成。

package com.first.pojo;

public class Users {
    private int userid;
    private String username;

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

SingleObjectServlet.java:

package com.first.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;

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;

/*
通过JSON格式响应单个对象
 */
@WebServlet("/single.do")
public class SingleObjectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Users对象
        Users users=new Users();
        users.setUserid(1);
        users.setUsername("kd");

        //不能通过字符流输出Users对象,
        // 要用Jackson的API将Users对象转换为JSON格式的字符串对象
        ObjectMapper objectMapper=new ObjectMapper();
        //将Users对象转换为JSON格式的字符串对象
        String string=objectMapper.writeValueAsString(users);
        System.out.println(string);

        //设置响应类型为application/json
        resp.setContentType("application/json");
        PrintWriter pw=resp.getWriter();
        pw.println(string);
        pw.flush();
        pw.close();
    }
}

?singleDemo.jsp:

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2022/5/10
  Time: 19:05
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <script>
        function btn() {
            var xhr=new XMLHttpRequest();
            xhr.open("get","single.do");
            xhr.send();
            xhr.onreadystatechange=function () {
                if (xhr.readyState == 4 && xhr.status == 200){
                    alert(xhr.responseText);
                    //通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对转换成javascript对象
                    var obj=JSON.parse(xhr.responseText);
                    alert(obj.userid+" "+obj.username);
                    document.getElementById("span").innerHTML=obj.userid+"<br/>"+obj.username;
                }
            }
        }
    </script>
</head>
<body>
<h3>JSON格式的单个对象响应</h3>
<hr/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>

运行:

访问:http://localhost:8888/ajaxTest/singleDemo.jsp

点击OK按钮

?

?

五.通过 JSON 格式在响应中传递多个对象

需求:
定义一个 Users 类,包含 userid username 属性。
实例化多个 Users 对象,通过 JSON 格式将 Users 对象响应到客户端浏览器。
Users 对象中的数据插入到页面中。

MultipleObjectServlet.java:

package com.first.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;

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.ArrayList;
import java.util.List;
@WebServlet("/multiple.do")
public class MultipleObjectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Users users1=new Users();
        users1.setUserid(1);
        users1.setUsername("kd");
        Users users2=new Users();
        users2.setUserid(2);
        users2.setUsername("kevin");

        //需要将多个对象放到集合中
        List<Users> list=new ArrayList<>();
        list.add(users1);
        list.add(users2);

        //通过jackson将List转换为JSON格式的字符串对象
        ObjectMapper objectMapper=new ObjectMapper();
        String string=objectMapper.writeValueAsString(list);
        System.out.println(string);

        resp.setContentType("application/json");
        PrintWriter pw=resp.getWriter();
        pw.println(string);
        pw.flush();
        pw.close();
    }
}

multipleDemo.jsp:

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2022/5/10
  Time: 23:07
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <script>
        function btn() {
            var xhr=new XMLHttpRequest();
            xhr.open("get","multiple.do");
            xhr.send();
            xhr.onreadystatechange=function () {
                if (xhr.readyState == 4 && xhr.status == 200){
                    alert(xhr.responseText);
                    //通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对转换成javascript对象
                    var obj=JSON.parse(xhr.responseText);
                    var temp="";
                    for (i=0;i<obj.length;i++){
                        alert(obj[i].userid+" "+obj[i].username);
                    }
                    temp+=obj[i].userid+" "+obj[i].username+"<br/>";
                    document.getElementById("span").innerHTML=temp;
                }
            }
        }
    </script>
</head>
<body>
<h3>JSON格式的多个对象响应</h3>
<hr/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>

Users类先前已经创建。

输出:

访问:http://localhost:8888/ajaxTest/multipleDemo.jsp

?

?

?

?

?六.在 JSON 中通过 Map 传递数据

JSON 格式中可以直接使用 Map 作为传递数据的模型。因为 Map 结构本身就是 key与 value 的结构与 JSON 格式对象模型完全匹配,所以我们可以直接将一个 Map 对象转换为 JSON 格式的字符串对象。这对于我们来说是一件非常方便的事情,如果我们返回的数据并 没有对应的模型来存放数据,那么我们可以通过 Map 来解决。

?MapModelServlet.java:

package com.first.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

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.HashMap;
import java.util.Map;
@WebServlet("/map.do")
public class MapModelServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //一个Map对象表示的是一个JSON格式的对象
        Map<String,Object> map=new HashMap<>();
        map.put("userid",1);
        map.put("url","map.do");

        ObjectMapper objectMapper=new ObjectMapper();
        //转换为JSON格式的字符串对象
        String string=objectMapper.writeValueAsString(map);
        System.out.println(string);

        resp.setContentType("application/json");
        PrintWriter pw=resp.getWriter();
        pw.println(string);
        pw.flush();
        pw.close();
    }
}

?mapDemo.jsp:

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2022/5/11
  Time: 14:22
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <script>
        function btn() {
            var xhr=new XMLHttpRequest();
            xhr.open("get","map.do");
            xhr.send();
            xhr.onreadystatechange=function () {
                if (xhr.readyState == 4 && xhr.status == 200){
                    alert(xhr.responseText);
                    //通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对转换成javascript对象
                    var obj=JSON.parse(xhr.responseText);
                    alert(obj.userid+" "+obj.url);
                    document.getElementById("span").innerHTML=obj.userid+"<br/>"+obj.url;
                }
            }
        }
    </script>
</head>
<body>
<h3>在JSON中通过Map传递数据</h3>
<hr/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>

?输出:

访问?http://localhost:8888/ajaxTest/mapDemo.jsp

?

?

?

七.在请求中通过 JSON 格式传递数据

我们除了可以在响应中通过 JSON 格式来传递数据以外,在 请求中 也可以使用 JSON 格式传递数据。如果在请求中使用 JSON 格式传递数据,那么提交方式需要使用 POST 方式 通过 JavaScript 中的 JSON.stringify() 函数将 JavaScript 对象转换为 JSON 格式数据。通过 send
方法将参数传递到 Servlet 中,在 Servlet 中通过 字符输入流 获取 JSON 格式数据。
在请求中使用 Jackson 处理 JSON 格式数据的步骤:
  • 添加 jackson-annotations.jarjackson-core.jarjackson-databind.jar
  • 在页面的 JavaScript 中通过 JSON.stringify()函数将 JavaScript 对象转换为 JSON 格式的数据
  • 将请求方式修改为 POST 方式
  • 通过 send()函数将 JSON 格式的数据提交到服务端。
  • Servlet 中通过字符输入流读取请求体中 JSON 格式的数据
  • 通过 jackson API 将获取到的 JSON 格式的数据转换为 Java 对象

requestDemo.jsp:

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2022/5/11
  Time: 14:44
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <script>
        function btn() {
            var id=document.getElementById("userid").value;
            var name=document.getElementById("username").value;
            /*将信息构造成JavaScript对象,因为下面的函数只能对JavaScript对象进行操作
            这里的键必须和Users类里的属性名相同,因为servlet里要根据名称构造类对象
             */
            var obj={userid:id,username:name};
            //将 JavaScript 对象转换为 JSON 格式的数据
            var  content=JSON.stringify(obj);
            alert(content);

            var xhr=new XMLHttpRequest();
            xhr.open("post","json.do");
            //post方式传递请求信息,get时是无参
            xhr.send(content);
            xhr.onreadystatechange=function () {
                if (xhr.readyState == 4 && xhr.status == 200){
                    alert(xhr.responseText);
                    document.getElementById("span").innerHTML=xhr.responseText;
                }
            }
        }
    </script>
</head>
<body>
<h3>在请求中通过JSON格式传递数据</h3>
<hr/>
用户ID:<input name="userid" id="userid"/><br/>
用户姓名:<input name="username" id="username"/><br/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>

?RequestJSONServlet.java:

package com.first.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;

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;
@WebServlet("/json.do")
public class RequestJSONServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //防止请求信息中有汉字造成乱码
        req.setCharacterEncoding("utf-8");
        //通过字符输入流从请求体中获取提交的JSON格式的数据
        String s=req.getReader().readLine();

        //使用Jackson将JSON格式的字符串对象转换成java对象
        ObjectMapper objectMapper=new ObjectMapper();
        //根据类模板(第二个参数)来解析json数据生成响应类的对象
        Users users=objectMapper.readValue(s,Users.class);
        System.out.println(users.getUserid()+" "+users.getUsername());

        resp.setContentType("application/json");
        PrintWriter pw=resp.getWriter();
        pw.println("OK");
        pw.flush();
        pw.close();
    }
}

?输出:

?

?

?

?八.Jackson 的常用注解

1.@JsonProperty

此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把 username 属性序列化为 name @JsonProperty("name")

2.@JsonIgnore

此注解用于属性或者方法上(一般都是定义在属性上),用来完全忽略被注解的字段和方法对应的属性,返回的 json 数据即不包含该属性。

3.@JsonFormat

此注解用于属性或者方法上(一般都是定义在属性上),可以方便的把 Date 类型属性的值直接转化为我们想要的样式。如: @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss")

annDemo.jsp:

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2022/5/11
  Time: 16:01
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
    <script>
        function btn() {
            //创建 XMLHttpRequest 对象
            var xhr=new XMLHttpRequest();
            //请求一个servlet,这个servlet的url是ajax.do
            xhr.open("get","ann.do");
            //发送异步请求
            xhr.send();
            //获取服务器端给客户端的响应数据
            //当send函数执行之后,下面的函数立即执行
            xhr.onreadystatechange=function () {
                //0:open()没有被调用
                // 1:open()正在被调用
                // 2:send()正在被调用
                // 3:服务端正在返回结果
                // 4:请求结束,并且服务端已经结束发送数据到客户端

                //响应成功
                if(xhr.readyState==4 && xhr.status == 200){
                    //输出服务端返回的内容
                    alert(xhr.responseText);
                    //将返回内容放到span标签中
                    document.getElementById("span").innerHTML=xhr.responseText;
                }
            }
        }
    </script>
</head>
<body>
<h3>Jackson 的常用注解</h3>
<hr/>
<span id="span">点击按钮改变</span>
<input type="button" value="ok" onclick="btn()"/>
</body>
</html>

?Users.java:

package com.first.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Date;

public class Users {
    @JsonIgnore
    private int userid;
    /*java对象以json形式输出时,这个键不再是username,而是name
    如果是json串转换成Java对象,那么键是name时,对应对象的username
     */

    //@JsonIgnore 已经有注解的属性上再加这个属性是使这个属性的其他注解无效
    @JsonProperty("name")
    private String username;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date userBirth;

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getUserBirth() {
        return userBirth;
    }

    public void setUserBirth(Date userBirth) {
        this.userBirth = userBirth;
    }
}

?AnnotationServlet.java:

package com.first.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;

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.Date;

@WebServlet("/ann.do")
public class AnnotationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Users users=new Users();
        users.setUserid(1);
        users.setUsername("kd");
        users.setUserBirth(new Date());

        ObjectMapper objectMapper=new ObjectMapper();
        //将Users对象转换为JSON格式的字符串对象
        String string=objectMapper.writeValueAsString(users);
        System.out.println(string);

        resp.setContentType("application/json");
        PrintWriter pw=resp.getWriter();
        pw.println("Jackson Annoation");
        pw.flush();
        pw.close();

    }
}

输出:

{"userBirth":"2022-05-11","name":"kd"}

九.Jackson 工具类的使用

创建common文件夹,存放工具类

JsonUtils.java:

package com.first.common;

import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * JSON转换工具类
 */
public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
    	try {
			String string = MAPPER.writeValueAsString(data);
			return string;
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
    	JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
    	try {
    		List<T> list = MAPPER.readValue(jsonData, javaType);
    		return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
    	
    	return null;
    }
    
}

?上节的?AnnotationServlet.java可做如下修改:

//        ObjectMapper objectMapper=new ObjectMapper();
//        //将Users对象转换为JSON格式的字符串对象
//        String string=objectMapper.writeValueAsString(users);
        String string= JsonUtils.objectToJson(users);
        System.out.println(string);

可见输出还是一样。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 11:40:51  更:2022-05-13 11:40:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:50:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码