项目之初设计不足, 系统后台时间格设计了两种格式进行存储,开发选择后确定。
1:long的时间戳;
2:date格式存储数据库timestamp 。
在开发过程中,开发人员选择了2
开发中的时间格式设计
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
domain中输出时间转换:
@JsonFormat (timezone = "GMT+8",pattern = DATE_FORMAT)
private Timestamp handle_end_time;
由于系统设计中存在时区、日期格式的全局变量设计,接口中数据返回后台就需要动态切换所有时间格式的输出。JsonFormat 中的pattern 入参是常量, 参数无法传递,所以当改变了DATE_FORMAT后,对象转json 无法输出修改后的日期格式。
修改方案:
1,修改final修饰字段的属性值:
public static void change(final String str ,String change){
Class<?> v = str.getClass();
try {
Field field = v.getDeclaredField("value"); //修改值
field.setAccessible(true);
char [] charValue = change.toCharArray();
field.set(str, charValue);
field.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
}
2.当final修改后,修改domain 的@JsonFormat 注解属性
/**
* 扫描包下所有的class路径集合
* @param scanPackage
*/
public List<String> doScenner(String scanPackage) throws UnsupportedEncodingException {
List<String> classNames = new ArrayList<String>();
// System.getProperty("user.dir"); //项目根目录
//扫描scanPachage 的class
String url = this.getClass().getClassLoader().getResource( scanPackage
.replaceAll("\.","/")).getPath();
String packagePath = java.net.URLDecoder.decode(url,"utf-8");
File classPath = new File(packagePath);
for(File file: classPath.listFiles()){
if(file.isDirectory()){
doScenner(scanPackage+"." + file.getName());
}else {
if(!file.getName().endsWith(".class")){
continue;
}
String className = scanPackage + "." + file.getName().replace( ".class","");
classNames.add(className);
}
}
return classNames;
}
/**
* 扫描包,过滤出所有包含指定注解的类, 然后将类中所有指定注解属性替换。
* @param memberMap
*/
public static void changeDateFormatAnnotation(Map<String, Object> memberMap) {
//需要扫描的package
String scanPackage = "com.guideir.ipt.project.system.domain";
Scanner scanner = new Scanner();
List<String> classNames = null;
try {
classNames = scanner.doScenner(scanPackage);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
for (String className : classNames) {
try {
Class clazz = Class.forName(className);
try {
setValue(clazz,memberMap);
} catch (Exception e) {
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* 修改aclass 注解中的属性
* @param aClass
* @param memberMap
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public static void setValue(Class aClass, Map<String, Object> memberMap) throws NoSuchFieldException, IllegalAccessException {
//获取所有声明的属性
Field[] declaredFields = aClass.getDeclaredFields();
//过滤出所有带有注解的属性
// List<Field> fields = new ArrayList<>();
for (Field field : declaredFields) {
if (field.isAnnotationPresent(JsonFormat.class)) {
JsonFormat annotation = field.getAnnotation(JsonFormat.class);
field.setAccessible(true);
InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
//memberValues说明:
// AnnotationInvocationHandler中 private final Map<String, Object> memberValues;
//key为注解的属性名称,value即为注解的属性值。
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
// 因为这个字段是 private final 修饰,所以要打开权限
memberValues.setAccessible(true);
Map map = (Map) memberValues.get(invocationHandler);
for (Map.Entry<String, Object> entry : memberMap.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (map.containsKey(key)) {
map.put(key, value);
}
}
}
}
}