在開發的時候需要實現一個class文件的上傳存儲功能,所以用到了bootstrap fileinput 插件,後臺是用的springMVC。
提前準備
在開始貼代碼前把一些必要的jar,css,js等文件準備好。
bootstrap fileinput
需要加載jQuery、bootstrap、fileinput
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> <!-- 加載jQuery -->
<script src="http://cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <!-- 加載bootstrap的js -->
<script src="<%=webContext %>/resources/bootstrap/js/fileinput.js"></script> <!-- 加載fileinput的js -->
<link rel="stylesheet"
href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css" /> <!-- 加載bootstrap的css樣式 -->
<link rel="stylesheet"
href="<%=webContext %>/resources/bootstrap/css/fileinput.css" /> <!-- 加載fileinput的css樣式 -->
springMVC
需要配置文件解析器,下面是配置在spring-bean.xml中。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="-1" />
<property name="defaultEncoding" value="UTF-8" />
<property name="maxInMemorySize" value="40960"></property>
<property name="uploadTempDir" value="fileUpload/temp"></property>
</bean>
jar包
在配置springMVC的文件解析器時可能會拋出ClassNotFound的異常。原因很可能是缺少Apache的commons-io和commons-fileupload兩個jar包,下面是maven添加。
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
代碼片段
jsp頁面代碼
jsp頁面部分
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal">上傳</button>
<!-- 模態框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h2 class="modal-title" id="myModalLabel">
上傳class文件
</h2>
</div>
<div class="modal-body">
<form enctype="multipart/form-data" id="uploadForm">
<input id="fileUpload" name="classFile" type="file" multiple class="file-loading">
</form>
</div>
<div class="modal-footer">
<h6>class文件的包名必須是customfuction。</h6>
<h6>class名作爲表達式名,包含一個公開方法。</h6>
<h6>方法名爲class名+Template,無繼承,無實現接口。</h6>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
js代碼
$("#myModal").on("hidden.bs.modal",function(){
location.reload();
}); //關閉模態框時刷新頁面
$("#fileUpload").fileinput({
uploadUrl: "<%=webContext %>/craw/customFunctionUpload.do", // server upload action
allowedFileExtensions: ['class'],
uploadAsync: true,
maxFileCount: 5,
uploadExtraData: {state:"0"}
});
後臺控制代碼
@RequestMapping("craw/customFunctionUpload.do")
public void fileUpload(@RequestParam(value = "classFile") MultipartFile file, HttpServletRequest request,
HttpServletResponse response) throws IOException, JBOException {
if (file != null) {
//注意:返回格式必須是json(可查看官方文檔)
//=========================具體功能可忽略===========================
String globalDir = request.getSession().getServletContext().getRealPath("/");
String fileName = file.getOriginalFilename();
String state = request.getParameter("state");
BizObjectManager bm = JBOFactory.getBizObjectManager("jbo.service.custom_function");
String version = "1";
int count = bm.createQuery("select count(*) from O where funcName=:funcName")
.setParameter("funcName", fileName.substring(0, fileName.length() - 6))
.getSingleResult(false).getAttribute("count(*)").getInt();
if("0".equals(state)){
if(count >= 1){
response.getWriter().print("{\"error\":\"已存在同名class!\"}");
return;
}
}
else{
if(!fileName.substring(0, fileName.length() - 6).equals(state)){
response.getWriter().print("{\"error\":\"上傳的class文件名與要修改的表達式名不匹配!\"}");
return;
}
if(count >= 1){
version = "" + (Integer.valueOf(bm.createQuery("select version form O where funcName=:funcName")
.setParameter("funcName", fileName.substring(0, fileName.length() - 6))
.getSingleResult(false).getAttribute("version").getString()) + 1);
}
}
System.out.println(globalDir+"cfClasses/customfunction");
File write = new File(globalDir+"cfClasses/customfunction", fileName);
if (write.getParentFile().exists() == false) {
System.out.println("dir not exist");
write.getParentFile().mkdirs();
}
write.createNewFile();
InputStream ins = file.getInputStream();
OutputStream ous = new FileOutputStream(write);
try {
byte[] buffer = new byte[1024];
ARE.getLog().debug("開始寫文件:" + fileName);
int len = 0;
while ((len = ins.read(buffer)) > -1)
ous.write(buffer, 0, len);
ARE.getLog().debug("已保存的文件:" + fileName);
} catch (Exception e) {
response.getWriter().print("{\"error\":\"文件保存失敗\"}");
} finally {
ous.close();
ins.close();
}
System.out.println("fileupload success! name=" + fileName);
MyFileClassLoader fileClsLoader = new MyFileClassLoader();
fileClsLoader.setClassPath(globalDir + "cfClasses");
boolean flag = false;
int paramCount = 0;
String funcTemplateName = fileName.substring(0,fileName.length()-6)+"Template";
String funcTemplate = funcTemplateName + "(";
try {
Class cls = fileClsLoader.loadClass("customfunction."+fileName.substring(0,fileName.length()-6));
Method[] mthds = cls.getMethods();
for(Method mthd : mthds){
String methodName = mthd.getName();
System.out.println("mthd.name="+methodName);
if(methodName.equals(fileName.substring(0,fileName.length()-6)+"Template")){
flag = true;
paramCount = mthd.getGenericParameterTypes().length;
for (int i = 1; i <= paramCount; i++) {
funcTemplate += "${"+ i + "},";
}
if(paramCount > 0){
funcTemplate = funcTemplate.substring(0,funcTemplate.length() - 1);
}
funcTemplate += ")";
}
}
} catch (ClassNotFoundException | IllegalArgumentException e) {
ARE.getLog().error("解析class文件模板函數失敗!", e);
write.delete();
response.getWriter().print("{\"error\":\"文件保存失敗\"}");
}
if(!flag){
write.delete();
response.getWriter().print("{\"error\":\"class文件中不存在方法名爲"+funcTemplateName+"的方法\"}");
return;
}
BizObject obj = bm.newObject();
obj.setAttributeValue("funcName", fileName.substring(0, fileName.length() - 6));
obj.setAttributeValue("funcTemplate", funcTemplate);
obj.setAttributeValue("version", version);
obj.setAttributeValue("inputTime", StringFunction.getTodayNow());
obj.setAttributeValue("updateTime", StringFunction.getTodayNow());
bm.saveObject(obj);
//=========================具體功能可忽略===========================
response.getWriter().print("{}"); //成功時返回一個空json表示成功
} else {
System.out.println("file empty");
response.getWriter().print("{\"error\":\"上傳失敗\"}"); //出錯時返回一個包含error屬性的json,前端控件會顯示錯誤狀態並輸出對應信息
}
}
}
圖片展示
按鈕彈出模態框
成功
報錯