### 1. 响应正文
 
传统的处理请求时,响应的方式有转发或重定向,无论是哪种,最终都会直接呈现某个页面给客户端,这样做的缺点在于:
 
1. 用户体验可能不好,例如:用户注册时,提交的用户名被占用,出现错误,转发到错误页面,而用户操作时就必须从错误页面返回注册页,可能丢失原输入的内容,需要重新输入;
2. 流量消耗可能较大,例如:用户注册时,客户端所需的只是“1-成功;2-失败”等类似的结果即可,并不一定需要整个页面,同时,流量消耗较大也会对用户体验有不好的影响;
3. 可能不太适合多种不同的客户端,例如网页端、Android手机端、Android平板电脑端、iOS手机端、iOS平板电脑端。
 
所以,解决以上问题的方案就是:服务器端只提供服务,不处理界面,当客户端提交某种请求后,服务器端只响应相关数据,而不再响应页面,至于页面的处理,就交给各个客户端去处理。
 
假设:某用户提交了登录请求到`http://localhost:8080/项目/user/handle_login.do`,同时,还提交了参数`username`和`password`表示用户名和密码,服务器端对用户名和密码进行了判断,需要给出直接的响应结果,而不再转发或重定向:
 
    @RequestMapping("/handle_login.do")
    @ResponseBody
    public String handleLogin(
            String username, String password) {
        return "OK";
    }
 
当添加了`@ResponseBody`后,处理请求的方法的返回值就是**响应正文**,而不再表示转发或重定向。
 
假设:验证登录的规则是:仅`root/1234`这组用户名和密码可以登录,登录成功时提示信息,登录失败时也提示出错的原因。
 
 
 
### 2. JSON数据格式
 
为了更好的实现“服务器端向客户端响应数据”,能够满足各种不同的数据格式要求,应该将服务器端响应的内容有规则的组织起来,例如,可以使用XML语法来组织数据:
 
    <result>
        <state>1</state>
        <message>登录成功</message>
    </result>
 
或:
 
    <result>
        <state>2</state>
        <message>您输入的用户名XXX不存在!</message>
    </result>
 
或:
 
    <result>
        <state>1</state>
        <data>
            <user>
                <id>1</id>
                <username>Mike</username>
                <password>1234</password>
            </user>
            <user>
                <id>2</id>
                <username>Jack</username>
                <password>1234</password>
            </user>
            <user>
                <id>3</id>
                <username>Lucy</username>
                <password>1234</password>
            </user>
        </data>
    </result>
 
但是,使用XML来组织数据也存在一定的问题:
1. 解析难度略大;
2. 节点产生的不必要数据太多。
 
当前,主流的解决方案是使用JSON格式来组织数据:
 
    {
        "state":1,
        "message":"登录成功"
    }
 
或:
 
    {
        "state":2,
        "message":"您输入的用户名XXX不存在!"
    }
 
或:
 
    {
        "state":1,
        "data":[
            {
                "id":1,
                "username":"Mike",
                "password":"1234"
            },
            {
                "id":2,
                "username":"Jack",
                "password":"1234"
            },
            {
                "id":3,
                "username":"Lucy",
                "password":"1234"
            }
        ]
    }
 
可以看到,JSON的基本语法格式是:
1. 整个JSON数据使用一对大括号框住;
2. 可以有若干个属性与值的配置,属性与值之间使用冒号分隔,多个属性的配置之间使用逗号分隔,属性名应该使用双引号框住,属性的值如果是数值或布尔值可以直接写,如果是字符串则需要使用双引号框住。
3. JSON中也可以有数据,使用`[]`框住数组数据,数组中的各元素之间使用逗号进行分隔;
4. JSON中也可以有对象,甚至整个JSON数据就是一个对象,所有对象都应该使用`{}`框住,各属性的配置之间使用逗号分隔;
5. 以上各种不同的配置之间可以组合,例如数组的元素可以是对象,而对象中某属性的值也可以是数组。
 
### 3. 服务器响应JSON数据
 
通常,服务器向客户端响应的数据都会包括几项内容:
1. 状态码:服务器与客户端约定某个数值表示某种意义,例如约定1表示操作成功,0表示操作失败,或其它数字表示某种意义;
2. 消息:通常是对操作失败时的错误的描述,用于被客户端用于提示用户;
3. 数据:某些请求的目标只是希望得到操作成功与否的结果,例如登录、注册等,而某些请求的目标是希望获取数据的,例如显示用户列表等,对于获取数据的请求,则应该专门给予数据;
 
