搭建springboot后端框架(六)自定义异常+后端统一响应消息

本文档展示了如何在SpringBoot2.5.0项目中实现自定义异常捕获和统一返回处理。主要涉及错误码枚举、响应实体、工具类、自定义异常和异常拦截器配置。通过这些组件,可以标准化系统的异常反馈和正常请求的返回格式。

项目搭建工具及版本:

eclipse / jdk1.8 / springboot2.5.0 

实现功能:

主要实现2个点,自定义的异常捕获返回给请求方,正常请求的统一返回处理。

1.主要功能类说明

错误码枚举类、响应返回实体类、响应返回实体工具类、自定义异常、自定义异常拦截器配置类

 2.源代码

package com.bbnet.common.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 常见的错误枚举类
 *
 *
 * @author sgc
 * @since 2021-08-27
 */
@Getter
@AllArgsConstructor
public enum  ErrorEnum {
	
    RESP_CODE_SUCC("0","请求成功"),
    RESP_CODE_FAIL("1","请求失败"),
    RESP_CODE_NO_TOKEN("-1","TOKEN为空"),
    RESP_CODE_TIMEOUT("-2","会话超时或非法请求");

    /**
     * 错误码
     */
    private String code;

    /**
     * 提示信息
     */
    private String msg;
}
package com.bbnet.common.exception;

import lombok.Data;

/**
 * 响应对象
 *
 * @param <T>
 *
 * @author sgc
 * @since 2021-08-27
 */
@Data
public class ResponseResult<T> {

		/**
		 * 状态码
		 */
		private String code;

		/**
		 * 提示信息
		 */
		private String msg;
		
		/**
		 * 请求成功时返回的对象
		 */
		private T data;

}
package com.bbnet.common.exception;

/**
 * 响应对象工具类
 *
 *
 * @author sgc
 * @since 2021-08-27
 */
public class ResponseUtils {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static ResponseResult success(Object obj){
		ResponseResult res = new ResponseResult();
		res.setCode(ErrorEnum.RESP_CODE_SUCC.getCode());
		res.setData(obj);
		res.setMsg(ErrorEnum.RESP_CODE_SUCC.getMsg());
		return res;
	}

	@SuppressWarnings("rawtypes")
	public static ResponseResult success(){
		return success(null);
	}

	@SuppressWarnings("rawtypes")
	public static ResponseResult error(String code, String msg){
		ResponseResult res = new ResponseResult();
		res.setCode(code);
		res.setMsg(msg);
		return res;
	}

}

package com.bbnet.common.exception;

import lombok.Getter;

/**
 * 自定义异常
 *
 *
 * @author sgc
 * @since 2021-08-27
 */
@Getter
public class ServiceException extends RuntimeException{
	
	private static final long serialVersionUID = 7133651385712198609L;
	private String code;

    /**
     * 使用已有的错误类型
     * @param type 枚举类中的错误类型
     */
    public ServiceException(ErrorEnum type){
        super(type.getMsg());
        this.code = type.getCode();
    }

    /**
     * 自定义错误类型
     * @param code 自定义的错误码
     * @param msg 自定义的错误提示
     */
    public ServiceException(String code, String msg){
        super(msg);
        this.code = code;
    }
}
package com.bbnet.common.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bbnet.common.encrypt.annotation.Encrypt;

/**
 * 异常处理类
 *
 *
 * @author sgc
 * @since 2021-08-27
 */
@ControllerAdvice 
public class ServiceExceptionHandler {

    /**
     * <pre>
     * ExceptionHandler相当于controller的@RequestMapping
     * 如果抛出的的是ServiceException,则调用该方法
     * </pre>
     * 
     * @param se 业务异常
     * @return
     */
    @SuppressWarnings("rawtypes")
	@ExceptionHandler(ServiceException.class)
    @ResponseBody
    @Encrypt
    public ResponseResult handle(ServiceException se){
        return ResponseUtils.error(se.getCode(), se.getMessage());
    }
}

3.测试

