5.SpingBoot创建一个简单的登录示例

注意:由于内容有点多,在看本文章前,一定要按照下面菜单中的教程,一步一步来菜单-->SpringBoot企业级开发精讲系列教程接着上一章所讲,本节主要实现一个简单的登录认证系统,涉及到的技术点包

by
江江
on
2018/06/02
5.SpingBoot创建一个简单的登录示例

注意:由于内容有点多,在看本文章前,一定要按照下面菜单中的教程,一步一步来

菜单

-->SpringBoot企业级开发精讲系列教程

接着上一章所讲,本节主要实现一个简单的登录认证系统,涉及到的技术点包括API协议包装,全局异常统一处理等,这是真正的企业级核心技术,也是基础之一

1.创建rqto包和rpto

rqto即request transfer object,是API接口请求数据的包装

rpto即response transfer object,是API接口返回数据的包装

2.创建LoginRPTO类

@Data
public class LoginRPTO {
    private long user_id;
    private String nickname;
}

3.创建core包,新建ActionCode枚举类

public enum ActionCode {
    ERROR(0,"请求失败"),
    SUCCESS(1,"请求成功"),
    EXCEPTION(10,"服务器异常"),
    VALID(100,"参数校验异常");

    public int code;
    public String message;


    ActionCode(int code, String message) {
        this.code = code;
        this.message = message;
    }
}

在这个枚举类中定义常见的通用异常code

4.新建RPTO协议类

@Data
public class RPTO<T> {
    private int code;
    private String message;
    private T data;

    public RPTO(String message){
        this(ActionCode.ERROR,message,null);
    }
    public RPTO(ActionCode action){
        this(action,null);
    }
    public RPTO(ActionCode action,T data){
        this(action.code,action.message,data);
    }
    public RPTO(ActionCode action,String message,T data){
        this(action.code,message,data);
    }
    public RPTO(int code, String message) {
        this(code,message,null);
    }
    public RPTO(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

协议体如下:

code mssage data
接口状态码 接口处理消息 返回数据,泛型结构

最终希望看到在请求一个接口后,返回如下信息

{"code":1,"message":"请求成功","data":{"user_id":1,"nickname":"admin"}}

5.创建LoginRQTO

@Data
public class LoginRQTO {

    @NotEmpty(message = "昵称不能为空")
    @Length(max = 12,message = "昵称最大长度12")
    private String nickname;

    @NotEmpty(message = "密码不能为空")
    @Length(max = 20,message = "密码最大长度20")
    private String password;

}

6.修改GlobalExceptionHandler类

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public RPTO exceptionHandler(Exception ex) throws IOException {
        if (ex instanceof MethodArgumentNotValidException) {
            BindingResult result = ((MethodArgumentNotValidException) ex).getBindingResult();
            if (result.hasErrors()) {
                StringBuffer sb = new StringBuffer();
                printBindException(sb, result);
                return new RPTO<>(ActionCode.VALID,sb.toString(),null);
            }
        }
        return new RPTO<>(ActionCode.EXCEPTION);
    }
    private void printBindException(StringBuffer message, BindingResult result) {
        List<ObjectError> allErrors = result.getAllErrors();
        for (int i = 0; i < allErrors.size(); i++) {
            message.append(allErrors.get(i).getDefaultMessage());
            if (allErrors.size() > 1 && i < allErrors.size() - 1) {
                message.append(",");
            }
        }
    }
}

当发生异常时,我们希望接口返回

{"code":100,"message":"密码不能为空","data":null}

7.创建UserController类

@Controller
@RequestMapping("/user")
public class UserController {
    @ResponseBody
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public RPTO login(@RequestBody @Valid LoginRQTO login) {
        if(!login.getNickname().equals("admin") ||
                !login.getPassword().equals("123")){
            return new RVO<>("用户名密码错误");
        }
        LoginRPTO rvo = new LoginRPTO();
        rvo.setUser_id(1);
        rvo.setNickname(login.getNickname());
        return new RPTO<>(ActionCode.SUCCESS,rvo);
    }
}

8.新建login.html

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <h2>用户登录</h2><hr>
    <input id="nickname" type="text" value="admin"/></br>
    <input id="password"  type="text" value="123"/></br>
    <button onclick='login()'>登录</button></br>
    <div id="tip"></div>

    <script src="jquery.min.js"></script>
    <script>
    function login(){
        var nickname = $("#nickname").val();
        var password = $("#password").val();
        $.ajax({
                url: 'http://localhost:8080/user/login',
                type: "post",
                contentType: 'application/json;charset=utf-8',
                dataType: 'json',
                data: JSON.stringify({
                    nickname: nickname,
                    password: password
                }),
                success: function (res) {
                    if(res.code == 1){
                        $("#tip").html("用户ID = "+res.data.user_id+"  用户名 = "+res.data.nickname);
                    }else{
                        $("#tip").html(res.message);
                    }
                },
                error: function () {
                    $("#tip").html("连接失败");
                }
        });
    }
    </script>
</body>
</html>

此时目录结构如下

9.运行

打开浏览器,输入

http://localhost:8080/login.html

抓包分析,查看一下结构

删除密码,再次点击登录测试

抓包分析,查看一下结构

-----------------------------------------------------------------------------

江江江江于 2026-10-15 14:16:05 修改阅读 1644评论 0点赞 0