Ajax

发送请求的一些方式

1.输入浏览器回车

2.html>head>script/link

​ img标签

3.a标签form表单标签等

用户手动控制提交产生;

4.通过js代码产生请求;

Ajax的原理,通过js技术向后端发送请求,通过响应来进行判断是否 进行页面跳转,是否生成数据展示到dom树中

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

1. 同步请求异步请求

在这里插入图片描述

2. Ajax实现方式

  • 假如按钮触发了一个名为getmesssgae的js函数

  • script部分

    <script>
        function getmessage(){
            // 1.实例化一个xmlHttpRequest对象
            var req  = new XMLHttpRequest;

            // 2.设置xmlHttpRequest回调函数

            // 3.设置发送请求的方式和请求资源路径
            req.open("GET","/hello?username=zhangsan");

            // 4.发送请求
            req.send();
        }
    </script>

第二部分的代码有点多,很难写

  • 往页面上做出响应的代码*
req.onreadystatechange = function(){
    if(req.readyState==4&&req.status==200);
    // alert("后端响应了")
    console.log(req.responseText)

    //将信息放到指定的位置
    var inputEle = document.getElementById("message")
    inputEle.value = req.responseText
}
  • 进行页面跳转*
window.location.href="http://www.atguigu.com"

3. 日程管理第四期

注册提交前进行校验用户名是否占用功能;

也就是前端checkUsername函数 校验完格式后,继续进行是否占用校验 并修改 usernameMsg信息

  • 创建XMLHTTPRequest对象
var req = new XMLHTTPRequest()
  • 设置回调函数
req.openstatechange = function(){

​	if(req.status ==200 && req.readyState = 4){

​		usernameMsg.innerText = req.responseText;

​	}

}
  • 设置请求方式和 资源路径映射
req.open(“GET”,”user/checkUserUsed?username=”+username)
  • 发送请求
req.send()

使用Ajax技术在不跳转的情况下响应到前端页面

//控制层新增函数checkUsernameUsed
    /**
     * 注册时接收要注册的username,目的是检测其是否 合法是否被占用
     * @param req
     * @param resp
     */
    protected void  checkUsernameUsed(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//        接收用户名
        String username = req.getParameter("username");
//        服务层进行查询该用户名是否存在用户
        int username1 = userService.findUsername(new SysUser(null, username, "******"));

//        如果有响应已占有
//        如果没有响应可用
        /**
         * 0表示没查出来 username
         * 1表示 占用
         */
        String info = null;
        if (username1==0){
            info="可用";
        }else if (username1==1){
            info="不可用";
        }
        resp.getWriter().write(info);

    }

注意:本次开发传参仅传入username,但是会设置一个密码,这个密码必须不为空,因为后续代码逻辑会送入MD5校验,为空报错;

密码直接设置为

******

前端代码 会进行校验格式;用户无法起此代码

4. 响应JSON串

JSON串解决问题如下

  • 响应乱码问题

  • 响应信息格式问题

​ 后端响应的信息应该是JSON格式,前后端共同尊守;

​ 如果响应可用不可用;前后端需要保持一致,就很麻烦,后端代码进行修改了,那么前端也需要跟着改;

​ 统一的格式是前后端商量好的

  • 校验不通过无法阻止表单提交

4.1 响应JSON串格式的一般格式

{

​ 响应行 状态码200,404…

​ 响应头

​ 响应体 { code:”1成功/0失败”, message:业务状态码,“data”:{} }

}

响应报文如上图所示;
所谓的JSON串格式写的是 响应体中的东西
响应行必须触发,把东西响应回来,因此响应行状态码必须是200
响应体中的码是前后端提前商量好的;
code		业务状态码
message		业务状态码的补充说明
data		本次响应数据			具体内容根据业务相关
  • 具体流程

我们使用jacksonlib包 转化json格式,减少后端程序员拼写字符串的难度

后端程序员撰写响应体的 class ,后续使用,直接new对象,将我们业务数据封装进去即可

