add hot update

This commit is contained in:
huoyo 2022-09-28 19:46:05 +08:00
parent 65195c0386
commit f02d7d38e8
3 changed files with 146 additions and 8 deletions

View File

@ -246,13 +246,19 @@ public class KoTimeController {
@PostMapping("/updateClass") @PostMapping("/updateClass")
@ResponseBody @ResponseBody
@Auth @Auth
public Map updateClass(@RequestParam("classFile") MultipartFile classFile,String className) throws ClassNotFoundException { public Map updateClass(@RequestParam("classFile") MultipartFile classFile,String className) {
Map map = new HashMap(); Map map = new HashMap();
if (classFile==null || classFile.isEmpty()) { if (classFile==null || classFile.isEmpty()) {
map.put("state", 0); map.put("state", 0);
map.put("message", "文件不能为空"); map.put("message", "文件不能为空");
return map; return map;
} }
if (!StringUtils.hasText(className)) {
map.put("state", 0);
map.put("message", "文类名不能为空");
return map;
}
className = className.trim();
File file = null; File file = null;
try { try {
String originalFilename = classFile.getOriginalFilename(); String originalFilename = classFile.getOriginalFilename();
@ -262,33 +268,43 @@ public class KoTimeController {
return map; return map;
} }
String[] filename = originalFilename.split("\\."); String[] filename = originalFilename.split("\\.");
String substring = className.substring(className.lastIndexOf(".") + 1);
if (!substring.equals(filename[0])) {
map.put("state", 0);
map.put("message", "请确认类名是否正确");
return map;
}
file = uploadFile(classFile.getBytes(),filename[0]); file = uploadFile(classFile.getBytes(),filename[0]);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.severe("Error class file!");
map.put("state", 0);
map.put("message", "无法解析文件");
return map;
} }
File jar = null; File jar = null;
if (StringUtils.hasText(agentPath)) { if (!StringUtils.hasText(agentPath)) {
jar = ClassUtil.createJar(); jar = ClassUtil.createJar();
agentPath = jar.getAbsolutePath(); agentPath = jar.getAbsolutePath();
} }
ClassUtil.updateClass(agentPath,className.trim(),file.getAbsolutePath()); ClassUtil.updateClass(agentPath,className,file.getAbsolutePath());
file.delete(); file.deleteOnExit();
if (jar!=null) { if (jar!=null) {
jar.delete(); jar.deleteOnExit();
} }
map.put("state", 1); map.put("state", 1);
map.put("message", "更新成功"); map.put("message", "更新成功");
return map; return map;
} }
public static File uploadFile(byte[] file,String fileName) throws IOException {
private static File uploadFile(byte[] file,String fileName) throws IOException {
FileOutputStream out = null; FileOutputStream out = null;
try { try {
File targetFile = File.createTempFile(fileName, ".class", new File(System.getProperty("java.io.tmpdir"))); File targetFile = File.createTempFile(fileName, ".class", new File(System.getProperty("java.io.tmpdir")));
out = new FileOutputStream(targetFile.getAbsolutePath()); out = new FileOutputStream(targetFile.getAbsolutePath());
out.write(file); out.write(file);
out.flush(); out.flush();
out.close();
return targetFile; return targetFile;
} catch (Exception e) { } catch (Exception e) {
log.severe("" + e); log.severe("" + e);

View File

@ -16,6 +16,7 @@
var globalNeedLogin = globalNeedLoginValue; var globalNeedLogin = globalNeedLoginValue;
var globalToken = sessionStorage.getItem("kotimeToken") var globalToken = sessionStorage.getItem("kotimeToken")
$(document).ready(function () { $(document).ready(function () {
document.querySelector("#classForm").action='contextPath/koTime/updateClass?token='+globalToken
let globalIsLogin = false; let globalIsLogin = false;
$.ajaxSettings.async = false; $.ajaxSettings.async = false;
$.get('contextPath/koTime/isLogin?token='+globalToken, function (data) { $.get('contextPath/koTime/isLogin?token='+globalToken, function (data) {
@ -333,6 +334,47 @@
$('#searchText').val(''); $('#searchText').val('');
} }
} }
function updateClass(){
// document.querySelector("#classForm").submit();
var formData = new FormData();
var file = document.querySelector('#classFile').files[0];
if (file==null || file==undefined) {
UIkit.notification("<font color='red'>Null file</font>",{});
return;
}
var className = document.querySelector("#className").value
if (className==null || className==undefined || className.length<2) {
UIkit.notification("<font color='red'>Null class name</font>",{});
return;
}
formData.append('classFile', file);
formData.append('className', className );
$.ajax({
url: document.querySelector("#classForm").action,
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function (res) {
if (res['state']==1) {
UIkit.notification.closeAll();
UIkit.notification("<font color='green'>Success</font>",{});
}else {
UIkit.notification.closeAll();
UIkit.notification("<font color='red'>"+res['message']+"</font>",{});
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
UIkit.notification.closeAll();
UIkit.notification("<font color='red'>Fail</font>",{});
},
complete: function () {}
})
}
</script> </script>
</head> </head>
<body> <body>
@ -350,6 +392,7 @@
<li id="zl" class="uk-active"><a href="#" >Summary</a></li> <li id="zl" class="uk-active"><a href="#" >Summary</a></li>
<li id="jklb"><a href="#" >Interfaces</a></li> <li id="jklb"><a href="#" >Interfaces</a></li>
<li><a href="#" >Exceptions</a></li> <li><a href="#" >Exceptions</a></li>
<li><a href="#" >Hot update</a></li>
<li><a href="#" >Configurations</a></li> <li><a href="#" >Configurations</a></li>
<li><a href="#" >Contact me</a></li> <li><a href="#" >Contact me</a></li>
</ul> </ul>
@ -406,6 +449,22 @@
<li>exception 1 1&nbsp<span class="uk-label uk-label-danger">closed</span></li> <li>exception 1 1&nbsp<span class="uk-label uk-label-danger">closed</span></li>
</ul> </ul>
</li> </li>
<li style="margin-left: 35%;margin-right: 35%;">
<div class="uk-card uk-card-default uk-card-body">
<form id="classForm" method="post" enctype="multipart/form-data" action="">
<div uk-form-custom="target: true" class="uk-form-controls">
<input id="classFile" name="classFile" type="file" >
<input id="form-file" style="width: 500px;border-radius: 5px" class="uk-input" type="text" placeholder="class file needed to updatecompiled class file" >
</div>
<br>
<br>
<input id="className" name="className" style="width: 500px;border-radius: 5px" class="uk-input" id="" type="text" placeholder="class name needed to update com.xx.xx.TestService" >
<br>
<br>
<button type="button" onclick="updateClass();" style="width: 500px;background-color: #19985d;border-radius: 5px" class="uk-button uk-button-primary uk-width-1-1 uk-margin-small-bottom">OK</button>
</form>
</div>
</li>
<li style="margin-left: 30%;margin-right: 30%;"> <li style="margin-left: 30%;margin-right: 30%;">
<div class="layui-tab-item"> <div class="layui-tab-item">
<label >KoTime switch</label> <input id='kotimeEnable' type="checkbox" checked> <label >KoTime switch</label> <input id='kotimeEnable' type="checkbox" checked>

View File

@ -5,6 +5,10 @@
<style> <style>
UIKitCss UIKitCss
</style> </style>
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/css/uikit.min.css"/>-->
<!-- UIkit JS -->
<!-- <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit.min.js"></script>-->
<!-- <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit-icons.min.js"></script>-->
<script> <script>
UIKitJs; UIKitJs;
uiKitIconsJs; uiKitIconsJs;
@ -16,6 +20,7 @@
var globalNeedLogin = globalNeedLoginValue; var globalNeedLogin = globalNeedLoginValue;
var globalToken = sessionStorage.getItem("kotimeToken") var globalToken = sessionStorage.getItem("kotimeToken")
$(document).ready(function () { $(document).ready(function () {
document.querySelector("#classForm").action='contextPath/koTime/updateClass?token='+globalToken
let globalIsLogin = false; let globalIsLogin = false;
$.ajaxSettings.async = false; $.ajaxSettings.async = false;
$.get('contextPath/koTime/isLogin?token='+globalToken, function (data) { $.get('contextPath/koTime/isLogin?token='+globalToken, function (data) {
@ -331,6 +336,47 @@
$('#searchText').val(''); $('#searchText').val('');
} }
} }
function updateClass(){
// document.querySelector("#classForm").submit();
var formData = new FormData();
var file = document.querySelector('#classFile').files[0];
if (file==null || file==undefined) {
UIkit.notification("<font color='red'>文件不能为空</font>",{});
return;
}
var className = document.querySelector("#className").value
if (className==null || className==undefined || className.length<2) {
UIkit.notification("<font color='red'>类名不能为空</font>",{});
return;
}
formData.append('classFile', file);
formData.append('className', className );
$.ajax({
url: document.querySelector("#classForm").action,
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function (res) {
if (res['state']==1) {
UIkit.notification.closeAll();
UIkit.notification("<font color='green'>更新成功</font>",{});
}else {
UIkit.notification.closeAll();
UIkit.notification("<font color='red'>"+res['message']+"</font>",{});
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
UIkit.notification.closeAll();
UIkit.notification("<font color='red'>更新失败</font>",{});
},
complete: function () {}
})
}
</script> </script>
</head> </head>
<body> <body>
@ -348,6 +394,7 @@
<li id="zl" class="uk-active"><a href="#" >总览</a></li> <li id="zl" class="uk-active"><a href="#" >总览</a></li>
<li id="jklb"><a href="#" >接口列表</a></li> <li id="jklb"><a href="#" >接口列表</a></li>
<li><a href="#" >异常列表</a></li> <li><a href="#" >异常列表</a></li>
<li><a href="#" >热更新</a></li>
<li><a href="#" >配置</a></li> <li><a href="#" >配置</a></li>
<li><a href="#" >技术支持</a></li> <li><a href="#" >技术支持</a></li>
</ul> </ul>
@ -404,6 +451,22 @@
<li>exception 1 1&nbsp<span class="uk-label uk-label-danger">未开启</span></li> <li>exception 1 1&nbsp<span class="uk-label uk-label-danger">未开启</span></li>
</ul> </ul>
</li> </li>
<li style="margin-left: 35%;margin-right: 35%;">
<div class="uk-card uk-card-default uk-card-body">
<form id="classForm" method="post" enctype="multipart/form-data" action="">
<div uk-form-custom="target: true" class="uk-form-controls">
<input id="classFile" name="classFile" type="file" >
<input id="form-file" style="width: 500px;border-radius: 5px" class="uk-input" type="text" placeholder="更新的类文件:编译过的.class文件" >
</div>
<br>
<br>
<input id="className" name="className" style="width: 500px;border-radius: 5px" class="uk-input" id="" type="text" placeholder="更新的类全名com.xx.xx.TestService" >
<br>
<br>
<button type="button" onclick="updateClass();" style="width: 500px;background-color: #19985d;border-radius: 5px" class="uk-button uk-button-primary uk-width-1-1 uk-margin-small-bottom">确定</button>
</form>
</div>
</li>
<li style="margin-left: 30%;margin-right: 30%;"> <li style="margin-left: 30%;margin-right: 30%;">
<div class="layui-tab-item"> <div class="layui-tab-item">
<label >开启koTime</label> <input id='kotimeEnable' type="checkbox" checked> <label >开启koTime</label> <input id='kotimeEnable' type="checkbox" checked>