代码编织梦想

前提是前端必须有接收后端信息的载体:比如:ajax的异步接收等等。

后端:

编写后端的统一返回信息类:


/**
 * 后端统一返回结果
 * @param <T>
 */
@Data
public class Result<T> implements Serializable {
    private Integer code;//1成功,0和其他数字为失败。
    private String msg;//错误信息
    private T data;//数据

    public static <T> Result<T> success(){
        Result<T> result = new Result<T>();
        result.code=1;
        return result;
    }
    public static <T> Result<T> success(T object){
        Result<T> result = new Result<T>();
        result.data=object;
        result.code=1;
        return result;
    }

    public static <T> Result<T> error(String msg){
        Result<T> result = new Result<T>();
        result.code=0;
        result.msg=msg;
        return result;
    }
}

异常基础类:

/**
 * 业务异常
 */
public class BaseException extends RuntimeException{
    public BaseException(String message) {
        super(message);
    }
    public BaseException() {
    }
}
账号不存在异常:
/**
 * 账号不存在异常
 */
public class AccountNotFoundException extends BaseException {

    public AccountNotFoundException() {
    }

    public AccountNotFoundException(String msg) {
        super(msg);
    }

}
账号密码为空异常:
/**
 * 账号密码为空
 */
public class InputAccountAndPassword extends BaseException{
    public InputAccountAndPassword(String message) {
        super(message);
    }
}

 登录失败异常:

/**
 * 登录失败
 */
public class LoginFailedException extends BaseException{
    public LoginFailedException(String msg){
        super(msg);
    }
}

 密码错误:

/**
 * 密码错误异常
 */
public class PasswordErrorException extends BaseException {

    public PasswordErrorException() {
    }

    public PasswordErrorException(String msg) {
        super(msg);
    }

}

全局异常类:

/**
 * 全局异常处理
 */
//@ControllerAdvice(annotations = {RestController.class,Controller.class})
//@ResponseBody
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 业务异常
     * @param ex 异常信息
     * @return 封装、抛出给前端
     */
    @ExceptionHandler
    public Result<String> exceptionHandler(BaseException ex){
        log.error(ex.getMessage());
        return Result.error(ex.getMessage());
    }

    @ExceptionHandler
    public Result<String> exceptionHandler(ExpiredJwtException ex){
        String message=ex.getMessage();
        if (message.contains("expired")){
            return Result.error("登录过期!");
        }
        return null;
    }
}

举例:

登录的服务

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Autowired(required = false)
    private LoginMapper loginMapper;

    /**
     * 用户登录
     * @param user 用户
     */
    public void userLogin(User user) {
        String email = user.getEmail();
        String password = user.getPassword();
        if (email.isEmpty() || password.isEmpty()) {
            //账号密码为空
            throw new InputAccountAndPassword(MessageConstant.ACCOUNT_PASSWORD_EMPTY);
        }
        //账号密码不为空
        else {
            //验证账号
            int i = loginMapper.userExist(email);
            //账号存在
            if (i > 0) {
                //验证密码
                int p = loginMapper.loginCheck(email, password);
                //密码正确
                if (p == 1) {
                    //准许登录 state==1
                    loginMapper.login(email);
                }
                else {
                    //密码错误
                    throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
                }
            }
            //账号不存在
            else {
                throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
            }
        }
    }
}

异常提示常量类MessageConstant:

/**
 * 信息提示常量类
 */
public class MessageConstant {
    public static final String PASSWORD_ERROR = "密码错误";
    public static final String ACCOUNT_NOT_FOUND = "账号不存在";
    public static final String LOGIN_FAILED = "登录失败";
    public static final String ACCOUNT_PASSWORD_EMPTY="请输入账号和密码";
}

控制端:

@RestController
@RequestMapping("/login")
@Slf4j
public class LoginController {
    @Autowired(required = false)
    private LoginService loginService;
    @Autowired
    private JwtProperties jwtProperties;
    @PostMapping("/userlogin")
    public Result login(@RequestBody User user){
        log.info("开始登录:email:{},password:{}",user.getEmail(),user.getPassword());
        log.info("{}",user);
        loginService.userLogin(user);
        //登录成功后,生成jwt令牌
        Map<String, Object>claims=new HashMap<>();
        claims.put("userId",1L);
        claims.put("email",user.getEmail());
        String token= JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(),
                jwtProperties.getUserTtl(),
                claims);
        UserDTO userDTO = new UserDTO();
        userDTO.setToken(token);
        log.info("生成的token是:{}",token);
        return Result.success(userDTO);
    }
}

前端登录页面以及ajax的测试用例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>欢迎登录公司员工考勤管理平台</title>
    <link rel="shortcut icon" th:href="@{/images/icon.svg}">
    <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}">
    <script th:src="@{/js/jquery-3.2.1.js}"></script>
    <script th:src="@{/js/token.js}"></script>
    <script type="text/javascript">
        $(function () {
            let token=null;
            //登录按钮
            $("#login").click(function () {
                let email=$('#email').val();
                let password=$('#password').val();
                $.ajax({
                    type:"post",
                    url:"/login/userlogin",
                    contentType:"application/json",
                    data:JSON.stringify({"email":email,"password":password}),
                    success:function (result) {
                        if (result.code===1){
                             token=result.data.token;
                            alert("登录成功");
                        //    收到Token,开始存储token
                            localStorage.setItem('token',token);
                            alert("token值为:"+token+"!");
                            //返回Token给后端
                            //返回后端
                            location.href="/main";//也会经过拦截器
                        }else {
                            alert(result.msg);
                        }
                    }
                });
            });

         $("#registry").click(function () {
             location.href="/registry"
         })
        })
    </script>
