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

在第四期内容中,我们主要解决的是用 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();
        }
    }
}

完!

相关推荐
郑洁文9 天前
基于Javaweb的高校网上订餐系统
javaweb·毕设·高校网上订餐系统
初学小白...1 个月前
JavaWeb
javaweb·web
一只大袋鼠1 个月前
SpringMVC 框架中的拦截器
java·springmvc·javaweb·拦截器
一只大袋鼠1 个月前
SpringMVC全局异常处理
java·开发语言·springmvc·javaweb
一只大袋鼠1 个月前
JavaWeb四种文件上传方式(下篇)
java·开发语言·springmvc·javaweb
一只大袋鼠1 个月前
JavaWeb四种文件上传方式(上篇)
java·开发语言·servlet·javaweb
abcnull1 个月前
传统的JavaWeb项目Demo快速学习!
java·servlet·elementui·vue·javaweb
float_com2 个月前
【JavaWeb】----- 登录认证 与 统一拦截架构详解
javaweb
float_com2 个月前
【JavaWeb】----- Linux基础入门
linux·javaweb
夹芯饼干3 个月前
JavaWeb 核心:Request 与 Response 对象全解析与实战
javaweb·重定向·request对象·response对象