SpringBoot使用注解的方式统一返回接口结果集

1.创建一个Result类,包含返回的状态码,返回提示消息和数据结果


```java
package com.dyzwj.zwjsharding.entity;
 
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.io.Serializable;
 
/**
 * @Title: Result
 * @Description: 接口返回集
 * @Company: caixun
 * @Author: zhengtonghui
 * @Create: Date:2021年08月10日
 */
// 成功结果实体
@Data
public class Result implements Serializable {
 
    private Integer code;
    private String message;
    private T data;
 
    public void setResultCode(ResultCode resultCode) {
        this.code = resultCode.code();
    }
 
    public static Result success() {
        Result result = new Result();
        result.setResultCode(ResultCode.SUCCESS);
        return result;
    }
 
    public static Result success(T data) {
        Result result = new Result();
        result.setResultCode(ResultCode.SUCCESS);
        result.setCode(ResultCode.SUCCESS.code());
        result.setMessage(ResultCode.SUCCESS.message());
        result.setData(data);
        return result;
    }
 
    public static Result failure(Integer code, String message) {
        Result result = new Result();
        result.setCode(code);
        result.setMessage(message);
        return result;
    }
}

 
 2.创建结果状态码枚举类

```java
package com.dyzwj.zwjsharding.entity;
 
/**
 * @Title: ResultCode
 * @Description: 接口状态码
 * @Company: caixun
 * @Author: ChenCanWen
 * @Create: Date:2021年08月10日
 */
public enum ResultCode {
    /*成功状态码*/
    SUCCESS(1, "成功"),
    SYSTEM_ERROR(400, "系统繁忙,请稍后重试"),
    /*参数错误: 1001-1999 */
    PARAM_IS_INVALID(1001, "参数无效"),
    PARAM_IS_BLANK(1002, "参数为空"),
    PARAM_TYPE_BIND_ERROR(1003, "参数类型错误"),
    PARAM_NOT_COMPLETE(1004, "参数缺失"),
    /*用户错误: 2001-2999*/
    USER_NOT_LOGGED_IN(2001, "用户未登录,访问的路径需要验证,请登录"),
    USER_LOGIN_ERROR(2002, "账号不存在或密码错误"),
    USER_ACCOUNT_FORBIDDEN(2003, "账号已被禁用"),
    USER_NOT_EXIST(2004, "用户不存在"),
    USER_HAS_EXISTED(2005, "用户已存在");
 
    private Integer code;
    private String message;
 
    ResultCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
 
    public Integer code() {
        return this.code;
    }
 
    public String message(){
        return this.message;
    }
}

3.错误结果集

package com.concom.domain;
 
import lombok.Data;
 
// 错误结果实体
@Data
public class ErrorResult {
    private Integer code;
    private String message;
 
    public ErrorResult(Integer code, String message){
        this.code = code;
        this.message = message;
    }
}
 

4.创建注解类

package com.dyzwj.zwjsharding.annotation;
 
import java.lang.annotation.*;
 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface ResponseResult {
}

5.创建切面类

package com.dyzwj.zwjsharding.aop;
 
import com.dyzwj.zwjsharding.annotation.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
 
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
 
@Aspect
@Component
@Slf4j
public class ResponseResultAop {
    private static final String RESPONSE_RESULT_ANNO = "RESPONSE_RESULT_ANNO";
 
    //@Around("@within(com.dyzwj.zwjsharding.annotation.ResponseResult)")//这个切点表达式只作用在类上
    @Around("@annotation(com.dyzwj.zwjsharding.annotation.ResponseResult)")//这个切点表达式的作用只用在方法上
    public Object processAop(ProceedingJoinPoint joinPoint)  {
        Object result = null;
        try {
            log.info("开始切入");
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Class<?> clazz = joinPoint.getTarget().getClass();
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            if (clazz.isAnnotationPresent(ResponseResult.class)) {
                request.setAttribute(RESPONSE_RESULT_ANNO, clazz.getAnnotation(ResponseResult.class));
            }else if (method.isAnnotationPresent(ResponseResult.class)) {
                request.setAttribute(RESPONSE_RESULT_ANNO, method.getAnnotation(ResponseResult.class));
            }
            result = joinPoint.proceed();
            log.info("目标方法执行完成");
        } catch (Throwable e) {
            log.error("切面执行出错,原因是:{}", e);
        }
        return result;
    }
}
  1. 写一个类继承ResponseBodyAdvice重写supports()和beforeBodyWrire()方法,该类需要使用@RestControllerAdvice注解和@RestControllerAdvice注解,并将其放入IOC容器交给spring进行管理,这个类就是在将数据返回给DispathchServlet对视图进行渲渲染前对body进行重写,当supports方法返回true的时候,该方法才会去执行beforeBodyWrite()方法,对返回的body进行重写
package com.dyzwj.zwjsharding.handler;
 
import com.dyzwj.zwjsharding.annotation.ResponseResult;
import com.dyzwj.zwjsharding.entity.ErrorResult;
import com.dyzwj.zwjsharding.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
 
import javax.servlet.http.HttpServletRequest;
 
