diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/annotation/DoNotDeserialize.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/annotation/DoNotDeserialize.java new file mode 100644 index 0000000..bd59a2d --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/annotation/DoNotDeserialize.java @@ -0,0 +1,19 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.annotation; + +import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 用于{@link BeanUtils#beanToMap(Object, boolean, boolean)}时,当成员变量被标注本注释时,就不会被该方法放入Map + * + * @author 佘语殊 + * @since 2022/6/28 21:42 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface DoNotDeserialize { +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java index 2557085..c38e33d 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java @@ -14,6 +14,6 @@ public class Staff { private Integer staffId; private String staffUsername; private String staffPassword; - private String staffNickname; + private String staffFullname; private String staffGender; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/BeanUtils.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/BeanUtils.java new file mode 100644 index 0000000..37c2a54 --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/BeanUtils.java @@ -0,0 +1,83 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.utils; + +import cn.edu.hfut.rmdjzz.projectmanagement.annotation.DoNotDeserialize; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * @author 佘语殊 + * @since 2022/6/28 21:41 + */ +public class BeanUtils { + /** + * 将bean转成map,被标注{@link DoNotDeserialize}注释的变量会被跳过 + * + * @param putNulls 是否将值为null的变量也放入结果map + * @param toUnderline 是否将变量命名转为下划线型 + */ + public static Map beanToMap(Object object, boolean toUnderline, boolean putNulls) { + Map map = new HashMap<>(); + if (object == null) { + return map; + } + Field[] fields = object.getClass().getDeclaredFields(); + Class clazz = object.getClass(); + for (Field field : fields) { + String fieldName = field.getName(); + if (fieldName.equals("serialVersionUID") || field.getAnnotation(DoNotDeserialize.class) != null) { + continue; + } + String key = toUnderline ? StringUtils.camelToUnderline(fieldName) : fieldName; + try { + PropertyDescriptor pd = new PropertyDescriptor(fieldName, clazz); + Method method = pd.getReadMethod(); + Object value = method.invoke(object); + if (putNulls || value != null) { + map.put(key, value); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return map; + } + + public static Map beanToMap(Object object, boolean toUnderline) { + return beanToMap(object, toUnderline, true); + } + + public static Map beanToMap(Object object) { + return beanToMap(object, true, true); + } + + /** + * 检查是否objects全都非null + * @return 都非null则true,否则false + */ + public static boolean checkAllNotNull(Object... objects) { + for (Object object : objects) { + if (object == null) { + return false; + } + } + return true; + } + + /** + * 检查是否objects含有非null + * @return 有则true,否则false + */ + public static boolean checkAnyNotNull(Object... objects) { + for (Object object : objects) { + if (object != null) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/ResponseEntity.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseList.java similarity index 50% rename from src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/ResponseEntity.java rename to src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseList.java index 100011a..7c72c1f 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/ResponseEntity.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseList.java @@ -1,44 +1,62 @@ -package cn.edu.hfut.rmdjzz.projectmanagement.entity; +package cn.edu.hfut.rmdjzz.projectmanagement.utils.response; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; +import org.springframework.http.HttpStatus; import java.util.*; import java.util.stream.Collectors; /** - * 用于包装响应体的实体类,静态调用用of方法实例化对象,例:
- * {@code return ResponseEntity.of(HttpStatus.OK.value(),"查询成功!",result);} + * 用于包装响应体、返回列表型数据的实体类,静态调用用of方法实例化对象,例:
+ * {@code return ResponseList.of(HttpStatus.OK.value(),"查询成功!",result);} + * * @author 佘语殊 * @since 2022/6/28 11:59 */ @SuppressWarnings({"unchecked", "varargs"}) @Data @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class ResponseEntity { +public class ResponseList { private Integer code; private String msg; private QueryPage data; /** - * 静态构造函数 - * @param 数据类型 + * 静态构造函数,data可以不填,最终会构造一个total为0,records为空列表的data + * + * @param 数据类型 * @param code 响应码 - * @param msg 响应消息 + * @param msg 响应消息 * @param data 响应数据 */ - public static ResponseEntity of(Integer code, String msg, T... data) { - return new ResponseEntity<>(code, msg, new QueryPage<>(data)); + public static ResponseList of(Integer code, String msg, T... data) { + return new ResponseList<>(code, msg, new QueryPage<>(data)); } - public static ResponseEntity of(Integer code, String msg, Collection data) { - return new ResponseEntity<>(code, msg, new QueryPage<>(data)); + public static ResponseList of(Integer code, String msg, Collection data) { + return new ResponseList<>(code, msg, new QueryPage<>(data)); } - public static ResponseEntity of(Integer code, String msg, Page data) { - return new ResponseEntity<>(code, msg, new QueryPage<>(data)); + public static ResponseList of(Integer code, String msg, Page data) { + return new ResponseList<>(code, msg, new QueryPage<>(data)); + } + + /** + * 直接构造成功响应体 + */ + public static ResponseList ofSuccess(String msg, T... data) { + return of(HttpStatus.OK.value(), msg, data); + } + + public static ResponseList ofSuccess(String msg, Collection data) { + return of(HttpStatus.OK.value(), msg, data); + } + + public static ResponseList ofSuccess(String msg, Page data) { + return of(HttpStatus.OK.value(), msg, data); } /** @@ -69,7 +87,7 @@ public class ResponseEntity { } } - QueryPage(T[] data) { + QueryPage(T... data) { //筛掉所有null this.records = Arrays.stream(data).filter(Objects::nonNull).collect(Collectors.toList()); this.total = (long) records.size(); diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java new file mode 100644 index 0000000..155c375 --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/response/ResponseMap.java @@ -0,0 +1,103 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.utils.response; + +import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.core.serializer.support.SerializationFailedException; +import org.springframework.http.HttpStatus; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * 用于包装响应体,在data中返回一个json,静态调用用of或ofSuccess方法实例化对象,可以用put或putIgnoreNull方法链式构造响应体中的Map + * + * @author 佘语殊 + * @since 2022/6/28 21:29 + */ +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Data +public class ResponseMap { + private Integer code; + private String msg; + private Map data; + + /** + * 静态构造方法 + * + * @param code 响应码 + * @param msg 响应信息 + * @param data 响应数据,不可以是Collection或Page,否则报错 + */ + public static ResponseMap of(Integer code, String msg, Object data) { + if (data == null) { + return new ResponseMap(code, msg, new HashMap<>()); + } + if (data instanceof Collection || data instanceof Page) { + throw new SerializationFailedException("在使用集合类时请使用ResponseList而不是ResponseMap!"); + } + if (data instanceof Map mapData) { + return of(code, msg, mapData, true); + } + return new ResponseMap(code, msg, BeanUtils.beanToMap(data, false)); + } + + /** + * @param putNulls 若为false,则构造map时跳过null值 + */ + public static ResponseMap of(Integer code, String msg, Map data, boolean putNulls) { + ResponseMap responseMap = new ResponseMap(code, msg, new HashMap<>()); + if (data == null) { + return responseMap; + } + data.forEach((key, value) -> { + if (putNulls || value != null) { + responseMap.put(String.valueOf(key), value); + } + }); + return responseMap; + } + + /** + * 空静态构造方法 + */ + public static ResponseMap of(Integer code, String msg) { + return new ResponseMap(code, msg, new HashMap<>()); + } + + /** + * 直接构建成功响应体 + */ + public static ResponseMap ofSuccess(String msg, Object data) { + return of(HttpStatus.OK.value(), msg, data); + } + + public static ResponseMap ofSuccess(String msg, Map data, boolean putNulls) { + return of(HttpStatus.OK.value(), msg, data, putNulls); + } + + public static ResponseMap ofSuccess(String msg) { + return of(HttpStatus.OK.value(), msg); + } + + /** + * 可以链式构造包装类里的Map + */ + public ResponseMap put(String key, Object value) { + data.put(key, value); + return this; + } + + /** + * 当value为null时,不put到map中 + */ + public ResponseMap putIgnoreNull(String key, Object value) { + if (value != null) { + data.put(key, value); + } + return this; + } +} diff --git a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java index 08c4ca4..7764c52 100644 --- a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java +++ b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java @@ -1,6 +1,9 @@ package cn.edu.hfut.rmdjzz.projectmanagement; -import cn.edu.hfut.rmdjzz.projectmanagement.service.impl.StaffServiceImpl; +import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; +import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService; +import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import org.junit.jupiter.api.Test; @@ -16,13 +19,17 @@ import javax.annotation.Resource; public class MybatisPlusTests { @Resource - StaffServiceImpl staffService; + private IStaffService staffService; @Resource private ObjectMapper objectMapper; @SneakyThrows @Test public void test() { - System.out.println(objectMapper.writeValueAsString(staffService.list())); + System.out.println(objectMapper.writeValueAsString( + ResponseMap.ofSuccess("ok", + staffService.getOne(Wrappers.query().last("limit 1")) + ) + )); } }