Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 384|回复: 0

springboot2.0-统一处理返回结果和异常情况

[复制链接]
  • TA的每日心情
    奋斗
    昨天 14:28
  • 签到天数: 793 天

    [LV.10]以坛为家III

    2049

    主题

    2107

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    723458
    发表于 2021-7-9 11:44:45 | 显示全部楼层 |阅读模式

    一、统一处理返回结果和异常处理的原因:

    1、在springboot项目里我们希望接口返回的数据包含至少三个属性:

    a、code:请求接口的返回码,成功或者异常等返回编码,例如定义请求成功,code = "0000",查询结果为null,code = "0001";

    b、msg:请求接口的描述,也就是对返回编码的描述,"0000":就表示请求成功,"0001":表示结果为null;

    c、data:请求接口成功,返回的结果。

    
       
       
    1. {
    2. "data": {
    3. "id": 1,
    4. "studentId": "13240115",
    5. "name": "Tiger",
    6. "age": 25,
    7. "famillyAddress": "北京",
    8. "createdDate": "2018-10-08T05:45:49.000+0000",
    9. "updatedDate": "2018-10-09T03:15:33.000+0000"
    10. },
    11. "code": "0000",
    12. "msg": "请求成功"
    13. }

    2、在springboot项目里我们希望请求结果失败之后,通过返回码和返回描述来告诉前端接口请求异常。

    
       
       
    1. {
    2. "code": "0001",
    3. "msg": "学号不存在"
    4. }

    二、案例

    1、建一张学生信息表,包含学生的学号、姓名、年龄、家庭住址等

    
       
       
    1. CREATE TABLE student_info (
    2. id bigint( 20) NOT NULL AUTO_INCREMENT COMMENT '自增',
    3. student_id varchar( 20) NOT NULL COMMENT '学号',
    4. name varchar( 64) NOT NULL COMMENT '姓名',
    5. age int( 2) NOT NULL COMMENT '年龄',
    6. familly_address varchar( 256) NOT NULL COMMENT '家庭地址',
    7. created_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    8. updated_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
    9. PRIMARY KEY (student_id),
    10. KEY id ( id)
    11. ) ENGINE= InnoDB DEFAULT CHARSET=utf8mb4

    2、pom.xml

    
       
       
    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.boot </groupId>
    4. <artifactId>spring-boot-starter-web </artifactId>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.springframework.boot </groupId>
    8. <artifactId>spring-boot-starter-test </artifactId>
    9. <scope>test </scope>
    10. </dependency>
    11. <dependency>
    12. <groupId>org.springframework.boot </groupId>
    13. <artifactId>spring-boot-starter-data-redis </artifactId>
    14. </dependency>
    15. <dependency>
    16. <groupId>org.mybatis.spring.boot </groupId>
    17. <artifactId>mybatis-spring-boot-starter </artifactId>
    18. <version>1.3.1 </version>
    19. </dependency>
    20. <dependency>
    21. <groupId>mysql </groupId>
    22. <artifactId>mysql-connector-java </artifactId>
    23. <version>5.1.46 </version>
    24. </dependency>
    25. <dependency>
    26. <groupId>com.alibaba </groupId>
    27. <artifactId>druid </artifactId>
    28. <version>1.1.9 </version>
    29. </dependency>
    30. <dependency>
    31. <groupId>org.projectlombok </groupId>
    32. <artifactId>lombok </artifactId>
    33. <version>1.16.22 </version>
    34. </dependency>
    35. <dependency>
    36. <groupId>com.alibaba </groupId>
    37. <artifactId>fastjson </artifactId>
    38. <version>1.2.43 </version>
    39. </dependency>
    40. <dependency>
    41. <groupId>com.squareup.okhttp3 </groupId>
    42. <artifactId>okhttp </artifactId>
    43. <version>3.9.1 </version>
    44. </dependency>
    45. <dependency>
    46. <groupId>org.glassfish </groupId>
    47. <artifactId>javax.json </artifactId>
    48. <version>1.0.4 </version>
    49. </dependency>
    50. <dependency>
    51. <groupId>org.apache.tomcat.embed </groupId>
    52. <artifactId>tomcat-embed-jasper </artifactId>
    53. </dependency>
    54. </dependencies>

    3、案例中使用redis进行缓存,可以不需要

    Windows环境安装redis以及缓存应用

    4、创建实体类:StudentInfo

    
       
       
    1. package com.dl.cn.message.bean;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Builder;
    4. import lombok.Data;
    5. import lombok.NoArgsConstructor;
    6. import java.io.Serializable;
    7. import java.util.Date;
    8. /**
    9. * Created by Tiger on 2018/10/8.
    10. */
    11. @Data
    12. @Builder
    13. @AllArgsConstructor
    14. @NoArgsConstructor
    15. public class StudentInfo implements Serializable{
    16. private static final long serialVersionUID = 2597547944454691103L;
    17. private Long id;
    18. private String studentId;
    19. private String name;
    20. private Integer age;
    21. private String famillyAddress;
    22. private Date createdDate;
    23. private Date updatedDate;
    24. }

    5、创建Mapper:StudentInfoMapper

    
       
       
    1. package com.dl.cn.message.mapper;
    2. import com.dl.cn.message.bean.StudentInfo;
    3. import org.apache.ibatis.annotations.*;
    4. /**
    5. * Created by Tiger on 2018/10/8.
    6. */
    7. @Mapper
    8. public interface StudentInfoMapper {
    9. @Insert("insert into student_info(student_id,name,age,familly_address)" +
    10. " values(#{studentId},#{name},#{age},#{famillyAddress})")
    11. /**
    12. * 通过bean保存实体类是,建议不要通过@Param注解,负责实体类的属性都在@Param中找
    13. * */
    14. void saveStudentInfo(StudentInfo studentInfo);
    15. @Select("select * from student_info where student_id = #{studentId}")
    16. StudentInfo findByStudentId( @Param("studentId") String studentId);
    17. @Update("update student_info set familly_address = #{famillyAddress},updated_date = now() ")
    18. void updateFamillyAddress( @Param("studentId") String studentId, @Param("famillyAddress") String famillyAddress);
    19. }

    6、创建service:StudentInfoService

    
       
       
    1. package com.dl.cn.message.service;
    2. import com.dl.cn.message.bean.StudentInfo;
    3. import com.dl.cn.message.mapper.StudentInfoMapper;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.springframework.beans.factory. annotation.Autowired;
    6. import org.springframework.cache. annotation.CacheConfig;
    7. import org.springframework.cache. annotation.CacheEvict;
    8. import org.springframework.cache. annotation.Cacheable;
    9. import org.springframework.stereotype.Service;
    10. /**
    11. * Created by Tiger on 2018/10/8.
    12. */
    13. @Service
    14. @CacheConfig(cacheNames = "studentInfo")
    15. @Slf4j
    16. public class StudentInfoService {
    17. @Autowired
    18. StudentInfoMapper studentInfoMapper;
    19. /**
    20. * 保存学生信息
    21. * @param studentInfo
    22. * */
    23. public void saveStudentInfo(StudentInfo studentInfo){
    24. studentInfoMapper.saveStudentInfo(studentInfo);
    25. }
    26. /**
    27. * 根据学号查学生信息
    28. * @param studentId
    29. * @return
    30. * */
    31. @Cacheable(key = "#studentId",unless = "#result == null")
    32. public StudentInfo findByStudentId(String studentId){
    33. log.info( "查找信息:{}",studentId);
    34. return studentInfoMapper.findByStudentId(studentId);
    35. }
    36. /**
    37. * 根据学号更新家庭地址
    38. * @param studentId
    39. * @param famillyAddress
    40. * */
    41. //删除对应key的缓存
    42. @CacheEvict(key = "#studentId")
    43. public void updateFamillyAddress(String studentId,String famillyAddress){
    44. studentInfoMapper.updateFamillyAddress(studentId,famillyAddress);
    45. }
    46. }

    7、创建统一返回结果类:Response

    
       
       
    1. package com.dl.cn.message.response;
    2. import com.fasterxml.jackson.databind. annotation.JsonSerialize;
    3. import lombok.Getter;
    4. import lombok.Setter;
    5. import java.io.Serializable;
    6. /**
    7. * 请求返回类
    8. * Created by Tiger on 2018/10/9.
    9. */
    10. @Getter
    11. @Setter
    12. @JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
    13. public class Response<T> implements Serializable {
    14. private static final long serialVersionUID = -4505655308965878999L;
    15. //请求成功返回码为:0000
    16. private static final String successCode = "0000";
    17. //返回数据
    18. private T data;
    19. //返回码
    20. private String code;
    21. //返回描述
    22. private String msg;
    23. public Response(){
    24. this.code = successCode;
    25. this.msg = "请求成功";
    26. }
    27. public Response(String code,String msg){
    28. this();
    29. this.code = code;
    30. this.msg = msg;
    31. }
    32. public Response(String code,String msg,T data){
    33. this();
    34. this.code = code;
    35. this.msg = msg;
    36. this. data = data;
    37. }
    38. public Response(T data){
    39. this();
    40. this. data = data;
    41. }
    42. }

    8、创建异常编码和描述类:ErrorCodeAndMsg

    
       
       
    1. package com.dl.cn.message.enums;
    2. /**
    3. * Created by Tiger on 2018/10/9.
    4. */
    5. public enum ErrorCodeAndMsg {
    6. Student_number_does_not_exist( "0001", "学号不存在"),
    7. Insufficient_student_number( "0002", "学号长度不足"),
    8. Student_number_is_empty( "0003", "学号为空"),
    9. Network_error( "9999", "网络错误,待会重试"),
    10. ;
    11. private String code;
    12. private String msg;
    13. ErrorCodeAndMsg(String code, String msg) {
    14. this.code = code;
    15. this.msg = msg;
    16. }
    17. public String getCode() {
    18. return code;
    19. }
    20. public void setCode(String code) {
    21. this.code = code;
    22. }
    23. public String getMsg() {
    24. return msg;
    25. }
    26. public void setMsg(String msg) {
    27. this.msg = msg;
    28. }
    29. }

    9、创建统一异常处理类:StudentException

    
       
       
    1. package com.dl.cn.message.exception;
    2. import com.dl.cn.message.enums.ErrorCodeAndMsg;
    3. import java.io.Serializable;
    4. /**
    5. * 统一异常捕获类
    6. * Created by Tiger on 2018/10/9.
    7. */
    8. public class StudentException extends RuntimeException{
    9. private static final long serialVersionUID = - 6370612186038915645L;
    10. private final ErrorCodeAndMsg response;
    11. public StudentException(ErrorCodeAndMsg response) {
    12. this.response = response;
    13. }
    14. public ErrorCodeAndMsg getResponse() {
    15. return response;
    16. }
    17. }

    10、创建异常处理的全局配置类:ExceptionHandler

    
       
       
    1. package com.dl.cn.message.exception;
    2. import com.dl.cn.message.enums.ErrorCodeAndMsg;
    3. import com.dl.cn.message. response. Response;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.springframework.web.bind.annotation.ControllerAdvice;
    6. import org.springframework.web.bind.annotation.ResponseBody;
    7. import javax.servlet.http.HttpServletRequest;
    8. /**
    9. * Created by Tiger on 2018/ 10/ 9.
    10. */
    11. @ControllerAdvice
    12. @Slf4j
    13. public class ExceptionHandler {
    14. @org.springframework.web.bind.annotation.ExceptionHandler(StudentException. class)
    15. @ResponseBody
    16. public Response handleStudentException(HttpServletRequest request, StudentException ex) {
    17. Response response;
    18. log. error( "StudentException code:{},msg:{}",ex.getResponse().getCode(),ex.getResponse().getMsg());
    19. response = new Response(ex.getResponse().getCode(),ex.getResponse().getMsg());
    20. return response;
    21. }
    22. @org.springframework.web.bind.annotation.ExceptionHandler(Exception. class)
    23. @ResponseBody
    24. public Response handleException(HttpServletRequest request, Exception ex) {
    25. Response response;
    26. log. error( "exception error:{}",ex);
    27. response = new Response(ErrorCodeAndMsg.Network_error.getCode(),
    28. ErrorCodeAndMsg.Network_error.getMsg());
    29. return response;
    30. }
    31. }

    11、创建controler类:StudentInofController

    
       
       
    1. package com.dl.cn.message.controller;
    2. import com.dl.cn.message.enums.ErrorCodeAndMsg;
    3. import com.dl.cn.message.exception.StudentException;
    4. import com.dl.cn.message.response.Response;
    5. import com.dl.cn.message.service.StudentInfoService;
    6. import com.dl.cn.message.bean.StudentInfo;
    7. import lombok.extern.slf4j.Slf4j;
    8. import org.springframework.beans.factory. annotation.Autowired;
    9. import org.springframework.web.bind. annotation.PostMapping;
    10. import org.springframework.web.bind. annotation.RequestMapping;
    11. import org.springframework.web.bind. annotation.RequestParam;
    12. import org.springframework.web.bind. annotation.RestController;
    13. /**
    14. * Created by Tiger on 2018/10/8.
    15. */
    16. @RestController
    17. @RequestMapping("/student")
    18. @Slf4j
    19. public class StudentInofController {
    20. @Autowired
    21. StudentInfoService studentInfoService;
    22. /**
    23. * 保存学生信息
    24. * @param studentId
    25. * @param name
    26. * @param age
    27. * @param famillyAddress
    28. * */
    29. @PostMapping("/save")
    30. public void saveStudentInfo( @RequestParam("student_id") String studentId,
    31. @RequestParam("name") String name,
    32. @RequestParam("age") Integer age,
    33. @RequestParam("familly_address") String famillyAddress){
    34. StudentInfo studentInfo = StudentInfo.builder()
    35. .studentId(studentId)
    36. .name(name)
    37. .age(age)
    38. .famillyAddress(famillyAddress)
    39. .build();
    40. studentInfoService.saveStudentInfo(studentInfo);
    41. }
    42. /**
    43. * 根据学号查学生信息
    44. * @param studentId
    45. * @return
    46. * */
    47. @PostMapping("/findByStudentId")
    48. public Response findByStudentId( @RequestParam("student_id") String studentId){
    49. try{
    50. log.info( "Get student information based on student number:{}",studentId);
    51. if(studentId == null){
    52. throw new StudentException(ErrorCodeAndMsg.Student_number_is_empty);
    53. }
    54. //学号固定为8位
    55. if(studentId.length() != 8){
    56. throw new StudentException(ErrorCodeAndMsg.Insufficient_student_number);
    57. }
    58. StudentInfo studentInfo = studentInfoService.findByStudentId(studentId);
    59. if(studentInfo == null){
    60. throw new StudentException(ErrorCodeAndMsg.Student_number_does_not_exist);
    61. }
    62. return new Response(studentInfo);
    63. } catch (Exception e){
    64. if(e instanceof StudentException){
    65. throw e;
    66. } else {
    67. log.error( "findByStudentId error:",e);
    68. throw new StudentException(ErrorCodeAndMsg.Network_error);
    69. }
    70. }
    71. }
    72. @PostMapping("/updateFamillyAddress")
    73. public Response updateFamillyAddress( @RequestParam("student_id") String studentId,
    74. @RequestParam("familly_address") String famillyAddress){
    75. studentInfoService.updateFamillyAddress(studentId,famillyAddress);
    76. Response response = new Response();
    77. System. out.println(response.toString());
    78. return response;
    79. }
    80. }

    12、application.properties配置

    
       
       
    1. #redis
    2. spring.redis.host= 127.0 .0 .1
    3. spring.redis.port= 6379
    4. spring.redis.password=tiger
    5. #mybatis
    6. #开启mybatis驼峰命名,这样可以将mysql中带有下划线的映射成驼峰命名的字段
    7. mybatis.configuration.map-underscore-to-camel- case= true
    8. #datasource
    9. spring.datasource.url=jdbc:mysql: //127.0.0.1:3306/tiger?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&generateSimpleParameterMetadata=true
    10. spring.datasource.username=tiger
    11. spring.datasource.password=tiger
    12. spring.datasource.driver- class-name=com.mysql.jdbc.Driver
    13. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    14. spring.datasource.max-idle= 10
    15. spring.datasource.max-wait= 60000
    16. spring.datasource.min-idle= 5
    17. spring.datasource.initial-size= 5
    18. spring.datasource.validationQuery=select 'x'

    三、说明

    1、controller层使用注解@RestController,这样返回结果就是json格式,而@Controller返回结果是字符串

    2、throw 异常

    如果exception类型是自定义的异常StudentException,直接抛出,如果是其它异常统一抛出网络错误

    
       
       
    1. try{
    2. } catch ( Exception e){
    3. if(e instanceof StudentException){
    4. throw e;
    5. } else {
    6. log.error( "findByStudentId error:",e);
    7. throw new StudentException(ErrorCodeAndMsg.Network_error);
    8. }
    9. }

    3、在返回结果类添加了注解@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)

    是因为更新或者删除操作,一般没有返回值,我只需要知道是否更新成功或者删除成功就OK了,如果不加这个注解

    我们返回的结果中data为null!!!

    
       
       
    1. {
    2. "data": null,
    3. "code": "0000",
    4. "msg": "请求成功"
    5. }

    加上注解再更新数据,返回结果:

    
       
       
    1. {
    2. "code": "0000",
    3. "msg": "请求成功"
    4. }

    因此这个注解的作用就是:返回结果中有null值,干掉它!

    四、测试结果

    mysql数据库中有一条学号为13240115的数据:

    1、student_id = "13240115"时

    
       
       
    1. {
    2. "data": {
    3. "id": 1,
    4. "studentId": "13240115",
    5. "name": "Tiger",
    6. "age": 25,
    7. "famillyAddress": "北京",
    8. "createdDate": "2018-10-08T05:45:49.000+0000",
    9. "updatedDate": "2018-10-09T05:36:36.000+0000"
    10. },
    11. "code": "0000",
    12. "msg": "请求成功"
    13. }

    2、student_id = "13240114"时

    
       
       
    1. {
    2. "code": "0001",
    3. "msg": "学号不存在"
    4. }

    3、student_id = "1324011",不足8位时

    
       
       
    1. {
    2. "code": "0002",
    3. "msg": "学号长度不足"
    4. }

    4、student_id = "13240115",然后在接口中加上一行代码,System.out.println(1/0);

    返回结果:

    
       
       
    1. {
    2. "code": "9999",
    3. "msg": "网络错误,待会重试"
    4. }

    控制台日志:

    
       
       
    1. java.lang. ArithmeticException: / by zero
    2. at com.dl.cn.message.controller. StudentInofController.findByStudentId( StudentInofController.java: 54) ~[classes/:na]
    3. at sun. reflect. NativeMethodAccessorImpl.invoke0( Native Method) ~[na: 1.8. 0_161]
    4. at sun. reflect. NativeMethodAccessorImpl.invoke( NativeMethodAccessorImpl.java: 62) ~[na: 1.8. 0_161]
    5. at sun. reflect. DelegatingMethodAccessorImpl.invoke( DelegatingMethodAccessorImpl.java: 43) ~[na: 1.8. 0_161]
    6. at java.lang. reflect. Method.invoke( Method.java: 498) ~[na: 1.8. 0_161]
    7. at org.springframework.web.method.support. InvocableHandlerMethod.doInvoke( InvocableHandlerMethod.java: 209) [spring-web- 5.0. 8. RELEASE.jar: 5.0. 8. RELEASE]
    8. at org.springframework.web.method.support. InvocableHandlerMethod.invokeForRequest( InvocableHandlerMethod.java: 136) [spring-web- 5.0. 8. RELEASE.jar: 5.0. 8. RELEASE]

    通过测试,发现这个小案例满足刚开始我们提出的需求,一定还有很多其它问题,暂时没有发现,我会及时修改,不知道有人是否看我的博客?我只是想把自己的学习成果总结记录下来。人可以成长为芳草,也可以长成杂莠!!!

    原文地址:https://blog.csdn.net/qq_31289187/article/details/82980714

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-9-19 04:39 , Processed in 0.600589 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表