目录
一、Ajax概述
二、Axios框架 (封装Ajax)
1. Axios基本用法
2. 客户端发送 json 类型数据(data)
3. 服务端返回 json 类型数据 (箭头函数 =>)
a. 接收json对象
b. 接收Json数组
4. gson、jackson 工具类 (json数据与java对象的转换)
封装 JSONUtils
三、书城项目第五阶段
1. 封装CommonResult (ajax结果模型)
2. 注册页面:用户名唯一性检查优化 — Ajax局部更新
3. 加入购物车
一、Ajax概述
Ajax:(Asynchronous Javascript And XML)(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax 是一种浏览器通过 js 异步发起请求,局部更新页面的技术,Ajax 请求的局部更新,不刷新浏览器窗口,不做页面跳转,不会舍弃原来页面的内容。
前后端分离:前端后端分开服务器部署,数据传递采用json格式传递。在我们这里我们先理解为彻底舍弃服务器端渲染,数据全部通过Ajax方式以JSON格式来传递
JSON (JavaScript Object Notation, JS 对象简谱),一种用于跨平台传输的数据格式。Day52.JavaScript、对象|数组、JSON、DOM *** 作、正则RegExp_焰火青年·的博客-CSDN博客
服务器渲染:
Ajax渲染:
二、Axios框架 (封装Ajax)同步:多个 *** 作按顺序执行,前面的 *** 作没有完成,后面的 *** 作就必须等待。所以同步 *** 作通常是串行的。
异步:多个 *** 作相继开始并发执行,在各自在自己独立的进程或线程中完成,所以互不干扰,谁也不用等谁。
使用原生的JavaScript程序执行Ajax极其繁琐,所以一定要使用框架来完成。而Axios就是目前最流行的前端Ajax框架。(大自然的搬运工,对Ajax进行封装)
Axios官网:axios中文网|axios API 中文文档 | axios
axios程序接收到的响应对象结构:
属性名 | 作用 |
---|---|
config | 调用axios(config对象)方法时传入的JSON对象 |
data | 服务器端返回的响应体数据 |
headers | 响应消息头 |
request | 原生JavaScript执行Ajax *** 作时使用的XMLHttpRequest |
status | 响应状态码 |
statusText | 响应状态码的说明文本 |
1.在前端页面引入开发环境
2.发送普通请求参数
html
var vue = new Vue({
"el":"#box",
"data":{
"msg":"",
},
"methods":{
sendAjax(){
//使用axios发送异步请求
axios({
"method":"post", //请求方式(不写默认get)
"url":"demo01", //请求的地址
"params":{ //发送的请求参数
"userName":"tom",
"userPwd":"123456"
} //response是服务器端的响应数据,是json类型的
}).then(function (response) { //请求成功会执行的函数
//alert("Ajax请求成功");
console.log(response);
console.log(response.data); //响应体
console.log(response.headers); //成功的响应头
console.log(response.status); //成功的状态码
vue.msg = response.data; //将响应的消息渲染到页面上
}).catch(error => { //可以使用箭头函数简化回调函数
//alert("Ajax请求失败")
console.log(error); //获取失败信息
console.log(error.response); //失败的响应信息
console.log(error.response.data); //失败的数据(其实是一个页面)
console.log(error.response.headers);//失败的响应头
console.log(error.response.status); //失败的状态码
})
}
}
})
2. 客户端发送 json 类型数据(data)
在使用Axios传递数据时,无论是get还是post,数据都在地址栏后拼接。
如何解决安全问题?
使用 json类型传输数据。(data 传递json数据,param 传递普通参数)。
注意:客户端发送json类型数据,必须采用post请求传递 (get请求只能提交字符串数据)。
服务端解析:
服务端不能采用 getParameterMap() 方式获取 Json 数据;
应采用流的方式 BufferdReader br = req.getReader() 获取 json 数据。
@WebServlet("/ajax3") //采用注解的方式地址匹配
public class Ajax03Servlet extends HttpServlet {
//service,内部会判断请求方式
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("------ Ajax03Servlet ------");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//Parameter()无法接收Json数据
/*Map map = req.getParameterMap();
map.forEach(System.out::printf);*/
//1.通过获取io流,接收Json数据
BufferedReader br = req.getReader();
//2.读取数据,拼接到一起
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = br.readLine())!=null){
sb.append(line);
}
System.out.println(sb);
//3.通过工具类Gson,将json格式字符串转换为 Java对象
Gson gson = new Gson();
User user = gson.fromJson(sb.toString(), User.class);
System.out.println(user);
}
}
3. 服务端返回 json 类型数据 (箭头函数 =>)
a. 接收json对象
服务端发送:
@WebServlet("/ajax4")
public class Ajax04Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("------ Ajax04Servlet ------");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//1.调用gson工具将对象转换为json字符串
User zs = new User("张三", "123456");
Gson gson = new Gson();
String json = gson.toJson(zs);
//2.获取打印流响应到客户端
PrintWriter writer = resp.getWriter();
writer.println(json);
}
}
客户端接收:
可以使用箭头函数 => 简化回调函数,箭头函数内可以用 this 表示 Vue 对象 (因为特性,不存在函数) (类似Lamda表达式)。
姓名
密码
{{user.username}}
{{user.password}}
b. 接收Json数组
客户端接收:
姓名
密码
{{u.username}}
{{u.password}}
服务端发送:
@WebServlet("/ajax5")
public class Ajax05Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("------ Ajax05Servlet ------");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//封装user集合
User us1 = new User("张三", "123456");
User us2 = new User("李四", "123456");
User us3 = new User("王五", "123456");
User us4 = new User("赵六", "123456");
ArrayList userList = new ArrayList<>();
Collections.addAll(userList,us1,us2,us3,us4);
//1.调用gson工具将user集合转换为json字符串
Gson gson = new Gson();
String listJson = gson.toJson(userList);
//2.获取打印流打印到客户端
PrintWriter writer = resp.getWriter();
writer.println(listJson);
}
}
4. gson、jackson 工具类 (json数据与java对象的转换)
Gson 是Google研发的一款非常优秀的JSON数据解析和生成工具,它可以帮助我们将数据在JSON字符串和Java对象之间互相转换。 new Gson()
jackson 是Java中比较常用的JSON解析的工具包,SpringMVC和SpringBoot中默认支持的就是jackson。 new ObjectMapper();
jackson:
public class JackSonTest {
//jackSon
ObjectMapper objectMapper = new ObjectMapper();
//1.Java对象 转为 json格式字符串
@Test
public void test01() throws JsonProcessingException {
User user = new User("李白", "123456");
//转换
String json = objectMapper.writeValueAsString(user);
System.out.println("json = " + json);//{"username":"李白","password":"123456"}
}
//2.json格式字符串 转为 Java对象
@Test
public void test02() throws IOException {
String json = "{\"username\":\"李白\",\"password\":\"123456\"}";
//转换
User user = objectMapper.readValue(json, User.class);
System.out.println("user = " + user);//user = User{username='李白', password='123456'}
}
//3.Java集合 转为 Json格式数组字符串
@Test
public void test03() throws IOException {
User user1 = new User("李白", "123456");
User user2 = new User("杜甫", "123456");
List list = new ArrayList<>();
list.add(user2);
list.add(user1);
//转换
String json = objectMapper.writeValueAsString(list);
System.out.println("json = " + json);//[{"username":"杜甫","password":"123456"},{"username":"李白","password":"123456"}]
}
//4. Json格式数组字符串 转为 Java集合
@Test
public void test04() throws IOException {
String json ="[{\"username\":\"杜甫\",\"password\":\"123456\"},{\"username\":\"李白\",\"password\":\"123456\"}]";
TypeReference> typeReference = new TypeReference>() {};
//转换
List list = objectMapper.readValue(json, typeReference);
list.forEach(System.out::println);
}
Gson:
public class GsonTest {
//gson工具类 Java对象与json数据字符串转换
Gson gson = new Gson();
//1.Java对象 转为 json格式字符串
@Test
public void test01(){
User user = new User("李白", "杜甫");
//转换
String json = gson.toJson(user);
System.out.println("json = " + json); //{"username":"李白","password":"杜甫"}
}
@Test
//2.json格式字符串 转为 Java对象
public void test02(){
String json = "{\"username\":\"李白\",\"password\":\"杜甫\"}";
//转换
User user = gson.fromJson(json, User.class);
System.out.println("user = " + user);//User{username='李白', password='杜甫'}
}
//3, Java集合 转为 Json格式数组字符串
@Test
public void test03(){
User user1 = new User("李白", "杜甫");
User user2 = new User("李白", "杜甫");
ArrayList list = new ArrayList<>();
Collections.addAll(list, user1,user2);
//转换
String json = gson.toJson(list);
System.out.println("json = " + json);//[{"username":"李白","password":"杜甫"},{"username":"李白","password":"杜甫"}]
}
//4. Json格式数组字符串 转为 Java集合
@Test
public void test04(){
String json = "[{\"username\":\"李白\",\"password\":\"123456\"},{\"username\":\"杜甫\",\"password\":\"123456\"}]";
//生成的对象类型
Type type = new TypeToken>() {}.getType();
List o = gson.fromJson(json, type);
o.forEach(System.out::println);
}
}
封装 JSONUtils
将重复内容进行封装:JSON工具类,用于获取json格式的请求参数 以及 向客户端响应json字符串。
public class JSONUtils {
/**
* 通用的将 json数据从请求中获取并封装为对象
* @param req 请求
* @param clazz 转为对象的Class类型
* @return
*/
//将json数据从请求中获取并封装为对象
public static T parseJsonStr(HttpServletRequest req,Class clazz){
//java8新特性 自动关闭流 获取输入流
try (BufferedReader reader = req.getReader()){
//准备拼接字符串
StringBuilder sbl = new StringBuilder();
String line = "";
while ((line = reader.readLine())!=null){
sbl.append(line);
}
//jackson工具类 将Json数据字符串转换为Java对象
ObjectMapper mapper = new ObjectMapper();
T t = mapper.readValue(sbl.toString(), clazz);
return t;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
/**
* 将对象转为json写出的方法
* @param response 响应对象
* @param obj 要写出的对象
*/
public static void writeJson(HttpServletResponse response, Object obj){
try {
//jackson工具类 将Java对象转换为Json数据字符串
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(obj);
response.getWriter().println(json);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}
三、书城项目第五阶段
由于后期有很多配置文件,建立资源文件夹方便管理,等同于放在src目录下。
1. 封装CommonResult (ajax结果模型)在整个项目中,凡是涉及到给Ajax请求返回响应,我们都封装到CommonResult类型中。
属性名 | 含义 |
---|---|
flag | 服务器端处理请求的结果,取值为true或者false |
message | 服务器端处理请求失败之后,要响应给客户端的数据 |
resultData | 服务器端处理请求成功之后,需要响应给客户端的数据 |
作为整个团队开发过程中,前后端交互时使用的统一的数据格式,有利于团队成员之间的协助,提高开发效率。
代码实现:
//ajax 结果模型
public class CommonResult {
private boolean flag; //请求(业务)成功还是失败
private Object resultData; //请求成功时响应的数据 (主要针对查询)
private String massage; //失败时响应的错误信息
//业务成功
public static CommonResult ok(){
return new CommonResult().setFlag(true);
}
//业务成功,返回数据
public static CommonResult ok(Object data){
return new CommonResult().setFlag(true).setResultData(data);
}
//业务失败
public static CommonResult error(){
return new CommonResult().setFlag(false);
}
//业务失败,返回失败原因
public static CommonResult error(String message){
return new CommonResult().setFlag(false).setMassage(message);
}
由于在setFlag() 等 *** 作中返回值为null,并不会返回CommonResult对象,所以在生成get()、set() 方法时我们选择:
public boolean isFlag() {
return flag;
}
public CommonResult setFlag(boolean flag) {
this.flag = flag;
return this; //会返回当前this对象
}
public Object getResultData() {
return resultData;
}
public CommonResult setResultData(Object resultData) {
this.resultData = resultData;
return this;
}
2. 注册页面:用户名唯一性检查优化 — Ajax局部更新
在用户输入用户名之后,立即检查这个用户名是否可用(触发失去焦点事件blur)。
代码:
html(部分)
UserServlet (部分) 表述层
public class UserServlet extends ModelBaseServlet {
UserService userService = new UserServiceImpl(); //业务层 service
//注册用户名异步校验(axios)
private void checkUserName(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("----- checkUserName -----");
//ajax 结果模型
CommonResult commonResult = null;
try {
//1.获取浏览器传递的用户名
String name = request.getParameter("username");
//2.调用业务层方法 判断用户名是否可以用
userService.findByUserName(name);
//3.用户名可用返回业务成功模型
commonResult = CommonResult.ok();
} catch (Exception e) {
e.printStackTrace();
//4.用户名不可用返回业务失败模型,传入失败信息,局部更新
commonResult = CommonResult.error(e.getMessage());
}
//5.调用工具类将结果模型对象转换为Json格式,对ajax进行信息反馈
JSONUtils.writeJson(response,commonResult);
}
}
UserService (部分) 业务逻辑层
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl(); //数据访问层 Dao
//异步校验用户名
@Override
public void findByUserName(String name) {
//1.查询用户名是否存在
User user = userDao.selectByName(name);
if(user!=null){
throw new RuntimeException("用户名["+name+"]已经存在");
}
}
}
3. 加入购物车
待续...
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)