</head>
<body style="position: absolute;
  top: 20%;
  left: 38%;
  transform: translate(40%,40%);
  margin: 0;padding: 0">
<div>
    <h2>登录页面</h2>
</div>
<div>
    <label for="email"></label><input type="text" id="email" name="email" placeholder="E-mail address">
</div>
<div>
    <label for="password"></label><input type="password" id="password" name="password" placeholder="Password"/>
</div>
<button id="login">登录</button>
<button id="registry">注册</button>
</body>
</html>

测试:

账号密码不为空:

后台:

账号不存在:

后台:

密码错误:

后台:

还有很多其他的情况......

Tips:其实有些情况可以直接在前端判断,没有必要全部都给到后台判断,这样会造成后台压力比较大;比如密码账号不为空,账号格式等等。

本期内容到这,如果帮到你了,或者你学到了新知识点,可以点赞收藏关注走一波,支持作者!作者后续会更新发布更多更加高质量的文章!谢谢!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_70630103/article/details/140285616

springboot中异常处理_李守余的博客-爱代码爱编程

本文先介绍默认的异常处理类,然后介绍自定义的异常处理 默认的异常处理类BasicErrorController 默认的基础处理类BasicErrorController处理异常的路径是/error,对于请求头中带

基于Spring Boot + Vue 前后端分离个人博客网站设计-爱代码爱编程

基于Spring Boot + Vue 前后端分离个人博客网站设计 项目源码摘要一、绪论1.1 课题背景、目的、意义1.2 国内外研究现状1.3 技术介绍1.3.1 Spring Boot1.3.2 MyBatisPlus1.3.3 Shiro1.3.4 Redis1.3.5 Jwt1.3.6 Vue1.3.7 Element-ui1.3.8 Ax

前端怎么获得后端抛出的异常_Spring MVC/Boot 统一异常处理最佳实践-爱代码爱编程

1. 前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 对于很多人来说, 可能对异常处理有以下几个问题: 什么时候需要捕获(try-catch)异常, 什么时候需要抛出(throws)异常到上层.在 dao 层捕获还是在 service 捕获, 还是在 controller 层捕获.抛出异常后要怎么处理. 怎

spring boot捕获异常,直接返回给前端,造成信息泄露的问题。_justforglory的博客-爱代码爱编程

近日解决项目安全漏洞问题,有个异常直接抛出问题。 请求信息: POST /javaxieyi/api.do?no=601&ver=507&timestamp=1661323408810 HTTP/1.1 Host: 192.168.0.91:8018 Content-Length: 151 Accept: application/j

springboot统一收集异常信息并返回给前端-爱代码爱编程

目录 适用场景 实现方法 结合Servlet对象 @RestControllerAdvice 适用场景 通常前后端交互时,后端对前端参数进行校验后,对于校验不通过的信息会自定义一个异常抛出,但是后端一旦抛出异常,后台接口服务就会报500的错误 对于有些逻辑错误而言,我们只是想将此信息提示给用户,这时候我们需要将抛出来的异常进行捕获,

电脑弹窗消息=springboot瘦包+pc消息提醒-爱代码爱编程

1、springboot中要正常使用java.awt的包,请修改主入口为如下代码 @SpringBootApplication public class ActivemqHandlerApplication { public static void main(String[] args) { ConfigurableAppli

springboot优雅地处理全局异常,返回前端-爱代码爱编程

笔者这边提供了两种处理全局异常的方式。这两种方式各有千秋,都很优雅。至于伙伴们想用哪种方式,那就仁者见仁,智者见智了。 0、公共部分 在介绍异常处理方式前,先定义一些公共的类。这些类在两种处理方式中都会用到。 【自定义业务异常】 /** * 自定义业务异常 */ @Data public class SunException extends

springboot+vue练手小项目[前台搭建+后台编写](非常详细)_spirngboot+vue项目练手-爱代码爱编程

[ springboot+vue练手小项目 ] 技术栈: springboot+vue3+element-plus +Mybaties-plus+hutool +mysql8 项目介绍 :最近刚学了springboo

使用spring boot实现异常的统一返回-爱代码爱编程

在这个前后端分离的时代,一个 统一的数据格式非常重要。本次我们实现用spring boot实现一下返回给前端数据的统一格式,不再出现服务器500的错误。 新建一个spring boot项目,并导入knife4j的依赖。 写一个controller控制器,用来是实现测试http的请求 @RestController public class TestC

springboot中实现全局异常处理,统一返回错误信息给前端_javaspringboot中如何在get请求没有传递参数的时候返回一个统一的错误信息给前端-爱代码爱编程

背景引入:最近实现了一个限流切面类,但是在限流方法中throw异常,会直接打印到控制台,报错500,对前端很不友好。因为是注解,又没办法捕获再处理。那么怎么才能将错误码返回给前端呢?原来是全局异常处理…… 切面方法: @Before(value = "AccessLimitPointcut()") public void handleAcces