本项目使用了ajax、ssm、layui。为了实现效果为在表单输入时判断该字段是否在数据库中存在以及文件上传的功能。
- 如下图所示
知识编号为21的值已经在数据库中存在,但是业务要求知识编号不能重复,所以在表单提交的时候首先需要判断该值是否存在。如果存在则提示重新输入
文件上传且支持多文件上传。并提供缩略图。
准备工作
- 我们使用的框架是ssm即springMVC + spring + mybatis ,使用了maven来构建项目。并且使用了json解析格式。
第一步:在pom.xml文件引入依赖坐标
commons-fileupload
commons-fileupload
1.3.3
com.alibaba
fastjson
1.2.68
javax.annotation
jsr250-api
1.0
com.fasterxml.jackson.core
jackson-core
2.9.8
com.fasterxml.jackson.core
jackson-databind
2.9.8
com.fasterxml.jackson.core
jackson-annotations
2.9.8
第二步:在spirng的配置文件applicationContext.xml文件中引入文件上传所需的multipartResolver对象
第三步:在spirngmvc的配置文件springmvc.xml文件中配置json
text/html; charset=UTF-8
application/json;charset=UTF-8
text/html; charset=UTF-8
application/json;charset=UTF-8
- 到这里准备工作完毕,下面开始进行业务
前端界面
- 前端使用的是JSP界面,使用的layui前端框架快速搭建
- 由于在这个页面,使用了表单数据验证、文件上传、表单提交
表单样式
ajax使用
- 在js这里,因为我们使用了layui。所以我们首先提供layui.use([可选模块],function{})方法引入模块。再定义layui模块使用函数
- 在ajax里,我们需要配置以下:
// 调用ajax进行异步提交
$.ajax({
type: 'post',
dataType: "json",
url: '', // 你的url地址
//async: true, 是否开启异步操作,默认为ture,为异步调用。false为同步调用
data: {}, // 需要传输到后台的数据
success: function (res) {
// 异步操作执行成功后调用的方法
},
error: function (err) {
// 异步操作执行错误后调用的方法
}
});
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后,后台控制层执行方法成功,但就是不调用success方法,一直调用error方法。
- 原因:后台返回的参数不是json类型。由于ajax规定后台参数必须是json类型,如果返回的参数(列表,对象)都正确,因为不是json类型,则一样调用error方法。
- 解决: 后台使用map返回,使用@ResponseBody注解
@RequestMapping("拦截路径")
@ResponseBody
public Object findByMId(String mId) throws Exception {
HashMap map = new HashMap<>();
// 方法省略
return map;
}
js代码
后台代码
- 业务1:判断知识编号是否已存在,如存在则提示信息。
controller
/**
* 判断知识编号是否存在
*/
@RequestMapping("/toVerifyByKId.do")
@ResponseBody
public boolean toVerifyByKId(Knowledge knowledge){
String KId = knowledge.getkId();
if (KId!=null) {
List knowledge1 = knowledgeService.findByKId(KId);
System.out.println(knowledge1);
if (knowledge1.size()==0) {
return true;
}
}
System.out.println("知识编号存在");
return false;
}
- 业务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;
}
}