@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface RequestInitial {
Class<?>[] groups() default Group.All.class;
}
package com.heima.commons.groups;
public class Group {
/**
* 创建
*/
public interface Create {
}
/**
* 修改
*/
public interface Update {
}
/**
* 修改
*/
public interface Delete {
}
/**
* 查询
*/
public interface Select {
}
/**
* 所有条件
*/
public interface All {
}
}
public interface VO {
Class getPO();
}
package com.heima.modules.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.heima.commons.constant.HtichConstants;
import com.heima.commons.domin.vo.VO;
import com.heima.commons.enums.InitialResolverType;
import com.heima.commons.groups.Group;
import com.heima.commons.initial.annotation.InitialResolver;
import com.heima.modules.po.AccountPO;
import javax.validation.constraints.NotEmpty;
import java.util.Date;
public class AccountVO implements VO {
/**
* 主键
*/
@InitialResolver(resolver = InitialResolverType.GEN_SNOWFLAKE_ID, groups = {Group.Create.class})
@NotEmpty(message = "ID不能为空", groups = {Group.Update.class})
private String id;
/**
* 用户名
*/
@NotEmpty(message = "用户名不能为空", groups = {Group.Create.class, Group.Select.class})
private String username;
/**
* 用户姓名
*/
private String useralias;
/**
* 当前登录用户
*/
@InitialResolver(resolver = InitialResolverType.CURRENTA_ACCOUNT, groups = {Group.All.class})
private String currentUserId;
/**
* 密码
*/
@NotEmpty(message = "密码不能为空", groups = {Group.Create.class, Group.Select.class})
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
/**
* 新密码 用户密码修改用
*/
private String newPassword;
/**
* 手机号码
*/
@NotEmpty(message = "手机号码不能为空", groups = {Group.Create.class})
private String phone;
/**
* 角色 乘客:1司机:2
*/
private Integer role;
/**
* 用户头像
*/
@InitialResolver(resolver = InitialResolverType.DEF_VALUE, groups = {Group.Create.class}, def = HtichConstants.ACCOUNT_DEFAULT_AVATAR)
private String avatar;
/**
* 状态 禁用:0
* 正常:1
*/
private Integer status;
/**
* 乐观锁
*/
private Integer revision;
/**
* 创建人
*/
@InitialResolver(resolver = InitialResolverType.CURRENTA_ACCOUNT, groups = {Group.Create.class})
private String createdBy;
/**
* 创建时间
*/
@InitialResolver(resolver = InitialResolverType.CURRENT_DATE, groups = {Group.Create.class})
private Date createdTime;
/**
* 更新人
*/
@InitialResolver(resolver = InitialResolverType.CURRENTA_ACCOUNT, groups = {Group.Update.class})
private String updatedBy;
/**
* 更新时间
*/
@InitialResolver(resolver = InitialResolverType.CURRENT_DATE, groups = {Group.Update.class})
private Date updatedTime;
private String token;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUseralias() {
return useralias;
}
public void setUseralias(String useralias) {
this.useralias = useralias;
}
public String getCurrentUserId() {
return currentUserId;
}
public void setCurrentUserId(String currentUserId) {
this.currentUserId = currentUserId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNewPassword() {
return newPassword;
}
public void setNewPassword(String newPassword) {
this.newPassword = newPassword;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getRole() {
return role;
}
public void setRole(Integer role) {
this.role = role;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getRevision() {
return revision;
}
public void setRevision(Integer revision) {
this.revision = revision;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
public Date getUpdatedTime() {
return updatedTime;
}
public void setUpdatedTime(Date updatedTime) {
this.updatedTime = updatedTime;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@JsonIgnore
@Override
public Class getPO() {
return AccountPO.class;
}
}
package com.heima.modules.po;
import com.heima.commons.domin.po.PO;
import com.heima.modules.vo.AccountVO;
import java.io.Serializable;
import java.util.Date;
public class AccountPO implements Serializable, PO {
public AccountPO() {
}
public AccountPO(String accountId) {
this.id = accountId;
}
/**
* 主键
*/
private String id;
/**
* 用户名
*/
private String username;
/**
* 用户姓名
*/
private String useralias;
/**
* 密码
*/
private String password;
/**
* 手机号码
*/
private String phone;
/**
* 角色 乘客:1司机:2
*/
private Integer role;
/**
* 用户头像
*/
private String avatar;
/**
* 状态 禁用:0
* 正常:1
*/
private Integer status;
/**
* 乐观锁
*/
private Integer revision;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updatedBy;
/**
* 更新时间
*/
private Date updatedTime;
/**
* t_account
*/
private static final long serialVersionUID = 1L;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username == null ? null : username.trim();
}
public String getUseralias() {
return useralias;
}
public void setUseralias(String useralias) {
this.useralias = useralias == null ? null : useralias.trim();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone == null ? null : phone.trim();
}
public Integer getRole() {
return role;
}
public void setRole(Integer role) {
this.role = role;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar == null ? null : avatar.trim();
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getRevision() {
return revision;
}
public void setRevision(Integer revision) {
this.revision = revision;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy == null ? null : createdBy.trim();
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
}
public Date getUpdatedTime() {
return updatedTime;
}
public void setUpdatedTime(Date updatedTime) {
this.updatedTime = updatedTime;
}
@Override
public Class getVO() {
return AccountVO.class;
}
}
package com.heima.commons.enums;
import com.heima.commons.initial.realize.CurrentDateInitialParser;
import com.heima.commons.initial.realize.CurrentUserInitialParser;
import com.heima.commons.initial.realize.DefaultValueInitialParser;
import com.heima.commons.initial.realize.SnowflakeIDInitialParser;
public enum InitialResolverType {
CURRENT_DATE("CURRENT_DATE", CurrentDateInitialParser.class),
CURRENTA_ACCOUNT("CURRENTA_ACCOUNT", CurrentUserInitialParser.class),
GEN_SNOWFLAKE_ID("GEN_SNOWFLAKE_ID", SnowflakeIDInitialParser.class),
DEF_VALUE("DEF_VALUE", DefaultValueInitialParser.class);
InitialResolverType(String resolverName, Class resolverClass) {
this.resolverName = resolverName;
this.resolverClass = resolverClass;
}
//错误码
private String resolverName;
//具体错误信息
private Class resolverClass;
public String getResolverName() {
return resolverName;
}
public void setResolverName(String resolverName) {
this.resolverName = resolverName;
}
public Class getResolverClass() {
return resolverClass;
}
public void setResolverClass(Class resolverClass) {
this.resolverClass = resolverClass;
}
}
package com.heima.commons.initial;
import com.heima.commons.initial.annotation.InitialResolver;
public interface InitialParser {
boolean isMatch(Class clazz);
Object getDefaultValue(Class clazz, InitialResolver initialResolver);
}
package com.heima.commons.initial.realize;
import com.heima.commons.initial.InitialParser;
import com.heima.commons.initial.annotation.InitialResolver;
import com.heima.commons.utils.SnowflakeIdWorker;
/**
* 雪花ID生成器
*/
public class SnowflakeIDInitialParser implements InitialParser {
SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(10, 11);
@Override
public boolean isMatch(Class clazz) {
return clazz.isAssignableFrom(String.class);
}
@Override
public Object getDefaultValue(Class clazz, InitialResolver initialResolver) {
return String.valueOf(snowflakeIdWorker.nextId());
}
}
SnowflakeIdWorker ...
@ApiOperation(value = "用户注册接口", tags = {"账户管理"})
@PostMapping("/register")
@RequestInitial(groups = {Group.Create.class})
public ResponseVO<AccountVO> register(@Validated(Group.Create.class) @RequestBody AccountVO accountVO) {
return accountHandler.register(accountVO);
}
/**
* 启动参数初始化功能
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import(RequestInitialAspect.class)
@Documented
public @interface EnableRequestInital {
}
package com.heima.commons.initial.annotation;
import com.heima.commons.enums.InitialResolverType;
import com.heima.commons.groups.Group;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
@Documented
public @interface InitialResolver {
InitialResolverType resolver();
Class<?>[] groups() default Group.All.class;
//默认值
String def() default "";
}
package com.heima.commons.initial.aspect;
import com.heima.commons.initial.annotation.RequestInitial;
import com.heima.commons.initial.factory.InitialParserFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Aspect
public class RequestInitialAspect {
@Autowired
private HttpServletRequest request;
@Pointcut("@annotation(com.heima.commons.initial.annotation.RequestInitial)")
public void annotationPoinCut() {
}
@Around("annotationPoinCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
RequestInitial requestInitial = getRequestInitial(pjp);
Object[] parameterValues = pjp.getArgs();
if (null != requestInitial) {
//拦截后给属性赋值
InitialParserFactory.initialDefValue(parameterValues, requestInitial);
}
return pjp.proceed(parameterValues);
}
private RequestInitial getRequestInitial(ProceedingJoinPoint pjp) {
MethodSignature signature = (MethodSignature) pjp.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
return method.getAnnotation(RequestInitial.class);
}
}
package com.heima.commons.initial.factory;
import com.heima.commons.domin.po.PO;
import com.heima.commons.domin.vo.VO;
import com.heima.commons.groups.Group;
import com.heima.commons.initial.InitialParser;
import com.heima.commons.initial.annotation.InitialResolver;
import com.heima.commons.initial.annotation.RequestInitial;
import com.heima.commons.utils.CommonsUtils;
import com.heima.commons.utils.reflect.ReflectUtils;
import com.heima.commons.utils.reflect.wrap.WrapObject;
import com.heima.commons.utils.reflect.wrap.WrapObjectFactory;
import com.heima.commons.utils.reflect.wrap.WrapProperty;
import org.apache.commons.collections4.CollectionUtils;
import java.lang.annotation.Annotation;
import java.util.Arrays;
public class InitialParserFactory {
public static PO initialDefValueForPO(PO po) {
Object vo = ReflectUtils.newInstance(po.getVO());
initialDefValue(vo, Group.All.class);
return CommonsUtils.toPO((VO) vo);
}
public static void initialDefValueForVO(VO vo) {
initialDefValue(vo, Group.All.class);
}
public static void initialDefValue(Object[] objArray, RequestInitial requestInitial) {
if (null != objArray && objArray.length > 0) {
for (Object obj : objArray) {
if (obj instanceof VO) {
//request可能有多个入参,只对VO类赋值
initialDefValue(obj, requestInitial);
}
}
}
}
public static void initialDefValue(Object obj, RequestInitial requestInitial) {
initialDefValue(obj, requestInitial.groups());
}
public static void initialDefValue(Object obj, Class<?>... groups) {
//Wrapper赋值工具
WrapObject wrapObject = WrapObjectFactory.getWarpObject(obj);
InitialParserFactory initialParserFactory = new InitialParserFactory();
for (WrapProperty property : wrapObject.getPropertyList()) {
Object value = wrapObject.getValue(property.getPropName());
if (null != value) {
//属性有值的话,跳过
continue;
}
//从VO的中拿到Resolver注解定义的生成器
InitialResolver initialResolver = getInitialResolver(property);
if (initialResolver == null) {
continue;
}
//判断注解的group信息,resolver和controller匹配上就反射生成resolver(属性值生成器)
InitialParser initialParser = initialParserFactory.getInitialParser(property, initialResolver, groups);
if (null != initialParser && initialParser.isMatch(property.getDataType())) {
//获取值,通过wrapper工具赋值上去(反射)。
wrapObject.setValue(property.getPropName(), initialParser.getDefaultValue(property.getDataType(), initialResolver));
}
}
}
public static InitialResolver getInitialResolver(WrapProperty property) {
Annotation[] annotations = property.getAnnotations();
return getInitialResolverAnnotation(annotations);
}
public static InitialParser getInitialParser(WrapProperty wrapProperty, InitialResolver initialResolver, Class[] groups) {
Class<?>[] groupArray = initialResolver.groups();
if (groupArray == null || groups == null) {
return null;
}
if (groupArray.length == 0 || groups.length == 0) {
return null;
}
boolean flag = false;
if (groups[0] == Group.All.class) {
flag = true;
} else {
flag = CollectionUtils.containsAny(Arrays.asList(groupArray), groups);
}
return flag ? ReflectUtils.newInstance(initialResolver.resolver().getResolverClass()) : null;
}
private static InitialResolver getInitialResolverAnnotation(Annotation[] annotations) {
if (null != annotations && annotations.length > 0) {
for (Annotation annotation : annotations) {
if (annotation instanceof InitialResolver) {
return (InitialResolver) annotation;
}
}
}
return null;
}
}
package com.heima.commons.utils.reflect;
import com.heima.commons.utils.reflect.wrap.WrapObject;
import com.heima.commons.utils.reflect.wrap.WrapObjectFactory;
import com.heima.commons.utils.reflect.wrap.WrapProperty;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ReflectUtils {
public static <T> T newInstance(Class clazz) {
Object value = null;
try {
value = clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return (T) value;
}
}
package com.heima.commons.utils;
import com.heima.commons.domin.po.PO;
import com.heima.commons.domin.vo.VO;
import com.heima.commons.utils.reflect.ReflectUtils;
import com.heima.commons.valuation.BasicValuation;
import com.heima.commons.valuation.FuelCostValuation;
import com.heima.commons.valuation.StartPriceValuation;
import com.heima.commons.valuation.Valuation;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.NumberFormat;
import java.util.*;
public class CommonsUtils {
public static <T> T toPO(VO vo) {
PO po = ReflectUtils.newInstance(vo.getPO());
BeanUtils.copyProperties(vo, po);
return (T) po;
}
}
public class WrapObjectFactory {
private static final Map<Class, WrapClass> wrapClassMap = new ConcurrentHashMap<>();
public static WrapObject getWarpObject(Object orginObject) {
WrapClass wrapClass = getClass(orginObject.getClass());
return new WrapObject(orginObject, wrapClass);
}
private static WrapClass getClass(Class clazz) {
return wrapClassMap.computeIfAbsent(clazz, k -> new WrapClass(k));
}
}
package com.heima.commons.utils.reflect.wrap;
import com.heima.commons.utils.reflect.ReflectUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class WrapClass {
private Class classType;
private Map<String, WrapProperty> propertyMap = new ConcurrentHashMap<>();
private Map<String, Field> fieldMap = new ConcurrentHashMap<>();
public WrapClass(Class clazz) {
this.classType = clazz;
List<Field> fieldList = ReflectUtils.getFieldList(clazz);
fieldList.forEach(field -> addField(field));
List<WrapProperty> propertyList = ReflectUtils.getWrapPropertyList(clazz);
propertyList.forEach(prop -> addProperty(prop));
}
private void addProperty(WrapProperty prop) {
if (!propertyMap.containsKey(prop.getPropName())) {
Annotation[] annotations = ReflectUtils.getAnnotations(fieldMap.get(prop.getPropName()));
prop.setAnnotations(annotations);
propertyMap.put(prop.getPropName(), prop);
}
}
private void addField(Field field) {
if (!fieldMap.containsKey(field.getName())) {
fieldMap.put(field.getName(), field);
}
}
public WrapProperty getProperty(String propName) {
return propertyMap.get(propName);
}
public Class getClassType() {
return classType;
}
public Map<String, WrapProperty> getPropertyMap() {
return propertyMap;
}
public Map<String, Field> getFieldMap() {
return fieldMap;
}
}
package com.heima.commons.utils.reflect.wrap;
import java.util.Collection;
public class WrapObject {
private WrapClass wrapClass;
private Object originalData;
public WrapObject(Object originalData, WrapClass wrapClass) {
if (originalData == null) {
throw new IllegalArgumentException("参数不能为空");
}
this.originalData = originalData;
this.wrapClass = wrapClass;
}
public Object getValue(String propName) {
WrapProperty meateProp = wrapClass.getProperty(propName);
if (null == meateProp) {
return null;
}
return meateProp.getValue(originalData);
}
public Object setValue(String propName, Object... args) {
WrapProperty meateProp = wrapClass.getProperty(propName);
if (null == meateProp) {
return null;
}
return meateProp.setValue(originalData, args);
}
public WrapProperty getProperty(String key) {
return wrapClass.getPropertyMap().get(key);
}
public Collection<WrapProperty> getPropertyList() {
return wrapClass.getPropertyMap().values();
}
}
package com.heima.commons.utils.reflect.wrap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class WrapObjectFactory {
private static final Map<Class, WrapClass> wrapClassMap = new ConcurrentHashMap<>();
public static WrapObject getWarpObject(Object orginObject) {
WrapClass wrapClass = getClass(orginObject.getClass());
return new WrapObject(orginObject, wrapClass);
}
private static WrapClass getClass(Class clazz) {
return wrapClassMap.computeIfAbsent(clazz, k -> new WrapClass(k));
}
}
package com.heima.commons.utils.reflect.wrap;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 元数据属性
*/
public class WrapProperty {
private String propName;
private Class dataType;
private Method readMethod;
private Method writeMethod;
private Annotation[] annotations;
public WrapProperty(PropertyDescriptor propertyDescriptor) {
this.propName = propertyDescriptor.getName();
this.dataType = propertyDescriptor.getPropertyType();
this.readMethod = propertyDescriptor.getReadMethod();
this.writeMethod = propertyDescriptor.getWriteMethod();
}
public Object getValue(Object originalData) {
if (null == readMethod) {
return null;
}
try {
return readMethod.invoke(originalData);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public boolean setValue(Object originalData, Object... args) {
boolean isSuccess = false;
if (null == writeMethod) {
return isSuccess;
}
try {
writeMethod.invoke(originalData, args);
isSuccess = true;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return isSuccess;
}
public String getPropName() {
return propName;
}
public void setPropName(String propName) {
this.propName = propName;
}
public Class getDataType() {
return dataType;
}
public void setDataType(Class dataType) {
this.dataType = dataType;
}
public Method getReadMethod() {
return readMethod;
}
public void setReadMethod(Method readMethod) {
this.readMethod = readMethod;
}
public Method getWriteMethod() {
return writeMethod;
}
public void setWriteMethod(Method writeMethod) {
this.writeMethod = writeMethod;
}
public void setAnnotations(Annotation[] annotations) {
this.annotations = annotations;
}
public Annotation[] getAnnotations() {
return annotations;
}
}