Day60.Ajax、Axios、Json格式转换、书城第五阶段: 结果模型、Ajax局部更新、购物车

Day60.Ajax、Axios、Json格式转换、书城第五阶段: 结果模型、Ajax局部更新、购物车,第1张

目录

一、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. Axios基本用法

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. 加入购物车

 待续...

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/944733.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存