全面学习AJAX入门与提高(含代码)

这一篇文章我将和大家一起回AJAX技术,内容共分为三部分供大家一起讨论学习,这也是对自己之前学习的总结。如果有不对的地方欢迎大家指正、讨论。

1.JSON的基本介绍、基于jQuery的AJAX访问…
2.异步操作、整合注册功能…

<1>.JSON的基本介绍、基于jQuery的AJAX访问…

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:将请求提交到哪里去,相当于中的action

  • 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>

<2>.异步操作、整合注册功能…

1. 整合整套注册流程

1.1. 处理持久层

复制此前项目的db.propertiesspring-dao.xml到当前项目中,修改必要的配置,例如持久层接口所在的包。

在创建src\main\resources下创建mappers文件夹,复制并得到新的UserMapper.xml文件。

检查User实体类是否与数据表保持一致:

public class User implements Serializable {

	private static final long serialVersionUID = 2905888894945816600L;

	private Integer id;
	private String username;
	private String password;
	private Integer age;
	private String phone;
	private String email;
	private Integer isDelete;
	private Integer department;

	// ... ...

设计注册时需要执行的SQL语句:

INSERT INTO t_user (
	username, password, 
	age, phone,
	email, is_delete,
	department
) VALUES (
	#{username}, #{password},
	#{age}, #{phone}, 
	#{email}, #{isDelete}, 
	#{department}
)

以上字段列表和值列表,每行(横排)都只写2个,便于检查;
注意:最后一个字段和值的后面没有逗号,避免复制粘贴了多余的符号

为了保证“用户名唯一”,还应该添加“根据用户名查询数据”的功能,对应的SQL语句是:

SELECT 
	id, password
FROM 
	t_user 
WHERE 
	username=#{username}

单从注册来看,查询的字段列表是无所谓的,只关心有没有匹配的数据即可,基于“根据用户名查询数据”功能还可以应用于“登录”,所以,查询字段中可以有密码,用于登录时判断密码,还可以有id,用于成功登录后存入Session。

所以,实现注册功能,至少需要执行2种SQL语句,那么,接口中也应该存在2个抽象方法!则创建cn.tedu.ajax.mapper.UserMapper接口,并添加抽象方法:

Integer insert(User user);

User findByUsername(String username);

然后,修改UserMapper.xml根节点的namespace属性,并配置以上2个抽象方法的映射!

1.2. 处理业务层

业务层是持久层的调用者,且,大多数情况下,被控制器层调用。

Controller ---> Service ---> Mapper

在实际应用中,不允许控制器层直接调用持久层。

首先,创建cn.tedu.ajax.service.UserService类,声明private UserMapper userMapper;持久层对象,以便于调用并实现功能,但是,仅声明是没有值的,所以,添加@Autowired注解!如果属性需要被自动装配,当前类本身也应该在Spring管理范围之内,所以,当前类需要添加Service注解,并在组件扫描范围之内:

@Service
public class UserService {

	@Autowired
	private UserMapper userMapper;

	// ... ...

需要修改web.xml中加载的Spring配置文件,改为spring-*.xml
以下是我的web.xml配置文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>AJAX</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
   <servlet>
  	<servlet-name>SpringMVC</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <!-- 这是框架的系统组件之一,不需要我们写 -->
  	<init-param>
  		<!-- 由于整个框架是基于Spring的,所以,需要加载Spring的配置文件 -->
  		<param-name>contextConfigLocation</param-name>    <!-- DispatcherServlet的父类的属性名称,作用是加载spring的配置文件(上下文配置文件) -->
  		<param-value>classpath:spring-*.xml</param-value>         <!-- 只要是在resource文件夹下面,文件前面都要加一个classpath -->
  		<!--效果就是DispatcherServlet一开始工作之后就直接加载spring-mvc.xml配置文件 -->
  		<!-- servlet只有当第一次接收请求的时候才进行初始化 -->
  		<!-- 当我们发出一个.do的请求,servlet就开始工作,他一工作就开始读spring的配置文件,进而导致spring就是执行组件扫描  然后将有注解的UserDao顺手new出来了 -->
  	</init-param>
  	<load-on-startup>1</load-on-startup>   <!-- 表示当Tomcat启动时就初始化这个Servlet,从而加载Spring的配置文件 -->
  </servlet>
  <servlet-mapping>
  	<servlet-name>SpringMVC</servlet-name>
  	<url-pattern>*.do</url-pattern>    <!-- 只负责处理以.do结尾的请求 -->
  </servlet-mapping>
  
 
  <filter>
  	<filter-name>CharacterEncodingFilter</filter-name>                                    <!-- 搞定所有请求参数里面的中文 -->
  	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>utf-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>CharacterEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>                             <!--任何请求都从这里过  -->
  </filter-mapping>
  
</web-app>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值