本項目使用了ajax输瓜、ssm、layui。為了實現效果為在表單輸入時判斷該字段是否在數據庫中存在以及文件上傳的功能尤揣。
- 如下圖所示
知識編號為21的值已經在數據庫中存在搔啊,但是業(yè)務要求知識編號不能重復,所以在表單提交的時候首先需要判斷該值是否存在北戏。如果存在則提示重新輸入
知識編號字段驗證
文件上傳且支持多文件上傳负芋。并提供縮略圖。
文件上傳
文件上傳
準備工作
- 我們使用的框架是ssm即springMVC + spring + mybatis 嗜愈,使用了maven來構建項目旧蛾。并且使用了json解析格式。
第一步:在pom.xml文件引入依賴坐標
<!-- 文件上傳 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- json配置 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.8</version>
</dependency>
第二步:在spirng的配置文件applicationContext.xml文件中引入文件上傳所需的multipartResolver對象
<!--文件上傳配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 請求的編碼格式蠕嫁,必須和jSP的pageEncoding屬性一致锨天,以便正確讀取表單的內容, 默認為ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/> <!-- 上傳文件大小上限剃毒,單位為字節(jié)(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
第三步:在spirngmvc的配置文件springmvc.xml文件中配置json
<!--配置json-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html; charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html; charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
- 到這里準備工作完畢病袄,下面開始進行業(yè)務
前端界面
- 前端使用的是JSP界面,使用的layui前端框架快速搭建
- 由于在這個頁面赘阀,使用了表單數據驗證益缠、文件上傳、表單提交
表單樣式
<form id="addForm" class="layui-form" action="#"
method="post">
<div class="layui-form-item">
<label class="layui-form-label">知識編號</label>
<div class="layui-input-inline shortInput">
<input type="text" id="kId" name="kId" autocomplete="off" placeholder="請輸入知識編號基公,例:SS002"
class="layui-input" lay-verify="inputKId">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">知識名稱</label>
<div class="layui-input-inline shortInput">
<input type="text" id="kName" name="kName" autocomplete="off" placeholder="請輸入知識名稱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">知識描述</label>
<div class="layui-input-inline shortInput">
<textarea style="width: 100%;" placeholder="請輸入內容" id="kDescribe" class="layui-textarea" name="kDescribe"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">知識價格</label>
<div class="layui-input-inline shortInput">
<input type="text" id="kPrice" name="kPrice" autocomplete="off" placeholder="請輸入知識價格"
class="layui-input" required
lay-verify="required|number">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">知識文件</label>
<div class="layui-upload">
<button type="button" class="layui-btn" id="uploadFile">請選擇文件</button>
<blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
預覽圖:
<div class="layui-upload-list" id="previewImages"></div>
</blockquote>
<button id="hideUpload" type="button" style="display: none"></button>
</div>
</div>
<hr class="layui-bg-blue">
<div class="layui-form-item">
<div class="layui-input-block">
<button id="btnAction" class="layui-btn" lay-submit="" lay-filter="submit">保存</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
ajax使用
- 在js這里幅慌,因為我們使用了layui。所以我們首先提供layui.use([可選模塊],function{})方法引入模塊轰豆。再定義layui模塊使用函數
- 在ajax里胰伍,我們需要配置以下:
// 調用ajax進行異步提交
$.ajax({
type: 'post',
dataType: "json",
url: '', // 你的url地址
//async: true, 是否開啟異步操作,默認為ture秒咨,為異步調用喇辽。false為同步調用
data: {}, // 需要傳輸到后臺的數據
success: function (res) {
// 異步操作執(zhí)行成功后調用的方法
},
error: function (err) {
// 異步操作執(zhí)行錯誤后調用的方法
}
});
return false; // 關閉操作掌挚,否則無法刷新數據
});
注意: 使用ajax通常會遇到幾個問題:
1.使用ajax向后臺傳參問題:
- data這里使用的是key:value的傳參方式雨席。比如后臺springMVC的控制層需要獲取userId的值。則data定義為:
data: {
userId: value // value為前端參數
}
data里面的key需要與后臺接收參數定義一致吠式,否則后臺無法接收參數
- 后臺如果需要通過對象的形式獲取參數陡厘,例如異步表單提交。則data定義為:
data: {
user: {
userId : value
name: value
}
}
2.使用ajax后特占,后臺控制層執(zhí)行方法成功糙置,但就是不調用success方法,一直調用error方法是目。
- 原因:后臺返回的參數不是json類型谤饭。由于ajax規(guī)定后臺參數必須是json類型,如果返回的參數(列表,對象)都正確揉抵,因為不是json類型亡容,則一樣調用error方法。
- 解決: 后臺使用map返回,使用@ResponseBody注解
@RequestMapping("攔截路徑")
@ResponseBody
public Object findByMId(String mId) throws Exception {
HashMap<String, Object> map = new HashMap<>();
// 方法省略
return map;
}
js代碼
<script>
layui.use(["jquery", "upload", "form", "layer", "element"], function () {
var $ = layui.$,
element = layui.element,
layer = layui.layer,
upload = layui.upload,
form = layui.form;
// 驗證表單字段是否存在
form.verify({
inputKId: function (value) {
var knowledge = {
kId: value
};
var message = '';
$.ajax({
type: "post",
url: "${pageContext.request.contextPath}/knowledge/toVerifyByKId.do",
dataType: 'json',
async: false,
data: knowledge,
success: function (data) {
if (data) {
} else {
message = "知識編號已存在請重新輸入!"
}
}
});
if (message !== "") {
return message
}
}
});
// 表單提交事件
form.on('submit(submit)', function (data) {
var date = new Date();
var knowledge = {
kId: data.field.kId,
kName: data.field.kName,
kDescribe: data.field.kDescribe,
kPrice: data.field.kPrice,
};
// 調用ajax進行異步提交
$.ajax({
type: 'post',
dataType: "json",
url: '${pageContext.request.contextPath}/knowledge/addKnowledge.do',
data: knowledge,
success: function (res) {
if (res.code == 0) {
$('#hideUpload').trigger('click');
layer.msg("知識信息保存成功!", {
time: 3000
});
// 信息保存成功后執(zhí)行查詢全部方法并跳轉列表界面
location.href="${pageContext.request.contextPath}/knowledge/findAll.do";
} else {
layer.msg("知識信息保存失敗!請重新填寫冤今!", {
time: 3000
}, function () {
//重新加載頁面
location.reload();
})
}
},
error: function (err) {
}
});
return false;
});
// layui文件上傳方法
var uploadInst = upload.render({
elem: '#uploadFile' // id選擇器闺兢,用于指向文件上傳的div樣式
, url: '${pageContext.request.contextPath}/knowledge/uploadFile.do' // 請求后臺的路徑
, auto: false //選擇文件后不自動上傳
, bindAction: '#hideUpload' //指向一個按鈕觸發(fā)上傳,這里是指定了當用戶點擊保存表單后戏罢,一起提交
, multiple: true // 是否開啟多文件上傳
, accept: 'file' // 接收上傳文件的類型
, before: function (obj) { // 上傳文件方法執(zhí)行前調用
this.data = {'kId': $('#kId').val()}; // 獲取主鍵屋谭,并方便保存至文件表數據庫
}
, choose: function (obj) { // 選擇文件后調用,用于顯示縮略圖
//將每次選擇的文件追加到文件隊列
var files = obj.pushFile();
//預讀本地文件龟糕,如果是多文件桐磁,則會遍歷。(不支持ie8/9)
obj.preview(function (index, file, result) {
$('#previewImages').append('<img src="' + result + '" alt="' + file.name + '" class="layui-upload-img" style="height: 100px;width: 140px;margin-left: 10px;margin-right: 10px">')
});
}
, done: function (res) { // 上傳以后調用
//上傳完畢
layer.msg("文件上傳成功!", {
time: 3000
});
}
,error: function(index, upload){ // 上傳文件失敗時調用
layer.closeAll('loading');
}
});
});
</script>
后臺代碼
- 業(yè)務1:判斷知識編號是否已存在翩蘸,如存在則提示信息所意。
controller
/**
* 判斷知識編號是否存在
*/
@RequestMapping("/toVerifyByKId.do")
@ResponseBody
public boolean toVerifyByKId(Knowledge knowledge){
String KId = knowledge.getkId();
if (KId!=null) {
List<Knowledge> knowledge1 = knowledgeService.findByKId(KId);
System.out.println(knowledge1);
if (knowledge1.size()==0) {
return true;
}
}
System.out.println("知識編號存在");
return false;
}
- 業(yè)務2:文件上傳(支持多文件)。
controller這里通過MultipartFile 接收一個file對象催首,注意不是數組[]類型扶踊,因為在layui里,上傳文件是單獨調用郎任。一個文件上傳就調用一次上傳文件的方法秧耗。如果是三個文件上傳,那么就調用三次文件上傳的方法舶治。
/**
* 上傳知識文件
*/
@RequestMapping("/uploadFile.do")
@ResponseBody
@CrossOrigin
public int uploadFile(@RequestParam("file") MultipartFile file , String kId) throws Exception {
int code = -1;
if (file != null) {
code = knowledgeFileService.uploadFile(file,kId);
}
return code;
}
serviec這里使用文件上傳工具類
/**
* 上傳文件
*
* @param file
* @param kId
*/
@Override
public int uploadFile(MultipartFile file, String kId) throws Exception {
int code = -1;
String path = "D:\\ideaTestFile\\knowpay";
if (!"".equals(kId) && kId != null) {
// 獲取文件名
String fileName = file.getOriginalFilename();
if (fileName != null) {
// 上傳文件
upLoadUtil(path,fileName,file);
// 獲取文件類型(后綴)
String[] splitStr = fileName.split("\\.");
String suffix = splitStr[splitStr.length - 1];
// 獲取文件路徑
String filePath = path + "\\" +fileName;
// 保存數據庫
KnowledgeFile knowledgeFile = new KnowledgeFile();
knowledgeFile.setkId(kId);
knowledgeFile.setfName(fileName);
knowledgeFile.setfType(suffix);
knowledgeFile.setfPath(filePath);
knowledgeFileDao.addKnowledgeFile(knowledgeFile);
code = 0;
}
}
return code;
}
FileUtils文件操作工具類
package com.ozy.utils;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
/**
* 文件操作工具類
*/
public class FileUtils {
/**
* 上傳文件工具
*
* @param UPLOAD_FILES_PATH 上傳路徑
* @param fileName 文件名稱
* @param file 文件
*/
public static Boolean upLoadUtil(String UPLOAD_FILES_PATH, String fileName, MultipartFile file) throws IOException {
if (file.isEmpty()) {
return false;
} else {
File dest = new File(UPLOAD_FILES_PATH + "/" + fileName);
//判斷文件父目錄是否存在
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
file.transferTo(dest);
}
return true;
}
/**
* 下載文件工具
*
* @param response response對象
* @param realPath 文件路徑
* @param fileName 文件名稱
*/
public static void downloadUtil(final HttpServletResponse response, String realPath, String fileName) throws IOException {
File file = new File(realPath);
if (file.exists()) {
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
// 下載文件能正常顯示中文
try {
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 實現文件下載
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
assert bis != null;
bis.close();
fis.close();
}
}
}
/**
* 刪除文件夾
*
* @param sPath 文件夾路徑
*/
public static boolean DeleteFolder(String sPath) {
boolean flag = false;
File file = new File(sPath);
// 判斷目錄或文件是否存在
if (!file.exists()) { // 不存在返回 false
return flag;
} else {
// 判斷是否為文件
if (file.isFile()) { // 為文件時調用刪除文件方法
return deleteFile(sPath);
} else { // 為目錄時調用刪除目錄方法
return deleteDirectory(sPath);
}
}
}
/**
* 刪除單個文件
*
* @param sPath 被刪除文件的文件名
* @return 單個文件刪除成功返回true分井,否則返回false
*/
public static boolean deleteFile(String sPath) {
boolean flag = false;
File file = new File(sPath);
// 路徑為文件且不為空則進行刪除
if (file.isFile() && file.exists()) {
file.delete();
flag = true;
}
return flag;
}
/**
* 刪除目錄(文件夾)以及目錄下的文件
*
* @param sPath 被刪除目錄的文件路徑
* @return 目錄刪除成功返回true,否則返回false
*/
public static boolean deleteDirectory(String sPath) {
//如果sPath不以文件分隔符結尾霉猛,自動添加文件分隔符
if (!sPath.endsWith(File.separator)) {
sPath = sPath + File.separator;
}
File dirFile = new File(sPath);
//如果dir對應的文件不存在尺锚,或者不是一個目錄,則退出
if (!dirFile.exists() || !dirFile.isDirectory()) {
return false;
}
boolean flag = true;
//刪除文件夾下的所有文件(包括子目錄)
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
//刪除子文件
if (files[i].isFile()) {
flag = deleteFile(files[i].getAbsolutePath());
if (!flag) {
break;
}
} //刪除子目錄
else {
flag = deleteDirectory(files[i].getAbsolutePath());
if (!flag) {
break;
}
}
}
if (!flag) {
return false;
}
//刪除當前目錄
if (dirFile.delete()) {
return true;
} else {
return false;
}
}
/**
* 轉文件格式
*
* @param img 照片文件
*/
public static byte[] fileToByte(File img) throws Exception {
byte[] bytes = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
BufferedImage bi;
bi = ImageIO.read(img);
ImageIO.write(bi, "jpg", baos);
bytes = baos.toByteArray();
} catch (Exception e) {
// e.printStackTrace();
} finally {
// 關閉輸出流
baos.close();
}
return bytes;
}
}