/**
- 成功
*/
public static Result success(T data) {
Result result = new Result();
result.setCode(ResultMsgEnum.SUCCESS.getCode());
result.setMessage(ResultMsgEnum.SUCCESS.getMessage());
result.setData(data);
return result;
}
/**
- 失败
*/
public static Result error(int code, String message) {
return new Result(code, message);
}
}
复制代码
- 定义返回状态码
public enum ResultMsgEnum {
SUCCESS(0, “成功”),
FAIL(-1, “失败”),
AUTH_ERROR(502, “授权失败!”),
SERVER_BUSY(503, “服务器正忙,请稍后再试!”),
DATABASE_OPERATION_FAILED(504, “数据库操作失败”);
private int code;
private String message;
ResultMsgEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
复制代码
- 使用方式
上面两步定义了数据返回格式
和状态码
,接下来就要看下在接口中如何使用了。
@GetMapping(“/getUserName”)
public Result getUserName(){
return Result.success(“huage”);
}
复制代码
调用结果如下,可以看到是我们在Result中定义的参数类型。
{
“code”: 0,
“message”: “成功”,
“data”: “huage”
}
复制代码
这样写虽然能够满足日常需求,而且我相信很多小伙伴也是这么用的,但是如果我们有大量的接口,然后在每一个接口中都使用Result.success
来包装返回信息,会新增很多重复代码,显得不够优雅,甚至都不好意思拿出去显摆。 肯定会有一种方式能够再一次提高代码逼格,实现最优解。
三、进阶用法
基本用法学会后,接下来看点究极版本,主要用到如下两个知识点,用法简单,无论是拿出来教学妹,还是指点小姐姐,都是必备技能。
3.1 类介绍
-
ResponseBodyAdvice: 该接口是SpringMVC 4.1提供的,它允许在 执行
@ResponseBody
后自定义返回数据,用来封装统一数据格式返回; -
@RestControllerAdvice: 该注解是对Controller进行增强的,可以全局捕获抛出的异常。
3.2 用法说明
-
新建
ResponseAdvice
类; -
实现
ResponseBodyAdvice
接口,实现supports
、beforeBodyWrite
方法; -
该类用于统一封装controller中接口的返回结果。
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
@Autowired
private ObjectMapper objectMapper;
/**
- 是否开启功能 true:是
*/
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
/**
- 处理返回结果
*/
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
//处理字符串类型数据
if(o instanceof String){
try {
return objectMapper.writeValueAsString(Result.success(o));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return Result.success(o);
}
}
复制代码
我们可以通过getUserName
接口测试一下,会发现和直接使用Result
返回的结果是一致的。
不过,细心的小伙伴们肯定注意到了,在ResponseAdvice
我们全部使用了Result.success(o)
来处理结果,对于error类型的结果未做处理。我们来看下,发生异常情况时,返回结果是什么样呢?继续使用上面HashMap空指针异常的代码,测试结果如下:
{
“code”: 0,
“message”: “成功”,
“data”: {
“timestamp”: “2021-08-09T09:33:26.805+00:00”,
“status”: 405,
“error”: “Method Not Allowed”,
“path”: “/sysUser/getUserName”
}
}
复制代码
虽然格式上没有毛病,但是在code、data字段的具体数据上是不友好或不正确的。不处理好这些事情,会严重影响自己在前端妹妹心中的高大形象的,这是决不能容忍的。
3.3 全局异常处理器
以前我们遇到异常时,第一时间想到的应该是try…catch…finnal吧,不过这种方式会导致大量代码重复,维护困难,逻辑臃肿等问题,这不是我们想要的结果。
今天我们要用的全局异常处理方式,用起来是比较简单的。首先新增一个类,增加@RestControllerAdvice
注解,该注解的作用花哥上面已经介绍过,就不再唠叨了。
@RestControllerAdvice
public class CustomerExceptionHandler {
}
复制代码
如果我们有想要拦截的异常类型,就新增一个方法,使用@ExceptionHandler
注解修饰,注解参数为目标异常类型。
例如:controller中接口发生Exception异常时,就会进入到Execption
方法中进行捕获,将杂乱的异常信息,转换成指定格式后交给ResponseAdvice
方法进行统一格式封装并返回给前端小伙伴。
@RestControllerAdvice
@Slf4j
public class CustomerExceptionHandler {
@ExceptionHandler(AuthException.class)
public String ErrorHandler(AuthorizationException e) {
log.error(“没有通过权限验证!”, e);
return “没有通过权限验证!”;
}
@ExceptionHandler(Exception.class)
public Result Execption(Exception e) {
log.error(“未知异常!”, e);
return Result.error(ResultMsgEnum.SERVER_BUSY.getCode(),ResultMsgEnum.SERVER_BUSY.getMessage());
}
}
复制代码
再次调用接口getUserName
查看返回结果,会发现还是有一些问题,因为我们在CustomerExceptionHandler
中已经将接口返回结果封装成Result
类型,而代码执行到统一结果返回类ResponseAdvice
时,又会结果再次封装,就出现了如下问题。
{
“code”: 0,
“message”: “成功”,
“data”: {
“code”: 503,
“message”: “服务器正忙,请稍后再试!”,
“data”: null
}
}
复制代码
3.4 统一返回结果处理类最终版
解决上述问题非常简单,只要在beforeBodyWrite
中增加一条判断即可。
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
@Autowired
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后,附一张自己面试前准备的脑图:
面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典
- Java核心知识整理
- Spring全家桶(实战系列)
Step3:刷题
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
]
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算