1. 通用工具
入口 http://localhost:8080/tool
![](https://img.haomeiwen.com/i20154612/01d668b242d231cc.png)
执行结果:
![](https://img.haomeiwen.com/i20154612/e74dcfe7d071ac6b.png)
2. 获取所有Bean
@Controller
@RequestMapping("tool")
public class BeanTools {
@GetMapping(value = {"", "/common"})
public ModelAndView common() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("beanNames", getBeanNames());
modelAndView.setViewName("invoke.html");
return modelAndView;
}
private List<JSONObject> getBeanNames() {
List<String> beanNames = SpringBeanUtils.getBeans();
List<JSONObject> beanObjs = new ArrayList();
beanNames.forEach(str -> {
JSONObject obj = new JSONObject();
obj.put("text", str);
obj.put("value", str);
beanObjs.add(obj);
});
return beanObjs;
}
}
@Component
public class SpringBeanUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanUtils.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static List<String> getBeans() {
String[] beanDefinitionNames = getApplicationContext().getBeanDefinitionNames();
List<String> beanNames = Arrays.stream(beanDefinitionNames)
.filter(str -> !str.contains("."))
.collect(Collectors.toList());
beanNames.sort(String::compareTo);
return beanNames;
}
}
3. 获取 Bean 的方法
@RestController
@RequestMapping("/ajax")
public class BeanAjax {
@GetMapping("/getMethods")
public List<Item> getMethods(String beanName) {
return getBeanMethods(beanName);
}
@PostMapping("/beanMethods")
public List<Item> beanMethods(AjaxPojo ajaxPojo) {
return getBeanMethods(ajaxPojo.getBeanName());
}
private List<Item> getBeanMethods(String beanName) {
List<Item> list = new ArrayList();
Object bean = SpringBeanUtils.getBean(beanName);
Method[] methods = bean.getClass().getMethods();
for (Method method : methods) {
String methodSign = method.toString();
String paramSign = methodSign.substring(methodSign.indexOf("("), methodSign.indexOf(")") + 1);
list.add(new Item(method.getName() + paramSign, method.getName() + paramSign));
}
return list;
}
@Data
public class Item implements Serializable {
private static final long serialVersionUID = -6504357622310055548L;
private String text;
private String value;
public Item(String text, String value) {
this.text = text;
this.value = value;
}
}
@Data
public class AjaxPojo implements Serializable {
private String appName;
private String beanName;
private String methodName;
private List<String> args = new ArrayList<>();
}
}
4. 执行方法
@RestController
@RequestMapping("/ajax")
public class BeanAjax {
@PostMapping("/invoke")
public JSONObject invoke(AjaxPojo ajaxPojo) throws InvocationTargetException, IllegalAccessException {
String beanName = ajaxPojo.getBeanName();
String methodName = ajaxPojo.getMethodName();
List<String> args = ajaxPojo.getArgs();
Object bean = SpringBeanUtils.getBean(beanName);
Method method = findMethod(bean, methodName);
Object invoke = method.invoke(bean, ReflectDemo.assemblyArgs(args, method.getParameterTypes()));
JSONObject result = new JSONObject();
JSONObject request = new JSONObject();
request.put("beanName", beanName);
request.put("methodName", method.getName());
request.put("params", ajaxPojo.getArgs());
request.put("paramTypes", method.getParameterTypes());
JSONObject response = new JSONObject();
response.put("data", invoke);
response.put("success", "true");
result.put("request", request);
result.put("response", response);
return result;
}
private Method findMethod(Object bean, String methodName) {
Method[] methods = bean.getClass().getMethods();
for (Method method : methods) {
String methodSign = method.toString();
if (methodSign.contains(methodName)) {
return method;
}
}
return null;
}
@Data
public class AjaxPojo implements Serializable {
private String appName;
private String beanName;
private String methodName;
private List<String> args = new ArrayList<>();
}
}
public class ReflectDemo {
/**
* 参数组装
*
* @param arguments 参数值
* @param parameterTypes 参数类型
* @return
*/
public static Object[] assemblyArgs(List<String> arguments, Class<?>[] parameterTypes) {
List<Object> args = new ArrayList<>();
for (int i = 0; i < arguments.size(); i++) {
args.add(getArgValue(parameterTypes[i], arguments.get(i)));
}
return args.toArray();
}
public static Object getArgValue(Class<?> parameterType, String arg) {
if (StringUtils.isBlank(arg)) {
return null;
}
arg = StringUtils.trim(arg);
if (parameterType.equals(String.class)) {
return arg;
}
if (parameterType.equals(Integer.class)) {
return Integer.valueOf(arg);
}
if (parameterType.equals(Date.class)) {
if (arg.length() == 10) {
// 例如:2023-01-01
arg += " 00:00:00";
}
return DateUtil.parseToDateTime(arg);
}
// 转为对象
return JSON.parseObject(arg, parameterType);
}
}
5. 页面 invoke.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Invoke</title>
<style type="text/css">
.tool_class {
height: 40px;
}
.form_class {
height: 30px;
}
.b_select {
width: 500px;
height: 26px;
}
.arg_class {
width: 500px;
}
.span_class {
display: inline-block;
width: 120px;
text-align: right;
vertical-align: top;
}
.button {
position: absolute;
background-color: #0a0a23;
color: #fff;
border: none;
width: 100px;
border-radius: 2px;
padding: 5px;
}
.button:focus {
outline-color: transparent;
outline-style: solid;
box-shadow: 0 0 0 2px #333338;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div class="tool_class">通用工具</div>
<form>
<div class="form_class">
<span class="span_class">IP地址:</span>
<input id="targetIp" placeholder="127.0.0.1"/><br>
</div>
<div class="form_class">
<span class="span_class">所属应用:</span>
<select id="appName" name="appName" class="b_select">
<option value="">请选择</option>
<option value="concrete" selected="selected">concrete</option>
</select>
</div>
<div class="form_class">
<span class="span_class">bean名称:</span>
<select id="beanName" name="beanName" class="b_select">
<option value="">请选择</option>
<option th:each="item:${beanNames}"
th:value="${item.value}" th:text="${item.text}">
</option>
</select>
</div>
<div class="form_class" id="methodDiv">
<span class="span_class">method名称:</span>
<select id="methodName" name="methodName" class="b_select">
<option value="">请选择</option>
</select>
</div>
<div class="form_class" id="submitDiv">
<button id="btn_click" class="button" type="button">提交</button>
</div>
</form>
<script>
var tmpEle = [];
$().ready(function () {
// change事件
$("#beanName").change(function () {
// var value = $("#beanName").val();
var value = $(this).val();
// $.ajax({
// type: "GET",
// url: "/ajax/getMethods?beanName=" + value,
// async: true,
// dataType: "json",
// success: function (data) {
// //清空下拉框选项
// // $("#methodName").empty();
// // $("#methodName").append("<option value=''>请选择</option>");
// if (data && data.length > 0) {
// // for循环:https://blog.csdn.net/hani_wen/article/details/81878112
// // for (var i = 0; i < data.length; i++) { data[i].value }
// // for (var item in data) { 下标 }
//
// for (item of data) {
// var option = "<option value=" + item.value + ">" + item.text + "</option>";
// $("#methodName").append(option);
// }
// }
// }
// });
// let paramObj = {
// beanName : value
// }
$.ajax({
type: "POST",
url: "/ajax/beanMethods",
data: {beanName: value},
async: true,
dataType: "json",
success: function (data) {
// 清空下拉框选项
$("#methodName").empty();
$("#methodName").append("<option value=''>请选择</option>");
if (data && data.length > 0) {
for (item of data) {
// 注意可能会有转义符号 <>
var option = "<option value=" + item.value + ">" + item.text + "</option>";
$("#methodName").append(option);
}
}
}
});
});
// 方法参数
$("#methodName").change(function () {
cleanParams();
$('#result').remove();
var startElement = $('#methodDiv');
var methodName = $(this).val();
var methodType = methodName.substring(methodName.indexOf("(") + 1, methodName.indexOf(")"));
if (methodType.length > 0) {
var paramTypeArray = methodType.split(",");
for (var i in paramTypeArray) {
var newElement;
if (isBasicType(paramTypeArray[i])) {
newElement = '<div id="methodDiv' + i + '" > <span class="span_class">arg-' + i +
':</span> <input type="text" id="arg-' + i + '" class="arg_class" style="height: 26px;" placeholder="' + paramTypeArray[i] + '" /></div>';
} else {
newElement = '<div id="methodDiv' + i + '" > <span class="span_class">arg-' + i +
'(对象JSON串):</span> <textarea id="arg-' + i + '" class="arg_class" style="resize:none;" rows="5" placeholder="' + paramTypeArray[i] + '"></textarea> </div>';
}
startElement.after(newElement);
startElement = $('#methodDiv' + i);
tmpEle.push(startElement);
}
}
});
// 按钮
$("#btn_click").click(function () {
$('#result').remove();
var beanName = $("#beanName").val();
var methodName = $("#methodName").val();
// 参数
var args = [];
// $("input[name='arg']").each(function () {
// args.push($(this).val());
// });
$(".arg_class").each(function () {
args.push($(this).val());
});
$.ajax({
type: "POST",
url: "/ajax/invoke",
data: {
beanName: beanName,
methodName: methodName,
args: args
},
async: true,
dataType: "json",
success: function (data) {
// JSON.stringify(data)
// JSON.stringify()方法最多接受三个参数:JSON对象,替换器和空格。 只有JSON对象是必需的,其余两个参数是可选的
var startElement = $('#submitDiv');
var resultEle = '<div class="result" id="result"> <span class="span_class">执行结果:</span> ' +
'<textarea style="resize:none; width: 500px;" rows="10" >' + JSON.stringify(data, null, 4) + '</textarea></div>';
startElement.after(resultEle);
}
});
});
});
function isBasicType(type) {
var basicTypes = [
"java.lang.Byte",
"java.lang.Boolean",
"java.lang.Integer",
"java.lang.Character",
"java.lang.Double",
"java.lang.Short",
"java.lang.Long",
"java.lang.Float",
"java.lang.String",
"int", "long", "byte", "boolean", "char", "float", "short", "double"
];
for (const basicType of basicTypes) {
if (basicType === type) {
return true;
}
}
return false;
}
function cleanParams() {
for (var i in tmpEle) {
$(tmpEle[i]).remove();
}
tmpEle = [];
}
</script>
</body>
</html>
网友评论