如下面的部分代码,如有异常可以直接抛出,如正常返回直接返回ResponseUtils.success()或者ResponseUtils.success(Obj)

//code...

    @SuppressWarnings("rawtypes")
	@ApiOperation(value="删除token接口", notes="token时效情况下删除token,即类似于退出登录")
    @PostMapping("/removeToken")
    public ResponseResult removeToken(@RequestBody Token token) {
		//参数校验
		if(oConvertUtils.isEmpty(token.getAccount())) {
			throw new ServiceException(ErrorEnum.RESP_CODE_FAIL.getCode(), "账号或用户名为空");
		}
		
		//account的加密结果
		String accountEnc = AES.aesEncryptBase64(token.getAccount());
		//bbnet:user_prefix_token:002604_MnJMUnY1TWNhVmZsMXlLQjNkajR6QT09
		String key = ServiceConstants.TOKEN_PREFIX+token.getAccount()+"_"+accountEnc;
		log.info("Token的key为:{}", key);
		
		//如果已经存在token直接返回
		if(redisService.hasKey(key)) {
			redisService.del(key);
		}
		
		return ResponseUtils.success();
	}


//code...
package com.bbnet.common.base.token;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
@ApiModel(value="TOKEN报文实体")
public class Token {
	
	@ApiModelProperty(value = "账号/用户名", dataType = "String")
	String account;
	
	@ApiModelProperty(value = "口令/密码", dataType = "String")
	String password;

}

比如以下请求示例截图:

### Spring Boot 后端开发框架介绍 Spring Boot 是一个用于简化新 Spring 应用程序初始搭建以及开发过程的框架。该框架旨在帮助开发者更加快捷高效地构建独立运行的应用程序,无需繁琐配置即可启动应用并提供生产级别的功能支持[^1]。 #### 创建 Spring Boot 项目 为了创建一个新的 Spring Boot 项目,在 IDE 中选择合适的模板并向其中添加所需的依赖项,比如 Web 支持、JPA 或 MyBatis 等持久化工具集成等。完成依赖的选择之后,点击 Finish 完成项目的初始化工作。 ```java // Maven pom.xml 文件片段展示部分依赖声明 <dependencies> <!-- 添加Web模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 数据库连接池和其他必要的组件 --> ... </dependencies> ``` #### 使用注解定义服务与仓库 在应用程序内部,`@Service` 和 `@Repository` 这两个注解分别用来标识业务逻辑和服务层组件以及数据访问对象(DAO)。前者负责处理具体的业务流程而后者则专注于同数据库交互的操作。此外,还可以借助 `@Autowired` 实现自动化的依赖注入机制来管理不同层次间的协作关系[^2]。 ```java @Service public class UserService { } @Repository public interface UserRepository extends JpaRepository<User, Long> { } ``` #### 自定义 Bean 及其注册方式 除了上述提到的基础结构外,有时也需要自定义一些辅助性的 Java 对象作为 spring 上下文中的一部分参与进来。这可以通过编写带有 `@Configuration` 的类,并在其内通过方法返回实例的方式向容器贡献新的 bean 来达成目的。例如下面这段代码展示了如何将 RestTemplate 注册成为一个可被其他地方使用的单例资源: ```java @Configuration public class AppConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } ``` #### 构建 RESTful API 接口 为了让前端能够顺利获取到后端所提供的信息,通常会设计一系列遵循REST风格的服务接口供外部调用。这些接口一般位于 Controller 层中,它们接收来自客户端发出的各种请求并将响应结果反馈回去。当用户在浏览器地址栏里键入特定 URL 路径时,实际上就是在尝试触发某个对应的 HTTP 方法从而获得预期的数据集[^3]。 ```java @RestController @RequestMapping("/api/users") public class UserController { private final UserService userService; @GetMapping("/{id}") public ResponseEntity<UserDTO> getUserById(@PathVariable Long id){ User user = userService.findById(id); if (user != null) { return ResponseEntity.ok(new UserDTO(user)); } else { throw new ResourceNotFoundException("User not found with id " + id); } } // 更多功能... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cgv3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值