1. 服务器的响应方式
在传统模式下,服务器端向客户端的主要响应方式是:转发,或重定向。使用这种模式时,通常,服务器端会向客户端响应某个页面,而这种模式是不利于当前的互联网架构的!因为现在客户端的种类越来越多,例如:电脑上的网页客户端、Android手机APP、iOS手机APP、Android平板电脑、iOS平板电脑、其它智能设备等,不同的设备存在明显的屏幕尺寸差异,如果把同一个网页响应到不同的客户端,是极为不合适的!所以,传统的响应模式只能适用于一些简单的、没有多种客户端的应用场景,例如:不知名的小型网站,内部的办公系统等。
目前,推荐的响应方式是:服务器端只向客户端响应必要的数据(不包括页面)!例如,在处理注册时,客户端将请求提交到服务器端之后,服务器端处理完注册请求,向客户端响应0
表示注册失败,或响应1
表示注册成功即可,至于页面如何处理,由客户端程序自行决定。
这是一种“前后端分离”的模式,服务器端就是“后端”,所有的客户端都统一称之为“前端”。
当使用前后端分离的模式后,服务器每次响应时,响应的数据量也会更小,传输耗时更短,用户体验更好,也能够很大程度的节省服务器在带宽流量费用!
2. 响应正文的格式
假设客户端向服务器端提交的是“用户注册”的请求,服务器在处理完成后,可以向客户端响应0
或1
或其它值的数据。
假设客户端向服务器端提交的是“查看用户数据详情”的请求,则最终服务器将需要将某个用户的完整信息响应到客户端,可能包括用户名、密码、年龄、手机号码、电子邮箱等数据,但是,在执行响应正文时,服务器端响应的数据本质就是1个字符串,使用1个字符串就不便于表示以上这些信息,例如:
"root12342513800138001root@163.com"
如果响应这样的字符串是极为不合理,甚至完全不可用的,所以,服务器端向客户端响应数据时,不能只是“包含值”就完事了,还必须将这些数据组织成某种特定的格式,以至于客户端收到数据后,可以从中解析出所需要使用的各个数据部分!
早期,推荐使用XML语法组织响应的数据,例如:
< user>
< username> root</ username>
< password> 1234</ password>
< age> 25</ age>
< phone> 13800138001</ phone>
< email> root@163.com</ email>
</ user>
当客户端接收到以上XML组织的数据之后,就可以结合XML解析技术,从中得到各属性值!
目前,比较推荐的是使用JSON格式来组织数据:
{
"username" : "root" ,
"password" : "1234" ,
"age" : 25 ,
"phone" : "13800138001" ,
"email" : "root@163.com"
}
使用JSON格式的数据,相比XML语句来说:
3. JSON格式
JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON的语法格式是:
使用一对大括号{}
框住的是JSON对象 ,整个JSON数据就是1个JSON对象; 在JSON对象 中可以配置若干个属性与值的对应关系,各项配置之间使用逗号,
分隔; 属性名与值之间使用冒号:
分隔; 属性的名称都是字符串类型的,需要使用一对引号""
框住; 如果属性的值是数值或布尔值,则直接写出字面值即可,无需添加任何符号,如果是字符串类型的,也使用一对引号""
框住; 属性的值还可以是数组类型的,也就是JSON数组 ,是使用一对中括号[]
框住,且各元素之间使用逗号,
分隔; 属性的值还可以是另一个JSON对象 。
{
"username" : "root" ,
"password" : "1234" ,
"age" : 25 ,
"phone" : "13800138001" ,
"email" : "root@163.com" ,
"skills" : [ "MySQL" , "Spring" , "SpringMVC" , "Mybatis" ] ,
"group" : {
"id" : 3 ,
"name" : "Administrators"
}
}
4. 服务器端向客户端响应JSON格式的数据
首先,在项目的pom.xml 文件中添加jackson-databind
依赖:
<!-- https:///artifact/com.fasterxml.jackson.core/jackson-databind -->
< dependency>
< groupId> com.fasterxml.jackson.core</ groupId>
< artifactId> jackson-databind</ artifactId>
< version> 2.10.4</ version>
</ dependency>
假设需要向客户端响应的是一个用户的数据,则先声明一个User
类,把要响应的各数据属性都声明在这个类中:
public class User {
private String username;
private String password;
private Integer age;
private String phone;
private String email;
}
在处理请求的方法中,使用以上创建的User
作为返回值类型,并返回匹配的对象:
// http://localhost:8080/ajax/user/info
@RequestMapping ( "info" )
@ResponseBody
public User info ( ) {
User user = new User ( ) ;
user. setUsername ( "root" ) ;
user. setPassword ( "1234" ) ;
user. setAge ( 25 ) ;
user. setPhone ( "13800138001" ) ;
user. setEmail ( "root@163.com" ) ;
return user;
}
注意:在SpringMVC的配置类之前,必须添加@EnableWebMvc
注解!
在控制器中,在处理请求的方法的声明之前,添加@ResponseBody
注解后,表示“响应正文”,处理请求的方法返回的对象就会响应给客户端,并不会被视为“视图名”或执行转发、重定向等操作。
SpringMVC在处理“响应正文”时,会使用到“转换器(Converter)”,转换器的作用就是对方法返回的对象进行处理,并处理响应时的响应头(Response Headers)中的相关信息。SpringMVC框架支持多种不同的转换器,并且,根据返回值类型的不同,将会自动的使用特定的转换器,例如,当返回值类型是String
时,SpringMVC框架会使用StringHttpMessageConverter
转换器,当添加了jackson
框架,且返回值的类型是SpringMVC默认不可识别的类型时,就会自动使用jackson
框架中的转换器,而jackson
框架中的转换器的工作模式主要有:
将返回的对象组织成JSON格式的数据; 设置响应头(Response Headers)中的Content-Type
的值为:application/json; charset=utf-8
所以,总的来说,如果需要在项目中响应JSON格式的数据,必须先添加jackson
框架的依赖,并且,在处理请求的方法中,返回SpringMVC默认并不识别的类型(只要是自定义的数据类型均可)的对象即可。
一般,在开发项目时,会专门创建一个数据类型,作为向客户端响应结果的通用数据类型(无论用户的请求是哪一种,都响应这种类型),例如:
public class JsonResult < T > {
// 操作状态,例如:1-成功,0-失败……
private Integer state;
// 操作失败的情况下,响应给客户端的提示信息,例如:“登录失败,用户名不存在”
private String message;
// 操作成功的情况下,需要响应给客户端的数据
private T data;
// Getters & Setters
}
5. jQuery - AJAX
Ajax即“Asynchronous Javascript And XML”(异步JavaScript 和XML),是指一种创建交互式网页应用的网页开发技术。Ajax=异步JavaScript和XML(标准通用标记语言的子集)。通过在后台与服务器进行少量数据交换,Ajax可以使用网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新(无刷新技术)。传统的网页(不使用Ajax)如果需要更新内容,必须重载整个网页页面。
首先,在项目的webapp 文件夹下创建注册页面,并在这个文件夹存放jQuery文件。
页面代码示例:
<! DOCTYPE html >
< html>
< head>
< meta charset = " UTF-8" >
< title> 用户注册</ title>
</ head>
< body>
< h1> 用户注册</ h1>
< form method = " post" >
< p> 用户名:< input id = " inp-username" name = " username" > </ p>
< p> 密码:< input name = " password" > </ p>
< p> 年龄:< input name = " age" > </ p>
< p> 手机号码:< input name = " phone" > </ p>
< p> 电子邮箱:< input name = " email" > </ p>
< p> < input type = " button" onclick = " reg()" value = " 注册" > </ p>
</ form>
< script type = " text/javascript" src = " jquery-3.4.1.min.js" > </ script>
< script type = " text/javascript" >
function reg ( ) {
// --------------------------
// 注意:需要在“用户名”的输入框中配置id
// --------------------------
// alert("准备提交注册……");
// $.ajax()函数:发出异步请求,获取响应结果
// $.ajax()函数的参数:JSON对象
// 注意:JSON对象各属性的名称区分大小写
// url:将请求提交到哪里去
// data:需要提交到服务器的请求参数
// type:请求类型
// dataType:服务器端响应的数据类型
// success:服务器端成功响应(HTTP响应码是200)时,会被回调的函数,函数的参数就是服务器响应的JSON对象
$. ajax ( {
"url" : "user/reg.do" ,
"data" : "username=" + $ ( "#inp-username" ) . val ( ) ,
"type" : "post" ,
"dataType" : "json" ,
"success" : function ( jsonData ) {
if ( jsonData. state == 1 ) {
alert ( "注册成功!" ) ;
} else {
alert ( jsonData. message)
}
}
} ) ;
}
</ script>
</ body>
</ html>
注意:服务器端配置DispatcherServlet
映射的路径请改为*.do
,且在控制器类中配置的请求路径也需要使用.do
作为后缀。