Ajax和JSON的基本用法

局部请求页面不会变化,返回的响应我们要动态获取,获取后选择数据更新区域。

<body>
<input id="btnLoad" type="button" value="加载">
<div id="divContent"></div>
<script>
    //获取点击按钮
    document.getElementById("btnLoad").onclick=function (){
     var xmlhttp;
     //根据不同的浏览器,创建xmlhttp的对象
     if(window.XMLHttpRequest){
         xmlhttp = new XMLHttpRequest();
     }else{
         xmlhttp=new ActiveXObject("eage.xmlhttp")
     }
        console.log("xmlhttpRequest", xmlhttp);
        //创建一个请求
        xmlhttp.open("GET", "/content");
        //发送一个请求
        xmlhttp.send();
        //监听ajax的执行过程
        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                //获取响应的文本
               var t=xmlhttp.responseText;
                console.log(t);
                console.log(document.getElementById("divContent").innerHTML);
                document.getElementById("divContent").innerHTML=document.getElementById("divContent").innerHTML+"<br/>"+t;
            }
        };
    }
</script>

全局请求会更新整个页面例子如下。

<body>
    <form action="/request" method="post">
      <input name="username"/>
      <input name="password" type="password"/>
      <input type="submit">
    </form>
</body>
@WebServlet("/request")
public class RequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse respose) throws ServletException, IOException {
        respose.getWriter().println("get");直接更新了整个页面
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse respose) throws ServletException, IOException {
        respose.getWriter().println("post");
    }
}

respose.getWriter().println("get");会将原来的页面销毁掉,重新生成另一张页面,但是在原来的页面中有不需要刷新的页面,我们想要的效果只是小部分区域进行显示刷新出来的内容,这时就要用到Ajax。

[
    {
        "empno": "7369",数字可以加双引号也可以不加
        "ename": "李宁",
        "job": "软件工程师",
        "hiredate": "2015-02-2",
        "salary": 1300,
        "dname": "研发部"
    },
    {
        "empno": "73691",
        "ename": "李上",
        "job": "软件工程师",
        "hiredate": "2015-02-2",
        "salary": 1300,
        "dname": "研发部"
    }
]

JS如何展示json数据利用json数据如下

<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script type="text/javascript">
    var employeeList=
    [
      {
        "empno": "7369",
        "ename": "李宁",
        "job": "软件工程师",
        "hiredate": "2015-02-2",
        "salary": 1300,
        "dname": "研发部"
      },
      {
        "empno": "73691",
        "ename": "李上",
        "job": "软件工程师",
        "hiredate": "2015-02-2",
        "salary": 1300,
        "dname": "研发部"
      }
    ]
    for(var i=0;i<employeeList.length;i++){
      var employee=employeeList[i];
      console.log(employee);
      document.write("<h1>");
      document.write(employee.ename);
      document.write(employee.empno);
      document.write(employee.job);
      document.write("</h1>");
    }
  </script>
</head>

注意:ajax请求返回的不再与展现相关,而是纯纯的数据,浏览器接受后要考虑如何展示。

两个数据转换核心问题:

  1. 数据对象序列化为JSON字符串----JacKson解决序列化问题

  1. JSON字符串如何转换成数据对象--

@WebServlet("/news")
public class NewServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<News> list = new ArrayList<>();
        list.add(new News("TIOBE:2018编程语言排行趋势","2018","TIBOT","...."));
        list.add(new News("TIOBE:2017编程语言排行趋势","2017","TIBOT","...."));
        list.add(new News("TIOBE:2016编程语言排行趋势","2016","TIBOT","...."));
        //序列化过程,可能报错
        ObjectMapper objectMapper=new ObjectMapper();
        String json = objectMapper.writeValueAsString(list);
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().println(json);
    }
}

Tomcat配置问题:Warning:The selected directory is not a TomEE home

解决:tomcat选择的时候选错了

错误: 代理抛出异常错误: java.rmi.server.ExportException: Port already in use: 1099; nested exception is:

java.net.BindException: Address already in use: JVM_Bind

解决:端口占用了

解决:中途导入的jar包和依赖没有被out出来,最后允许的目录在Out,如果jar添加了,out没有,那么此时需要手动添加

反序列化过程:

<body>
    <div id="container"></div>
    <script>
       //开始纯手工处理ajax
      var xmlhttp;
      if(window.XMLHttpRequest){
        xmlhttp=new XMLHttpRequest();
      }else {
        xmlhttp=new ActiveXObject("XMLHTTP");
      }
      xmlhttp.open("GET","/news");
      xmlhttp.send();
      xmlhttp.onreadystatechange = function () {
        if(xmlhttp.readyState==4&&xmlhttp.status==200){
          var str=xmlhttp.responseText;
            //JSON.parse()方法,把字符串编程json的对象
          console.log(JSON.parse(str));
          //渲染页面(二次加工数据)
            for (var i = 0; i < json.length; i++) {
                var news=json[i];
                var container = document.getElementById("container");
                container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
            }
        }
      };
    </script>
</body>

原生的ajax要创建对象,接受并且判断响应,很麻烦,有封装好的。

get方式发送请求:

<body>
<div id="container"></div>
    <script>
      // 第一个参数是对应的url是什么,,第二个向服务器传递的参数
      //axios.get('/news?t=pypl').then。。的传参方式也可
        axios.get('/news',{params:{"t":"pypl"}}).then(function (response) {
          console.log(response);
          var json=response.data;
            for (var i = 0; i < json.length; i++) {
                var news=json[i];
                var container = document.getElementById("container");
                container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
            }
        }).catch(function (error) {
          console.log(error);
        });
    </script>