@Component
@Slf4j
@RestControllerAdvice
public class ResponseResultAdvice implements ResponseBodyAdvice<Object> {
    private static final String RESPONSE_RESULT_ANNO="RESPONSE_RESULT_ANNO";
    /**
     * 获取请求中是否有包装注解标记,没有直接返回,如果有则需要重写返回体
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        // 获取请求是否有包装标记
        ResponseResult responseResultAnn = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANNO);
        return responseResultAnn == null ? false : true;
    }
 
    /**
     * 重写返回体
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
        log.info("进入返回体处理");
        if (body instanceof ErrorResult) {
            ErrorResult errorResult = (ErrorResult) body;
            return Result.failure(errorResult.getCode(), errorResult.getMessage());
        }
        return Result.success(body);
    }
 
}

7.控制器,用来发送请求,调用业务层获取数据,注意自定义注解是用在类上还是用在方法上,如果用在类上的话,则aop中的切点表达式使用的是@Around(@within(“xxx.xx.class”)),如果用在方法上则切点表达式为@Around(@annotation(“xxxx.xxx.class”))

package com.dyzwj.zwjsharding.controller;
 
import com.dyzwj.zwjsharding.annotation.ResponseResult;
import com.dyzwj.zwjsharding.entity.User;
import com.dyzwj.zwjsharding.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
 
import java.util.List;
 
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;
 
    @GetMapping(value = "/findAll")
    @ResponseResult
    public List<User> findAll() {
        return userService.findAll();
    }
 
    @GetMapping(value = "/findById/{id}")
    public User listUserByID(@PathVariable("id") long id) {
       return userService.findById(id);
    }
 
    @PostMapping(value = "/saveOrUpdate")
    public boolean updateOrInsertUser(@RequestBody User user) {
        if (user == null) {
            log.info("参数不对:{}", user);
        }
        User user1 = userService.findById(user.getId());
        if(user1!=null) {
            return userService.updateUser(user);
        }else{
            return userService.saveUser(user);
        }
    }
    @DeleteMapping(value = "/deleteUser/{id}")
    public int deleteUser(@PathVariable("id")long id){
        return userService.deleteUser(id);
    }
    @GetMapping(value = "/getAll")
    public List<User> getAll(){
        return userService.list();
    }
}

8.业务接口层

package com.dyzwj.zwjsharding.service;
 
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dyzwj.zwjsharding.entity.User;
import com.dyzwj.zwjsharding.exception.CustomException;
 
import java.util.List;
 
public interface UserService extends IService<User> {
    List<User> findAll();
 
    User findById(long id) throws CustomException;
 
    boolean updateUser(User user);
 
    boolean saveUser(User user);
 
    int deleteUser(long id);
}

9.业务实现类

package com.dyzwj.zwjsharding.service.impl;
 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dyzwj.zwjsharding.entity.User;
import com.dyzwj.zwjsharding.exception.CustomException;
import com.dyzwj.zwjsharding.mapper.UserMapper;
import com.dyzwj.zwjsharding.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.List;
 
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public List<User> findAll() {
        return userMapper.selectAll();
    }
 
    @Override
    public User findById(long id) throws CustomException{
        if(id==0){
            throw new CustomException("id不能为0");
        }
        return userMapper.findById(id);
    }
 
    @Override
    public boolean updateUser(User user) {
        return userMapper.updateUser(user);
    }
 
    @Override
    public boolean saveUser(User user) {
        return userMapper.saveUser(user);
    }
 
    @Override
    public int deleteUser(long id) {
        return userMapper.deleteById(id);
    }
 
}

10.数据访问层

package com.dyzwj.zwjsharding.mapper;
 
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dyzwj.zwjsharding.entity.User;
import org.apache.ibatis.annotations.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Repository;
 
import java.util.List;
 
@Repository
public interface UserMapper extends BaseMapper<User> {
 
 
    @Insert("insert into t_user(nickname,password,age,sex,birthday) values(#{nickname},#{password},#{age},#{sex},#{birthday})")
    int insert(User user);
 
    @Delete("delete from t_user")
    int delete();
 
 
    @Select("select * from t_user")
    List<User> selectAll();
 
    @Select("select * from t_user where id=#{id}")
    User findById(long id);
 
    @Update("update t_user set nickname=#{nickname},password=#{password},age=#{age},sex=#{sex},birthday=now() where id=#{id}")
    boolean updateUser(User user);
 
    @Insert("insert into t_user(nickname,password,age,sex,birthday) values(#{nickname},#{password},#{age},#{sex},#{birthday})")
    boolean saveUser(User user);
}

11.访问结果 ,数据比较多,暂未截完整图

12.实体类

package com.dyzwj.zwjsharding.entity;
 
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
 
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
 
@Data
@TableName(value = "t_user")
public class User {
 
    private long id;
    private String nickname;
    private String password;
    private Integer age;
    private Integer sex;
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date birthday;
}

13.依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--  MySQL 驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <!--  Sharding-JDBC  -->
 
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

14.配置application.propertis文件

server:
  port: 8089
spring:
  application:
    name: boot-student
  datasource:
    url: jdbc:mysql://localhost:3306/db3?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: west151211
mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  type-aliases-package: com.concom.domain
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启SQL语句打印

15.SQL语句

CREATE TABLE `t_user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(20) DEFAULT NULL,
  `user_sex` varchar(6) DEFAULT NULL,
  `user_age` int(10) DEFAULT NULL,
  `user_telphone` varchar(11) DEFAULT NULL,
  `login_time` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

你可能感兴趣的:(spring,boot,java,后端)