Ajax

Ajax


Ajax 是几项技术的综合运用,js、XHTML、CSS、DOM、XML、XMLHttpRequest
Ajax 核心在 JS 中调用 XMLHttpRequest 类,这个类可以与 Web 服务器使用 HTTP 协议交互,程序不通过浏览器发送请求,使用 JS 对象发送请求和接受响应。

XMLHttpRequest 对象就是 Ajax 对象,可以实现局部更新。

Ajax 缺陷:

  1. 使用 JS 和 Ajax 引擎,IE 5.0及以上、Mozilla1.0、NetScape7 以上才支持,Mozilla 支持 Ajax,但是提供 XMLHttpRequest 的方式不一样,所以使用 Ajax,必须针对其进行兼容。
  2. 网页后退功能失效,这个很容易理解。还需要在明显的位置提醒客户-数据已更新
  3. 对流媒体支持没有 Flash、Java Applet好。H5 已经解决了流媒体问题。
  4. Ajax 不支持跨域访问。

一个简单的 Ajax 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
window.onload = function () {
document.querySelector('#getTime').onclick = function (v1) {
// 发送请求
// 创建 XMLHttpRequest 对象
var ajax = new XMLHttpRequest();
// 参数 请求方式 请求路径,是否异步
ajax.open('get', '/getTime1?' + new Date(), true);
// 设置监听响应的函数
ajax.onreadystatechange = function () {
// 获取响应数据 监听 readyState 的值是否变化
// 每一次变化都会调用 function() 函数
// 0 对象没完成初始化
// 1 对象开始请求
// 2 对象请求发送完成
// 3 对象开始读取服务器响应
// 4 对象读取服务器响应结束
var state = ajax.readyState;
var status = ajax.status;
if (state == 4 && status == 200) { // 服务器成功响应
var data = ajax.responseText;
var jsonObj = JSON.parse(data);
}
}
// 发送请求
ajax.send();
}
}
</script>

IE

1
2
3
4
5
6
7
8
9
function createAjax() {
var ajax = null;
try {
ajax = new XMLHttpRequest();
} catch (e) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
return ajax;
}
1
2
3
4
5
6
7
8
9
@RequestMapping("/getTime1")
public void getTime1(Model model, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
JsonResult jr = new JsonResult();
jr.setMsg(new Date().toLocaleString());
writer.write(JSON.toJSONString(jr));
writer.flush();
}

JSON 库


Jackson,把 Java 对象转成 jsonStr,
Fastjson,阿里出的,号称 Java 领域转换 JSON 最快的插件,中文文档齐全。

Java 对象 <———> JSON 字符串

Jackson

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void testJson() throws Exception {
User user = new User();
user.setName("李朝");
user.setId(1L);
user.setAge(18);
user.setPassword("123456");
System.out.print(new ObjectMapper().writeValueAsString(user));
}
// {"name":"李朝","id":1,"age":18,"password":"123456"}

public void testString2Json() throws Exception {
String json = "{\"name\":\"李朝\",\"id\":1,\"age\":18,\"password\":\"123456\"}";
System.out.print(new ObjectMapper().readValue(json, User.class));
}

Ali:fastjson

1
2
3
4
5
6
7
8
9
10
11
12
public void testAliJosn2String() {
User user = new User();
user.setName("李朝");
user.setId(1L);
user.setAge(18);
user.setPassword("123456");
String s = JSON.toJSONString(user);
System.out.print(s);

String json = "{\"name\":\"李朝\",\"id\":1,\"age\":18,\"password\":\"123456\"}";
System.out.print(JSON.parseObject(json, User.class));
}

Json 数据处理


Jackson

jackson 是一个 Java 开源的 JSON 工具库,性能优秀。可以轻松将 Java 对象转换成 json 对象和 xml 文档,也可以将 json、xml 转换成 Java 对象。jackson-corejackson-databindjackson-annotations

SpringMVC 提供了处理 JSON 格式请求和响应的 HttpMessageConverter : MappingJackson2HttpMessageConverter,利用 Jackson 开源库处理 JSON 格式的请求和响应信息。SpringMVC 默认支持 jackson 处理 JSON 数据。

注解:

注解名 作用
RequestBody 处理请求,用于读取 HTTP 请求的内容(JSON 格式字符串),转换为 Java 对象。
ResponseBody 处理响应,用于将 Controller 中方法返回的对象转换为 JSON 字符串
RestController 复合组件,指出 RESTful