为了设计一个通用的响应的类型,可以:
 
    public class ResponseResult<E> {
        private Integer state;
        private String message;
        private E data;
        // SET/GET,Serialiazable
    }
 
然后,添加Jackson依赖:
 
    <!-- Jackson -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.8</version>
    </dependency>
 
最后,将处理请求的方法的返回值类型修改为`ResponseResult`类型,并且,在方法体中,根据不同的登录结果,为`ResponseResult`中的属性赋予不同的值即可:
 
    @RequestMapping("/handle_login.do")
    @ResponseBody
    public ResponseResult<Void> handleLogin(
            String username, String password) {
        ResponseResult<Void> rr
            = new ResponseResult<Void>();
        if ("root".equals(username)) {
            if ("1234".equals(password)) {
                // 登录成功
                rr.setState(1);
                rr.setMessage("登录成功");
            } else {
                // 密码错
                rr.setState(2);
                rr.setMessage("密码错");
            }
        } else {
            // 用户名错
            rr.setState(3);
            rr.setMessage("用户名错");
        }
        return rr;
    }
 
在SpringMVC框架中,当响应正文时(方法添加了`@ResponseBody`时),框架会根据方法的返回值类型寻找匹配的转换器,框架本身支持多款转换器,所以,会一一尝试,直到找到匹配的,例如返回String类型,就会使用内置的字符串的转换器(`StringHttpMessageConverter`),当把返回值声明为自定义的`ResponseResult`时,SpringMVC框架默认并没有内置相关的转换器,就会自动Jackson(Jackson中包括支持任何类型的转换器),而Jackson中的转换器的工作模式就是将响应的对象转换为JSON格式的字符串,并且,在响应头(Response Headers)中设置响应内容为`application/json,charset=utf8`。
 
### 4. 在Javascript中访问JSON数据
 
Javascript是默认直接识别JSON数据的,不需要编写特殊的解析程序。
 
假设存在:
 
    var json = {  
        "state":1,  
        "message":"登录成功!",  
        "data": [
            {
                "id":31,
                "username":"Jack",
                "password":"123456"
            },  
            {
                "id":35,
                "username":"Lucy",
                "password":"888888"
            },  
            {
                "id":36,
                "username":"Mike",
                "password":"654321"
            }
        ]
    };
 
通过`json.state`即可以访问到`"state"`属性的值,同理,通过`json.message`就可以访问到`"message"`属性的值,由于`"data"`属性的值的类型是数组,直接访问时,会显示为数组元素的输出,应该通过例如`json.data[1]`访问其中的某个元素,当然,该数组中的元素都是JSON对象,可以继续向下访问其中的某个属性,例如`json.data[1].username`即可获取到`"Lucy"`值。
 
在JSON中的数组也是可以循环或遍历的:
 
    for (var i = 0; i < json.data.length; i++) {
        console.log(json.data[i].id);
        console.log(json.data[i].username);
        console.log(json.data[i].password);
        console.log("");
    }
 
但是,在绝大部分情况下,获取到的JSON数据可能并不是一个JSON对象,而只是符合JSON语法的字符串而已,所以,还需要通过`JSON.parse()`函数将字符串转换为JSON对象:
 
    var json = JSON.parse(str);
 
### 5. AJAX
 
AJAX用于提交异步请求。
    //$("#username-hint"):或取当前元素对象。
    // 为按钮绑定单击事件
    $("#btn-login").click(function() {
        $("#username-hint").empty();
        $("#password-hint").empty();
        // 发出异步请求,获取响应
        // 调用$.ajax()函数即可发出请求并处理响应结果
        // $.ajax()函数的参数是JSON对象
        // url:把请求提交到哪里,相当于<form>中的action
        // data:提交到服务器端的数据,格式:param1=value1&param2=value2
        // type:提交方式,取值为POST或GET
        // dataType:服务器端响应的数据的类型,可以是text、json、xml,取决于服务器响应时的响应头中例如"application/json"
        // success:服务器端成功响应时的回调函数,函数的参数就是服务器端响应的数据,并且已经转换为指定的格式
        var u = $("#username").val();
        var p = $("#password").val();
        $.ajax({
            "url":"user/handle_login.do",
            "data":"username=" + u + "&password=" + p,
            "type":"POST",
            "dataType":"json",
            "success":function(json) {
                if (json.state == 1) {
                    alert("登录成功!");
                } else if (json.state == 2) {
                    $("#password-hint").html(json.message);
                } else if (json.state == 3) {
                    $("#username-hint").html(json.message);
                } else {
                    alert("发生未知错误!");
                }
            }
        });
    });
    </script>

参考链接:https://www.cnblogs.com/package-java/p/10385788.html

