1. 响应方式
在Java EE中,常见的响应方式有:转发和重定向。
无论是转发,还是重定向,都是由服务器端完成最终页面的显示,具体的表现为:用户提交请求后,页面完全由服务器端来完成!并且,伴随着页面的“刷新”!
例如:当用户尝试登录时,假设用户名错误,只能转发到某个页面(可能是错误提示页面),或重定向到某个页面,无论是哪种操作,用户在浏览器中看到的都不会再是原有的页面了!
使用这种做法,主要问题在于:(1)用户体验非常差;(2)服务器端压力较大,用户的请求次数也可能较多!(3)不适用于多种不同的客户端,例如PC端的浏览器、Android APP、iOS APP……
其实,服务器端并不一定需要把页面都处理掉,更多的应该是告之客户端此次操作的结果,例如客户端尝试登录时,服务器端应该给出“登录成功”或“登录失败!用户名或密码错误!”此类的结果即可,至于界面如何处理,可以交给客户端程序(例如Javascript)去进行处理!
如果需要响应的方式不是转发或重定向,而是直接响应一串字符,只需要在控制器处理请求的方式上添加@ResponseBody
注解即可!
使用该注解之前,应该在Spring的配置文件中添加
<mvc:annotation-driven />
注解驱动。
例如:
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/login.do")
@ResponseBody
public String handleLogin() {
return "LOGIN ERR.";
}
}
以上
@GetMapping
等效于@RequestMapping(method=RequestMethod.GET)
,使用4.3或以上版本的Spring框架时可用。
使用@ResponseBody可以向客户端响应正文,而不是某个页面!
2. JSON
以用户登录为例,可能存在:(1)成功;(2)用户名错误;(3)密码错误。即:同一次请求得到的结果可能是以上3种当中的某1种,客户获取到响应内容后,必须能够作出区分,然后执行下一步的任务,例如:成功,则跳转到某个页面,错误,则提示信息。当客户端收到数据后,如果数据中既包含操作结果的代码,又包含相关提示信息,则是比较好的处理方案,例如:
1-登录成功!
2-登录失败!尝试登录的用户名不存在!
3-登录失败!密码错误!
以上组织数据的方式并不严谨,为了更好的组织数据,可以使用XML语法:
<data>
<state>1</state>
<message>登录成功!</message>
</data>
使用XML组织数据可以很好的约定数据的格式,保证能够正确的获取到所需的数据内容!但是,这样的语法格式比较笨重,解析相对麻烦,目前,比较推荐的是使用JSON格式来组织数据:
{
"state":1,
"message":"登录成功!"
}
JSON格式不仅简单,而且,在Javascript中,是默认直接识别并解析的,例如:
var data = { "state":1, "message":"登录成功!" };
alert(data.message); // 使用警告框显示message
JSON的基本格式
JSON数据的基本格式是:使用大括号框住所有内容,内部可以有多个属性与值,属性与值使用冒号分隔,各属性及值的配置之间使用逗号分隔,如果值是字符串型的,需要使用单引号或双引号框住,如果值是数值型或布尔型则不需要使用引号。
练习:使用JSON表达某个用户数据,姓名为张三,来自北京,年龄25。
var user = { "name":"张三", "from":"北京", "age":25 };
alert(user.name);
属性的值也可以是另一个对象
每个属性的值,可以是直接表示出来的基本值,也可以是另一个对象,对象的表示方式与整个JSON的表示方式是一样的。
例如:用户数据中包括“部门”,而部门信息有编号与名称。
var user = { "name":"张三", "department":{"id":"9527", "name":"RD"} };
alert(user.department.name);
属性的值还可以是数组
在JSON中,和其它语言一样,使用[]
表示数组。
例如:某用户的个人技能包含:JAVA / HTML / CSS / JS / MYSQL
var user = { "name": "张三", "skill": ["JAVA", "HTML", "CSS", "JS", "MYSQL"] }
alert(user.skill[2]);
for (var i = 0; i < user.skill.length; i++) {
alert(user.skill[i]);
}
属性的值的组合应用
属性的值可以是基本值(数值、布尔值、字符串),也可以是某个对象,或是某个数组,甚至,当值是某个对象时,对象中还可以再包含对象或数组,当然,数组的成员也可以是对象,基于这种特性,JSON可以组织出任何类型的数据!
将字符串转换为JSON对象
在Javascript中,通过JSON.parse(str)
就可以将字符串转换为JSON对象,当然,字符串本身必须是符合JSON数据格式的!
var jsonString = '{ "name":"Tom", "age": 25 }';
var json = JSON.parse(jsonString);
小结
掌握JSON的数据格式,及数据的使用方式,掌握将字符串转换为JSON对象。
3. 服务器向客户端响应JSON格式的字符串
添加依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.7</version>
</dependency>
当处理请求的方法添加@ResponseBody
后,处理请求的方法的返回值将作为响应正文,响应到客户端,如果返回值类型是SpringMVC默认识别的类型,将直接处理,例如String,如果返回值类型是SpringMVC默认不识别的类型,将自动调用Jackson,将返回值组织成JSON数据格式!
除此以外,Jackson还会设置响应头为:application/json, charset=utf-8
,也就解决了中文乱码的问题!
通常会在服务器端创建专门用于确定响应结果的数据类型,例如:
public class ResponseResult {
private Integer state;
private String message;
// SET/GET, Serializable
}
然后,每次向客户端响应时,都使用ResponseResult
作为方法的返回值!
4. AJAX
AJAX是通过Javascript发出异步请求,并处理响应结果的做法!
原生的AJAX使用比较麻烦,还可能存在兼容性的问题,所以,推荐使用jQuery框架中封装好的函数来实现AJAX访问。
由jQuery提供的AJAX请求函数是$.ajax()
,参数是1个JSON对象,在该JSON对象中,通常,至少需要设置5个属性:
url
:将请求提交到哪里去,相当于data
:请求参数,参数格式为xx=xx&xx=xx&xx=xx
type
:请求类型,例如"GET"
或"POST"
等dataType
:服务器端响应的数据类型,取值可以是"text"
、"xml"
、"json"
success
:当服务器正确响应时(响应码=200)如何处理,取值为函数,由该函数对结果进行处理,可以在函数中添加1个参数,该参数就是服务器响应的内容,如果前序将dataType
设置为"json"
,则参数就是直接是JSON对象,无需实现JSON.parse()
转换!
使用例如:
function login() {
var u = $("#username").val();
var p = $("#password").val();
$.ajax({
"url": "user/login.do",
"data": "username=" + u + "&password=" + p,
"type": "POST",
"dataType": "json",
"success": function(json) {
if (json.state == 1) {
// 登录成功
location.href = "index.html"
} else if (json.state == 2) {
// 用户名错误
alert(json.message);
} else if (json.state == 3) {
// 密码错误
alert(json.message);
}
}
});
}
</script>