案例开发 - 日程管理 - 第四期

在第四期内容中,我们主要解决的是用 ajax 技术,实现用户在注册页面时候,输出要注册的用户名,当输入完用户名,点击空白处的时候,前端发送请求,检测用户名是否重复。

处理

在 regist.html 处,要进行如下处理:

在 controller 包下的 SysUserController 下应该新增加一个 checkUsernameUsed 方法:

增加这两段代码后,就可以实现我们预期的功能,但海撒存在一些问题:

  1. 响应乱码问题,浏览器打开开发者模式,响应的"可用"中,显示的是乱码

2 响应格式不规范,处理方式不规范

后端响应回来的信息,应该有一个统一的格式,前后端共同遵守

==》

响应一个 JSON 串

{

"code":"100/200/300/400...":业务状态码 本次请求业务是否成功...

"message":业务状态码的补充说明

"data":{ } 本次响应的数据 List<Schedule>...

... ...

}

  1. 当校验不通过,即用户名已经被占用的时候,无法阻止表单提交

解决

创建 common 包

创建类 Result:

java 复制代码
/**
 * 全局统一响应结果封装类
 * 用于标准化API接口的返回格式,包含状态码、响应消息和业务数据
 * @param <T> 响应数据的泛型类型,支持任意数据类型
 */

public class Result<T> {
    // 返回码:表示请求处理的状态(成功/失败/异常等)
    private Integer code;

    // 返回消息:对处理结果的文字描述(如"操作成功"、"参数错误"等)
    private String message;

    // 返回数据:业务处理的具体数据,泛型支持各种数据类型
    private T data;

    /**
     * 无参构造方法
     * 用于JSON序列化等场景
     */
    public Result() {
    }

    /**
     * 构建基础响应对象
     * @param data 响应数据
     * @param <T> 数据类型
     * @return 包含数据的Result对象
     */
    protected static <T> Result<T> build(T data) {
        Result<T> result = new Result<>();
        if (data != null) {
            result.setData(data);
        }
        return result;
    }

    /**
     * 构建完整响应对象
     * @param body 响应数据
     * @param code 状态码
     * @param message 响应消息
     * @param <T> 数据类型
     * @return 包含数据、状态码和消息的Result对象
     */
    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;
    }

    /**
     * 通过枚举构建响应对象
     * @param body 响应数据
     * @param resultCodeEnum 结果状态枚举(包含状态码和消息)
     * @param <T> 数据类型
     * @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 响应数据
     * @param <T> 数据类型
     * @return 包含成功状态和数据的Result对象
     */
    public static <T> Result<T> ok(T data) {
        return build(data, ResultCodeEnum.SUCCESS);
    }

    /**
     * 链式设置响应消息
     * @param msg 响应消息
     * @return 当前Result对象(支持链式调用)
     */
    public Result<T> message(String msg) {
        this.setMessage(msg);
        return this;
    }

    /**
     * 链式设置状态码
     * @param code 状态码
     * @return 当前Result对象(支持链式调用)
     */
    public Result<T> code(Integer code) {
        this.setCode(code);
        return this;
    }

    // Getter和Setter方法
    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;
    }
}

创建类 ResultCodeEnum:

java 复制代码
public enum ResultCodeEnum {
    SUCCESS(200, "success"),
    USERNAME_ERROR(501, "usernameError"),
    PASSWORD_ERROR(503, "passwordError"),
    NOTLOGIN(504, "notLogin"),
    USERNAME_USED(505, "usernameUsed");

    private Integer code;
    private String message;
    private ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public Integer getCode(){
        return code;
    }
    public String getMessage() {
        return message;
    }
}

我们要将这个 Result 对象转换成 JSON 串,需要导 jackson 包

controller 包下面的 SysUserControoller checkUsernameUsed 方法:

java 复制代码
    /**
     * 注册时,接收要注册的用户名,校验用户名是否被占用的业务接口
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void checkUsernameUsed(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收用户名
        String username = req.getParameter("username");
        // 调用服务处层业务处理方法查询用户名是否已经有对应的用户
        SysUser sysUser = userService.finByUsername(username);
        Result result = Result.ok(null);
        if (null != sysUser) {
            result = Result.build(null, ResultCodeEnum.USERNAME_USED);
        }

        // 将 result 对象转换为 JSON 串相应给客户端
        ObjectMapper objectMapper = new ObjectMapper();
        String info = objectMapper.writeValueAsString(result);
        // 告诉客户端响应的是一个是字符串
        resp.setContentType("application/json;charse=UTF-8");
        resp.getWriter().write(info);
    }

regist.html 修改:

这样就解决了两个问题。

在 SysUserController 下面的 checkUsernameUsed 中将 result 对象转换为 JSON 串的逻辑会经常被使用,我们可用抽象出一个方法:

java 复制代码
public class WebUtil {
    private static ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
    }

    // 专门用于向客户端响应 JSON 串的方法
    public static void writeJson(HttpServletResponse resp, Result result) {
        // 告诉客户端响应的是一个是字符串
        resp.setContentType("application/json;charse=UTF-8");

        // 将 result 对象转换为 JSON 串相应给客户端
        try {
            String info = objectMapper.writeValueAsString(result);
            resp.getWriter().write(info);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

完!

相关推荐
杭州杭州杭州14 天前
JavaWeb
后端·javaweb
qq_5895681015 天前
javaweb学习开发代码_HTML-CSS-JS
前端·javascript·css·javaweb
ruleslol1 个月前
Response对象
javaweb
Zz_waiting.1 个月前
Javaweb - 10.1 Servlet
servlet·tomcat·javaweb
Maỿbe1 个月前
实现回显服务器(基于UDP)
java·javaweb·echo·回显服务器
Java永无止境2 个月前
Web后端基础:数据库
java·数据库·javaweb·web
Java永无止境2 个月前
Web前端基础:HTML-CSS
java·前端·css·html·javaweb
fanTuanye2 个月前
JavaWeb是什么?总结一下JavaWeb的体系
java·大数据·javaweb·基础·体系
hello1114-3 个月前
Redis学习打卡-Day2-缓存更新策略、主动更新策略、缓存穿透、缓存雪崩、缓存击穿
java·redis·学习·缓存·javaweb