import com.google.common.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;java
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;web
@RestController
public class EchoController implements ApplicationContextAware {spring
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; }
//applicationContext中的對象反射調用,data爲請求參數(LinkedHashMap的json格式,其中key爲類型的全限定名)
@RequestMapping(method = RequestMethod.POST, value = "/invoke")
public String invoke(String obj, String methodName, @RequestParam(value = "data", required = false) String data) {
try {
Object object = getObj(applicationContext, obj);
LinkedHashMap<String, Object> linkedHashMap = StringUtils.isBlank(data) ?
new LinkedHashMap<>() : GSON.fromJson(data, new TypeToken<LinkedHashMap<String, Object>>() {
}.getType());
Object[] args = linkedMap2args(linkedHashMap);
try {
Object invoke = MethodUtils.invokeMethod(object, methodName, args);
return GSON.toJson(invoke);
} catch (Exception e) {
Method[] declaredMethods = object.getClass().getDeclaredMethods();
for (Method m : declaredMethods) {
if (m.getName().equals(methodName)) {
m.setAccessible(true);
Object invoke = m.invoke(object, args);
return GSON.toJson(invoke);
}
}
for (Class parentClass = object.getClass().getSuperclass(); parentClass != null; parentClass = parentClass.getSuperclass()) {
Method[] parentMethods = parentClass.getDeclaredMethods();
for (Method m : parentMethods) {
if (m.getName().equals(methodName)) {
m.setAccessible(true);
Object invoke = m.invoke(object, args);
return GSON.toJson(invoke);
}
}
}
throw new RuntimeException("未找到方法:" + methodName);
}
} catch (Exception e) {
return e.getMessage();
}
}apache
private Object[] linkedMap2args(LinkedHashMap<String, Object> linkedHashMap) { if (CollectionUtils.isEmpty(linkedHashMap)) { return null; } else { List<Object> args = new ArrayList<>(); linkedHashMap.entrySet().forEach(stringObjectEntry -> { String type = stringObjectEntry.getKey().split("_")[0]; Class<?> clazz = null; try { clazz = Class.forName(type); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } Object arg = GSON.fromJson(GSON.toJson(stringObjectEntry.getValue()), clazz); args.add(arg); }); return args.toArray(); } }
//applicationContext中的對象屬性訪問,例如bean.field1.field2.passwordbr/>@RequestMapping("/getObj")
public String getObj(String obj) {
Object object = getObj(applicationContext, obj);
return obj2String(object);
}json
public static String obj2String(Object o) { if (String.class.equals(o.getClass()) || Enum.class.equals(o.getClass()) || Date.class.equals(o.getClass()) || Long.class.equals(o.getClass()) || long.class.equals(o.getClass()) || Integer.class.equals(o.getClass()) || int.class.equals(o.getClass()) || Double.class.equals(o.getClass()) || double.class.equals(o.getClass()) || Float.class.equals(o.getClass()) || float.class.equals(o.getClass()) || Short.class.equals(o.getClass()) || short.class.equals(o.getClass()) || Boolean.class.equals(o.getClass()) || boolean.class.equals(o.getClass()) ) { return String.valueOf(o); } else { StringBuilder sb = new StringBuilder(); Field[] allFields = FieldUtils.getAllFields(o.getClass()); for (Field field : allFields) { sb.append(field.getName()); sb.append("\n"); } return sb.toString(); } } private static Object getObj(ApplicationContext ac, String propAccessChain) { Object o = null; if (StringUtils.isBlank(propAccessChain)) { return "參數不能爲空"; } String[] split = propAccessChain.split("\\."); try { o = ac.getBean(split[0]); } catch (Exception e) { System.out.println("獲取對象" + split[0] + "失敗"); return "對象" + split[0] + "不存在"; } int index = propAccessChain.indexOf(".") + 1; return index > 0 ? getObj(o, propAccessChain.substring(index)) : o; } private static Object getObj(Object o, String propAccessChainFromObj) { String[] split = propAccessChainFromObj.split("\\."); for (String next : split) { try { if (next.contains("(") && next.contains(")")) { try { String desc = next.substring(0, next.indexOf("(")); String key = next.substring(next.indexOf("(") + 1, next.indexOf(")")); Object listOrMap = FieldUtils.readField(o, desc, true); if (Map.class.isAssignableFrom(listOrMap.getClass())) { o = ((Map) listOrMap).get(key); } else if (List.class.isAssignableFrom(listOrMap.getClass())) { o = ((List) listOrMap).get(Integer.parseInt(key)); } else { Object[] cast = Object[].class.cast(listOrMap); o = cast[Integer.parseInt(key)]; } } catch (Exception e) { System.out.println("獲取屬性" + next + "失敗"); } } else { try { o = FieldUtils.readField(o, next, true); } catch (Exception e) { System.out.println("獲取屬性" + next + "失敗"); } } } catch (Exception e) { throw new RuntimeException("獲取屬性" + next + "失敗"); } } return o; }
}api