@RestController = @Controller + @ResponseBody

如果 HTTP 请求类型和数据格式是 JSON(contentType=application/json;charset=utf-8),此时必须使用 @RequestBody 贴在 Controller 方法参数上。如果是 key-value 就不需要

application/x-www-form-urlencoded 传统的方式处理方便,key-value。
application/json,application/xml 格式的数据,必须使用 RequestBody 来处理

单个对象转换为 JSON

1
2
3
4
5
6
7
8
9
// @ResponseBody 的作用是告诉 SpringMVC 响应的数据是 Json 格式
// 即 application/json;charset=utf-8
@RequestMapping("/getTime2")
@ResponseBody
public JsonResult getTime2() {
JsonResult jr = new JsonResult();
jr.setMsg(new Date().toLocaleString());
return jr;
}

多个对象转换为 JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RequestMapping("/getTime3")
@ResponseBody
public List<User> getTime3() {
User user1 = new User();
user1.setName("李朝2");
user1.setId(2L);
user1.setAge(18);
user1.setPassword("123456");
User user2 = new User();
user2.setName("李朝2");
user2.setId(2L);
user2.setAge(18);
user2.setPassword("123456");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
return users;
}

字符串转换为 JSON

1
2
3
4
5
@RequestMapping(value = "/test3", produces="application/json; charset=UTF-8")
@ResponseBody
public List<User> test7() {
return "你好,JSON";
}

Map 转换为 JSON

1
2
3
4
5
6
7
8
9
@RequestMapping("/test4")
@ResponseBody
public List<User> test7() {
Map<String, Object> map = new HashMap<>();
map.put("id", "123");
map.put("name", "will");
map.put("age", 17);
return map;
}

响应 Json 格式 Date 类型数据处理

问题:后台往前台响应数据,若返回数据存在 Date 类型字段,SpringMVC 自动把 Date 类型数据解析成毫秒值

方式一 在需要解析的字段上添加注解

1
2
3
4
public class User {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date hiredate;
}

方式二 在 mvc.xml 中配置全局的解析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

Ajax 实现登录


使用 Ajax 完成员工登录,比表单登录体验更好,可以记录用户的账号密码

login.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function randomCodeResult() {
/**
* 修改 src 的数据,由于浏览器发现地址跟之前地址一样,所以直接从浏览器缓存中去取数据,
* 而不会重新发送请求,
* 解决:欺骗浏览器,给一个变化的地址,实际上是同一个地址,依然访问 randomCodeServlet
* 秒变化太慢,转为毫秒 getTime()
*/
$('#randomCode').attr('src', '/login/randomCode?' + new Date().getTime())
}

/**
* username=admin&password=123456&randomCode=9f8c3
* $('#loginForm').serialize() 表单标签的 serialize() 方法作用:
* 将提交表单时的请求体中的数据序列化,将表单变成一个 js 对象
*/
$('#btn_submit').click(function () {
$.post('/login/doLogin', $('#loginForm').serialize(), function (data) {
if (data.success) {
location.href = '/dept/list'
} else {
$('#errorText').text(data.message)
randomCodeResult()
}
})
})


<div class="form-group">
<button type="button" class="btn btn-lg btn-primary btn-block"
id="btn_submit">登录</button>
</div>

LoginController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@RequestMapping("/doLogin")
@ResponseBody
public JsonResult login(String username,
String password,
String randomCode,
Boolean rememberMe) throws Exception {
HttpServletResponse resp = SessionUtil.getResponse();
// 记住用户名,存入 cookie
if (rememberMe) {
CookieUtil.addCookie("username", username);
} else {
CookieUtil.deleteCookie("username");
}

// 校验验证码
if (StringUtil.isEmpty(randomCode)) {
return new JsonResult("验证码为空", false);
}
if (!randomCode.equals(SessionUtil.getSessionAttribute("randomCode"))) {
return new JsonResult("验证码错误", false);
}
// 验证码通过,删除验证码
SessionUtil.removeSessionAttribute("randomCode");

try {
Employee employee = employeeService.getAccessLogin(username, password);
SessionUtil.setSessionAttribute(employee, Employee.class);
return new JsonResult("登录成功", true);
} catch (Exception e) {
return new JsonResult(e.getMessage(), false);
}
}
文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2019/03/31/Ajax/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论