AJAX和JSON笔记的更多相关文章

  1. ajax+jquery+JSON笔记

    ajax (asynchronous javascript and xml -- 基于javascript和xml的异同步通讯技术)    特征: 异步通讯  异步的请求-响应模式     1.传统的 ...

  2. AngularJS学习笔记(3)——通过Ajax获取JSON数据

    通过Ajax获取JSON数据 以我之前写的与用户交互的动态清单列表为例,使用JSON前todo.html代码如下: <!DOCTYPE html> <html ng-app=&quo ...

  3. ASP.NET 5 - $.ajax post JSON.stringify(para) is null

    JavaScript 代码: var para = {}; para.id = $("#ad-text-id").val(); para.title = $("#ad-t ...

  4. qt qml ajax 获取 json 天气数据示例

    依赖ajax.js类库,以下代码很简单的实现了获取天气json数据并展示的任务 [TestAjax.qml] import QtQuick 2.0 import "ajax.js" ...

  5. ajax将json写到table中去

    查询条件: <table style="width: 100%;border-collapse: collapse;" > <tr> <th styl ...

  6. ajax获取json对象

    ajax获取json对象 ajax获取json数据,都是一个原理,设置response 的Content-Type:application/json,这样浏览器自动会解析为json对象 $result ...

  7. Ajax与json在前后端中的细节解惑

    ajax请求JSON Thinkphp中对是否为Ajax的判断,在TP3.2开发手册中有这么一段:“需要注意的是,如果使用的是ThinkAjax或者自己写的Ajax类库的话,需要在表单里面添加一个隐藏 ...

  8. Ajax与Json的一些总结

    Ajax与Json AJAX=异步javaScript 和XML AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新. 这意味着可以在不 ...

  9. ajax返回JSON时的处理方式

    JSON中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value). json_encode() 该函数主要用来将数组和对象, ...

随机推荐

  1. Hacking PHP

    0X01 SQL注入 这里主要是PHP的防范注入的几个配置,注入手法不再赘述 magic_quotes_gpc 对 $_GET $_POST $_COOKIE 变量中的 ' " \ 空字符( ...

  2. sklearn学习4----预处理(1)标准化

    一.[标准化]scale: 1.导入模块  from sklearn.preprocessing import scaler 2.作用:直接将给定数据进行标准化 3.使用代码 X_scaled=sca ...

  3. laravel :Call to undefined function App\Http\Controllers\success() 解决方法

    今天在调用方法时,报错如下:Call to undefined function App\Http\Controllers\success():方法已定义好了,所以我怀疑是未引入function.ph ...

  4. HDU 2276 Kiki & Little Kiki 2( 矩阵快速幂 + 循环同构矩阵 )

    蒟蒻的我还需深入学习 链接:传送门 题意:给出一个长度为 n,n 不超过100的 01 串 s ,每当一个数字左侧为 1 时( 0的左侧是 n-1 ),这个数字就会发生改变,整个串改变一次需要 1s ...

  5. UVALive-7197 Axles 动态规划 多个背包问题

    题目链接:https://cn.vjudge.net/problem/UVALive-7197 题意 需要生产n种(2<=n<=14)零件,每种零件可以用两种材料制作,对这两种材料的消耗相 ...

  6. BZOJ 1016 最小生成树计数(矩阵树定理)

    我们把边从小到大排序,然后依次插入一种权值的边,然后把每一个联通块合并. 然后当一次插入的边不止一条时做矩阵树定理就行了.算出有多少种生成树就行了. 剩下的交给乘法原理. 实现一不小心就会让程序变得很 ...

  7. 查看系统进程:ps、top

    1.ps命令:提供最近进程的快照.显示当前活跃进程的简要信息. 常见使用: (1)与grep命令配合查找是否有相应进程存活 ps -ef | grep ksmd ps -Af | grep ksmd ...

  8. 小学生都能学会的python(运算符 和 while循环)

    ---恢复内容开始--- 小学生都能学会的python(运算符和编码) 一.格式化输出 #占位:"%s"占位,占得是字符串,"%d"占位,占的是数字. # 让用 ...

  9. ucore_lab0

    一直想好好学习一下操作系统课程,去一个Mooc网站上找了一门操作系统的课程.这便是里面的配套实验. 实验指导:点这里 lab0主要是准备相关的操作环境.课程推荐使用qemu作为硬件模拟器,推荐运行环境 ...

  10. oracle查询表空间的位置

    SELECT * FROM Dba_Data_Files ddf WHERE ddf.tablespace_name = 'TablespaceName'; 以上SQL代码可以查询出表空间的所在路径和 ...