public class Result<T> {
    private Integer code;
    private String message;
    private T data;
}
  • 后续会将Result对象使用jackon转化为json串

  • 关于业务码code使用枚举形式进行定义,用的时候直接拿来用即可

public enum ResultCodeEnum {
    /**
     * 此处创建枚举对象,自动的调用下面的构造器;
     */
    SUCCESS(200,"success"),
    USER_ERROR(501,"usernameError"),
    PASSWORD_ERROR(503,"passwordError"),
    NOT_LOGIN(504,"notLogin"),
    USER_USED(505,"usernameUsed");

    private Integer code;
    private String message;

    ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}
  • 此处创建枚举对象,自动的调用下面的构造器;
  • 枚举常量通常使用大写字母表示,默认常量 不可修改;
  • 枚举本身是一个类,具有类的所有成分,每一个枚举常量都是枚举类的实例,因此可以看出上面写法;
  • 创建Result类 未来后端传递数据使用Result对象即可;
package schedule.common;

/**
 * 全局统一响应的JSON格式处理类
 *
 */
public class Result<T> {
    // 返回码
    private Integer code;
    // 返回消息
    private String message;
    // 返回数据
    private T data;

    public Result(){}
    // 返回数据
    protected static <T> Result<T> build(T data) {
        Result<T> result = new Result<T>();
        if (data != null)
            result.setData(data);
        return result;
    }


    /**
     * 对上一个build的重载,除了设置data以外,还要进行code,message的设置;
     * @param body
     * @param code
     * @param message
     * @return
     * @param <T>
     */
    public static <T> Result<T> build(T body, Integer code, String message) {
        Result<T> result = build(body);
        result.setCode(code);
        result.setMessage(message);
        return result;
    }

    public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
        Result<T> result = build(body);
        result.setCode(resultCodeEnum.getCode());
        result.setMessage(resultCodeEnum.getMessage());
        return result;
    }
    /**
     * 操作成功,默认是将数据传进去,设置成功的状态码;
     * @param data  baseCategory1List
     * @param <T>
     * @return
     */
    public static<T> Result<T> ok(T data){
        Result<T> result = build(data);
        return build(data, ResultCodeEnum.SUCCESS);
    }
    public Result<T> message(String msg){
        this.setMessage(msg);
        return this;
    }
    public Result<T> code(Integer code){
        this.setCode(code);
        return this;
    }

//    ------------------------------下面是常规的GetSet方法------------------------------

    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
} 
  • 因此在后端传递的时候,传递码可以如下表示
        Result result = Result.ok();
        String info = null;
        if (username1==0){
            result = result.ok(null);
        }else if (username1==1){
            result = result.build(null, ResultCodeEnum.USER_USED);
        }
  • 接下来将result转化为JSON串
  • 导入jar包

在这里插入图片描述

  • 导入jar包后使用ObjectMapper进行 对象–>JSON串转化
//        接下来将result转化为json串响应给客户端
        ObjectMapper objectMapper = new ObjectMapper();
        String info = objectMapper.writeValueAsString(result);
        resp.getWriter().write(info);

对象转JSON串步骤

​ --导jackson包;

​ --实例化ObjectMapper对象

​ --直接使用writeValueAsString即可

  • 最终还需要告诉客户端响应json串格式
 resp.setContentType("application/json;charset=UTF-8");
  • 响应结果如下所示

在这里插入图片描述

  1. 创建WebJson工具类
public class WebJson {
    private static ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
    }
    public static void  writeJson(HttpServletResponse resp, Result result){
        resp.setContentType("application/json;charset=UTF-8");
        try {
            String s = objectMapper.writeValueAsString(result);
            resp.getWriter().write(s);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

因此所有代码一句话即可

在这里插入图片描述

writeJson是一个静态方法,因此这个工具包,调的不是类,是静态方法;可以直接类名.方法进行调用

Appendix

//回调函数不会阻止表单提交;未来使用vue axios 结合promise处理;

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部