### 客户端使用AJAX实现异步访问
`Ajax`即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
首先,应该引用`jQuery`文件,然后,调用`jQuery`框架中提供的`$.ajax()`函数以发出AJAX请求。
在`$.ajax()`函数中,函数的参数是1个JSON对象,常规访问至少需要配置5个属性:
- `url`:将请求提交到哪里去,取值可以是相对路径,也可以是绝对路径;
- `data`:请求参数,通常格式是`名称1=值1&名称2=值`这样的格式;
- `type`:请求类型,通常是`post`或`get`;
- `dataType`:服务器端响应的数据的类型,取值可以是`text`/`json`/`xml`,将根据响应头的Content Type决定;
- `success`:成功响应时(Http响应码是2xx)的回调函数,函数的参数是服务器端响应的JSON字符串转换得到的JSON对象
<script type="text/javascript" src="jquery-3.4.0.min.js"></script> <script type="text/javascript"> $("#btn-reg").click(function(){ $.ajax({ "url":"user/reg.do", "data":"username=" + $("#username").val(), "type":"post", "dataType":"json", "success":function(json) { alert("state=" + json.state); } }); }); </script>
### 1. 响应正文
当客户端向服务器端发出请求后,服务器端的响应方式是直接将某字符串响应给客户端,如果客户端是通过浏览器发出的请求,则在浏览器的界面中显示的就一个字符串!
使用这种做法的优点在于:服务器端不必再处理界面,即不需要考虑响应请求时,应该呈现什么样的界面给客户端,只是单纯的向客户端响应处理的结果,例如用1表示成功,用0表示失败,至于客户端如何处理这些结果并显示,是不需要服务器端关心的问题,同时,也就解决了多种不同的客户端的显示问题,例如PC端、手机端、平板电脑端,因为设备的差异,显示方式也应该有所不同,这些问题都可以交给不同的客户端开发人员去进行处理,另外,附带的好处就是服务器端产生流量消耗也会更小,因为响应的正文的长度一定远远小于响应一个页面的内容的长度。
响应正文的做法就是在处理请求的方法之前添加`@ResponseBody`注解即可:
@Controller @RequestMapping("user") public class UserController { @RequestMapping("reg.do") @ResponseBody public String reg() { return "hello"; } }
### 2. 响应的正文的格式
不可以每次只向客户端响应`1`或`0`或者某个数字,因为客户端请求后,可能要求得到更多的结果!例如客户端发出请求的目的就是为了得到某些数据,例如当前登录的用户的信息等。
服务器端如果需要向客户端响应数据,就不能直接把数据的多项属性直接写在1个字符串中,例如响应为`"小六2517575"`是不合适的,客户端很难或者无者正确的从这1个字符串拆分出所需要各种信息!所以,服务器端响应给客户端的正文应该是有一定格式的,以保证客户端接收到这个正文可以拆分出必要的信息。
例如可以使用XML语法去组织相关信息:
<user> <name>小六</name> <age>25</age> <height>175</height> <weight>75</weight> </user>
但是,使用XML也存在一定的问题:
1. 语法格式相对比较繁琐,且占用的字符数量较多;
2. 数据的产生与解析相对繁琐;
目前,业内比较提倡的是使用JSON格式来组织数据,例如:
{ "name":"小六", "age":25, "height":175, "weight":75 }
### 3. JSON数据格式
JSON数据格式是Javascript语言默认直接解析的,因为JSON是Javascript中的一种数据类型!
JSON的数据格式:
1. 每个JSON数据都是一个对象,每个对象都应该使用`{}`框住;
2. 每个对象中可以有若干条属性,属性名是字符串格式的,需要使用引号框住,属性值可以根据数据类型来决定是否使用引号框住,各属性之间使用逗号分隔;
3. 属性的值也可以是一系列数据,表现为JSON中的数组,数组需要使用`[]`框住,也可以通过数组属性的length获取数组的长度,也可以结合循环语法遍历数组;
JSON主要用于组织数据,并在网络中进行传递,当客户端接收到JSON数据,数据本身其实是一个字符串,可以使用`JSON.parse(str)`将字符串格式的数据转换为JSON对象,当然,前提是这个字符串的格式是符合JSON数据格式的。
### 4. 服务器端向客户端响应JSON格式的数据
当控制器中处理请求的方法添加`@ResponseBody`注解后,SpringMVC框架会通过转换器`Converter`实现响应正文。
SpringMVC中默认内置了一些转换器,适用于不同的返回类型,如果处理请求的方法的返回值类型是`String`,则会自动调用`StringHttpMessageConverter`,该转换器默认使用的编码就是`ISO-8859-1`,所以,默认是不支持中文的!
使用`Jackson`框架可以直接解决响应JSON数据及支持中文的问题!当项目中添加了`Jackson`依赖后,如果控制器中处理请求的方法的返回值并不在SpringMVC默认支持的范围之内(例如不是`String`),则SpringMVC会直接调用`Jackson`框架中的转换器来响应正文!
<!-- jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
使用`Jackson`框架时,需要在Spring的配置文件中启用注解驱动:
<!-- 注解驱动 --> <mvc:annotation-driven />
具体的使用可以是:
@RequestMapping("reg.do") @ResponseBody public User reg() { User user = new User(); user.setName("小六"); user.setAge(30); user.setWeight(80); return user; }
当提交访问时,通过客户端的浏览器,可以看到响应正文就是:
{"name":"小刘老师","age":30,"weight":80}
并且,`Jackson`框架还修改了`Response Headers`,将响应类型设置为:
Content-Type: application/json;charset=UTF-8
也就是客户端得到的就是JSON格式的字符串,并且,是支持中文的!
通常,在每个项目中,都会创建1个类,用于表示服务器向客户端响应正文的数据类型。
public class ResponseResult<T> { private Integer state; // 状态,使用数值描述此次用户的操作成功与否 private String message; // 消息,用于用户操作失败时描述错误的原因 private T data; // 数据,用于向客户端提供数据 }