</body>

post方式发送请求:

    <script>
      //写法一
      //"t=pypl&1=abc连续的参数用&隔开
      //{headers:{"content-type":"application/x-www-form-urlencoded"}}手动定义请求头固定写法
      // axios.post("/news1","t=pypl&1=abc",
      //     {headers:{"content-type":"application/x-www-form-urlencoded"}})
      //写法二
      const params = new URLSearchParams();
      params.append("t","pypl");
      params.append("l","abc");
      axios.post("/news",params)
          .then(function (response) {
              console.log(response);
              var json = response.data;
              for (var i = 0; i < json.length; i++) {
                  var news = json[i];
                  var container = document.getElementById("container");
                  container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
              }
          }).catch(function (error) {
              console.log(error);
          });
    </script>

异步执行代码实例:

<body>
    <div id="container"></div>
    <script>
      var xmlhttp;
      if(window.XMLHttpRequest){
        xmlhttp=new XMLHttpRequest();
      }else {
        xmlhttp=new ActiveXObject("XMLHTTP");
      }
      xmlhttp.open("GET","/news?t=pypl");
      xmlhttp.send();
      console.log("请求已经发送");
      xmlhttp.onreadystatechange = function () {
        if(xmlhttp.readyState==4&&xmlhttp.status==200){
          var str=xmlhttp.responseText;
            //JSON.parse()方法,把字符串编程json的对象
          console.log(JSON.parse(str));
          //渲染页面(二次加工数据)
            for (var i = 0; i < json.length; i++) {
                var news=json[i];
                var container = document.getElementById("container");
                container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
            }
        }
      };
    </script>

结果:send没有收到响应,就执行console.log("请求已经发送");这句话,然后随着状态变化事件得到执行。

<body>
    <div id="container"></div>
    <script>
      var xmlhttp;
      if(window.XMLHttpRequest){
        xmlhttp=new XMLHttpRequest();
      }else {
        xmlhttp=new ActiveXObject("XMLHTTP");
      }
      xmlhttp.open("GET","/news?t=pypl",false);
      xmlhttp.send();
      console.log("请求已经发送");
      if(xmlhttp.readyState==4&&xmlhttp.status==200){
          var str=xmlhttp.responseText;
          //JSON.parse()方法,把字符串编程json的对象
          console.log(JSON.parse(str));
          //渲染页面(二次加工数据)
          for (var i = 0; i < json.length; i++) {
              var news=json[i];
              var container = document.getElementById("container");
              container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
          }
      }
      
      xmlhttp.onreadystatechange = function () {

      };
    </script>
</body>

结果:当send执行没有结束,没有收到响应,不会执行console.log("请求已经发送");,导致事件状态变化监听失败,所以if必须提前,那么就可以执行相应的语句;

效果

准备数据

@WebServlet("/channel")
public class ChannerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //levels为一级目录大类,parent为一级大类的code,这两个都是用户选择的参数
        //用户根据需要选择一级大类,然后根据用户的选择获取大类的code,再用parent和用户选择的比较,得到二级大类
        String level=request.getParameter("level");
        String parent = request.getParameter("parent");
        List<Channel> chlist = new ArrayList<>();
        if (level==null){
            level = "0";
        } else if (parent==null) {
            parent = "0";
        }
        if (level.equals("1")) {
            chlist.add(new Channel("ai","人工智能"));
            chlist.add(new Channel("web","前端开发"));
        }else if(level.equals("2")){
            if (parent.equals("ai")) {
                chlist.add(new Channel("dl","深度学习"));
                chlist.add(new Channel("cv","计算机视觉"));
                chlist.add(new Channel("nlp","自然语言处理"));
            } else if (parent.equals("web")) {
                chlist.add(new Channel("html","前端html"));
                chlist.add(new Channel("css","前端css"));
                chlist.add(new Channel("js","前端js"));
            }
        }
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(chlist);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(json);
    }
}

实体类:

public class Channel {
    private String code;
    private String name;

    public Channel(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

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

前端界面发送请求:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
</head>
<body>
<select id="lv1" style="width: 200px;height: 30px">
  <option value="-1" selected="selected">请选择</option>
</select>

<!--//不写option标签,直接往里边添加会直接显示-->
<select id="lv2" style="width: 200px;height: 30px">
</select>
<script>
    //获取lv1标签,为了往lv1的option中放数据
    var lv1 = document.getElementById("lv1");
    axios.get("/channel",{params:{"level":1}})
        .then(function (response) {
            var json = response.data;
            console.log(json);
            for (var i=0;i<json.length;i++){
                var channel = json[i];
                //新创建的option对象,第一个参数是text,第二个是value
                // new(text?: string, value?: string,...)
                //如果有选择,那么select的value就是option的value
                lv1.options.add(new Option(channel.name, channel.code));
            }
        });
    var lv2 = document.getElementById("lv2");
    lv1.onchange=function () {
        axios.get("/channel",{params:{"level":2,"parent":lv1.value}})
            .then(function (response) {
                var json = response.data;
                //直接把之前的数据清除的办法,length=0就行了
                lv2.length=0;
                console.log(json);
                for (var i=0;i<json.length;i++){
                    var channel = json[i];
                    lv2.options.add(new Option(channel.name, channel.code));
                }
            });
    }
</script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码敲上天.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值