- 5.1 需求
- 5.2 名词解释
- 5.3 目标
- 5.4 案例实现步骤
- 5.4.1 数据库环境搭建
- 5.4.2 开发环境搭建
- 5.4.3 功能实现-展示所有债权信息
- 1)在CreditorInfoController类中创建index方法,将CreditorInfoService注入到controller中
- 2)在CreditorInfoService中提供getAllCreditorInfo方法
- 3)在CreditorInfoServiceImpl中对getAllCreditorInfo方法进行实现
- 4)因为是SpringBoot项目,所以需要在Mapper接口上加一个Mapper注解
- 5)在CreditorInfoMapper类中添加selectAllCreditorInfo方法
- 6)在IDEA中安装free Mybatis插件
- 7)在CreditorInfoMapper.xml文件中添加SQL语句
- 8)展示页面的设计
- 9)向数据库中加几条数据
- http://localhost:8080/fastdfs/index查看效果">10)启动项目,访问http://localhost:8080/fastdfs/index查看效果
- 11)调整页面样式
- 5.4.4 功能实现-为某一个债权合同上传文件
- 1)在index.html中添加操作列
- 2)在CreditorController中添加跳转到上传页面的方法
- 3)在templates下创建upload.html页面
- 4)在pom.xml文件中加入FastDFS客户端的jar包依赖
- 5)将FastDFS客户端的配置文件fast_client.conf拷贝到resources目录下
- 6)将原来我们封装的FastDFS类拷贝到fastdfs包下,修改其中的file_upload方法,定义一些参数
- 7)在CreditorController中添加处理上传文件的方法
- 8)在CreditorInfoService中添加updateCreditorInfo方法
- 9)在CreditorInfoServiceImpl中添加updateCreditorInfo方法实现
- 10)在upload.html做一个类似ajax的页面不刷新效果
- 11)如果上传文件超出了1M,需要在application.properties中配置SpringBoot上传文件的最大限制
- 5.4.5 功能实现-下载某一个债权合同
- 5.4.6 功能实现-删除某一个债权合同,使用ajax实现异步删除
- 5.4.7 功能实现-弹层组建layer的使用(简单介绍)
5.1 需求
对P2P项目合同进行管理,在WEB项目中实现对文件的上传下载和删除操作
5.2 名词解释
- 有一些债权:投资人有该债务的权利
通常隐含的意思就是:一笔借款常被称为一个债权
- 一个债权会有一个合同
- 合同是pdf文件
债权是债务的对应词,但是在P2P项目中,我们管理的债权,以及合同一般指的是借款人的信息,所以在我们下面创建的creditor_info表中存的是借款人信息
5.3 目标
实现对pdf文件上传、下载、删除
- 熟练一下Springboot+thymeleaf
5.4 案例实现步骤
5.4.1 数据库环境搭建
1)创建数据库fastdfs
2)在该库下创建creditor_info表
CREATE TABLE `creditor_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`real_name` varchar(35) DEFAULT NULL COMMENT '债权借款人姓名',
`id_card` varchar(18) DEFAULT NULL COMMENT '债权借款人身份证',
`address` varchar(150) DEFAULT NULL COMMENT '债权借款人地址',
`sex` int(1) DEFAULT NULL COMMENT '1男2女',
`phone` varchar(11) DEFAULT NULL COMMENT '债权借款人电话',
`money` decimal(10,2) DEFAULT NULL COMMENT '债权借款人借款金额',
`group_name` varchar(10) DEFAULT NULL COMMENT '债权合同所在组',
`remote_file_path` varchar(150) DEFAULT NULL COMMENT '债权合同所在路径',
`old_filename` varchar(255) DEFAULT NULL COMMENT '文件上传前的名字,用于下载文件时指定默认的文件名',
`file_size` bigint(20) DEFAULT NULL COMMENT '文件大小,用于下载文件时提供下载进度',
`file_type` varchar(255) DEFAULT NULL COMMENT '文件类型',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
5.4.2 开发环境搭建
1)创建SpringBoot项目10-fastdfs-web,添加Web和Thymeleaf依赖
2)在pom.xml文件中添加Mybatis依赖及MySQL依赖
```xmlorg.mybatis.spring.boot mybatis-spring-boot-starter 1.3.2 mysql mysql-connector-java
<a name="l3MJY"></a>
#### 3)在pom.xml文件中添加resources,指定编译的位置
```xml
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<!--如果存在jsp,需要指定jsp文件编译的位置-->
</resources>
4)在SpringBoot主配置文件application.properties中添加数据库配置信息
#数据库的连接配置信息
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.235.128:3306/fastdfs?useUnicode=true&characterEncoding=utf8&useSSL=false
5)使用Mybatis反向工程,生成实体类及mapper映射(参照SpringBoot附录教程)
A、在pom.xml文件中添加反向工程插件
<!--mybatis代码自动生成插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<!--配置文件的位置-->
<configurationFile>GeneratorMapper.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
B、从03-springboot-web中复制GeneratorMapper.xml到当前项目下
C、修改GeneratorMapper.xml配置文件内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 指定连接数据库的JDBC驱动包所在位置,指定到你本机的完整路径 -->
<classPathEntry location="D:/repository/mysql/mysql-connector-java/8.0.13/mysql-connector-java-8.0.13.jar"/>
<!-- 配置table表信息内容体,targetRuntime指定采用MyBatis3的版本 -->
<context id="tables" targetRuntime="MyBatis3">
<!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 配置数据库连接信息 注意:使用高版本的驱动 url后面应该加属性nullCatalogMeansCurrent=true,否则生成有问题 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://192.168.235.128:3306/fastdfs?nullCatalogMeansCurrent=true"
userId="root"
password="123456">
</jdbcConnection>
<!-- 生成model类,targetPackage指定model类的包名, targetProject指定生成的model放在eclipse的哪个工程下面-->
<javaModelGenerator targetPackage="com.bjpowernode.fastdfs.model" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="false" />
</javaModelGenerator>
<!-- 生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名, targetProject指定生成的mapper.xml放在eclipse的哪个工程下面 -->
<sqlMapGenerator targetPackage="com.bjpowernode.fastdfs.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名, targetProject指定生成的Mapper接口放在eclipse的哪个工程下面 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.bjpowernode.fastdfs.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 数据库表名及对应的Java模型类名 -->
<table tableName="creditor_info"
domainObjectName="CreditorInfo"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
D、双击生成
6)创建相关的包和类
- 在com.bjpowernode.fast包下创建controller ,service 包,及其子包impl
- 创建CreditorInfoController类
- 创建CreditorInfoService接口
- 创建CreditorInfoServiceImpl实现类
5.4.3 功能实现-展示所有债权信息
1)在CreditorInfoController类中创建index方法,将CreditorInfoService注入到controller中
@Controller
public class CreditorInfoController {
@Autowired
private CreditorInfoService creditorInfoService;
@GetMapping("/fastdfs/index")
public String index(Model model){
List<CreditorInfo> creditorInfoList = creditorInfoService.getAllCreditorInfo();
model.addAttribute("creditorInfoList",creditorInfoList);
//模板页面,不是jsp
return "index";
}
}
2)在CreditorInfoService中提供getAllCreditorInfo方法
public interface CreditorInfoService {
/**
* 获取所有债权信息
* @return
*/
List<CreditorInfo> getAllCreditorInfo();
}
3)在CreditorInfoServiceImpl中对getAllCreditorInfo方法进行实现
@Service
public class CreditorInfoServiceImpl implements CreditorInfoService {
@Autowired
private CreditorInfoMapper creditorInfoMapper;
@Override
public List<CreditorInfo> getAllCreditorInfo() {
return creditorInfoMapper.selectAllCreditorInfo();
}
}
4)因为是SpringBoot项目,所以需要在Mapper接口上加一个Mapper注解
@Mapper
public interface CreditorInfoMapper {
}
5)在CreditorInfoMapper类中添加selectAllCreditorInfo方法
List<CreditorInfo> selectAllCreditorInfo();
6)在IDEA中安装free Mybatis插件
该插件可以通过点击Mapper接口中的方法,进入到.xml文件
**
A、Setting->plugin->Browse repositories
B、在插件库中搜索,free mybatis安装
C、插件安装完毕,需要重启IDEA
7)在CreditorInfoMapper.xml文件中添加SQL语句
<select id="selectAllCreditorInfo" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from creditor_info
</select>
8)展示页面的设计
A、在项目的templates目录下创建index.html
B、百度搜索bootstrap表格,挑选自己喜欢风格的表格,将代码拷贝到index.html中
我这里使用的是http://www.runoob.com/try/try.php?filename=bootstrap3-table-striped表格进行改写
C、在html标签上加上Thymeleaf的命名空间
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
D、修改index.html内容
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>债权合同管理</title>
<link rel="stylesheet" th:href="@{/css/bootstrap-3.3.7.min.css}">
<script th:src="@{/js/jquery-2.1.1.min.js}"></script>
<script th:src="@{/js/bootstrap-3.3.7.min.js}"></script>
</head>
<body>
<table class="table table-striped">
<caption>债权合同信息列表</caption>
<thead>
<tr>
<th>序号</th>
<th>债权借款人姓名</th>
<th>债权借款人身份证</th>
<th>债权借款人住址</th>
<th>债权借款人手机号</th>
<th>债权借款人性别</th>
<th>债权借款人借款金额</th>
</tr>
</thead>
<tbody>
<tr th:each="creditorInfo:${creditorInfoList}">
<td th:text="${creditorInfoStat.count}"></td>
<td th:text="${creditorInfo.realname}"></td>
<td th:text="${creditorInfo.idcard}"></td>
<td th:text="${creditorInfo.address}"></td>
<td th:text="${creditorInfo.phone}"></td>
<td th:text="${creditorInfo.sex == 1 ?'男':'女'}"></td>
<td th:text="${creditorInfo.money}"></td>
</tr>
</tbody>
</table>
</body>
</html>
注意:我们从网络上拷贝过来的内容css,js等是联网获取的,我们这里可以从04-FastDFS\resources获取,并放在项目的static的相关目录下,在页面上引用
**
9)向数据库中加几条数据
10)启动项目,访问http://localhost:8080/fastdfs/index查看效果
11)调整页面样式
<body style="margin: 50px">
5.4.4 功能实现-为某一个债权合同上传文件
1)在index.html中添加操作列
<th>合同管理</th>
<td>
<!--为哪个合同上传,需要将合同的id传递过去-->
<a th:href="@{'/fastdfs/toUpload?id=' + ${creditorInfo.id}}">上传</a>
下载
删除
</td>
2)在CreditorController中添加跳转到上传页面的方法
@GetMapping("/fastdfs/toUpload")
public String toUpload(Model model, @RequestParam("id") Integer id){
model.addAttribute("id",id);
return "upload";
}
3)在templates下创建upload.html页面
在网上搜索bootstrap表单,并对其内容进行修改,我这里使用的是http://www.runoob.com/try/try2.php?filename=bootstrap3-form-inline
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>债权合同上传</title>
<link rel="stylesheet" th:href="@{/css/bootstrap-3.3.7.min.css}">
<script th:src="@{/js/jquery-2.1.1.min.js}"></script>
<script th:src="@{/js/bootstrap-3.3.7.min.js}"></script>
</head>
<body>
<form th:action="@{/fastdfs/upload}" class="form-inline" role="form" method="post" enctype="multipart/form-data">
<div class="form-group">
<label class="sr-only" for="fileName">文件输入</label>
<input type="file" id="fileName" name="fileName">
</div>
<input type="hidden" name="id" th:value="${id}">
<button type="submit" class="btn btn-default">提交</button>
</form>
</body>
</html>
注意
- 文件上传必须是post请求
- enctype必须为multipart/form-data
- 合同的id通过隐藏域传递
4)在pom.xml文件中加入FastDFS客户端的jar包依赖
<!--加入FastDFS的java客户端依赖-->
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27-SNAPSHOT</version>
</dependency>
5)将FastDFS客户端的配置文件fast_client.conf拷贝到resources目录下
connect_timeout=20
network_timeout=60
charset=UTF-8
http.tracker_http_port=8080
http.anti_steal_token=no
http.secret_key=FastDFS1234567890
tracker_server=47.95.113.235:22122
6)将原来我们封装的FastDFS类拷贝到fastdfs包下,修改其中的file_upload方法,定义一些参数
/**
* 文件上传
*/
public static String[] upload(byte[] buffFile,String fileExtName) {
TrackerServer trackerServer = null;
StorageServer storageServer = null;
try {
//读取FastDFS的配置文件用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fdfs_client.conf");
TrackerClient trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = trackerClient.getStoreStorage(trackerServer);
//定义StorageClient的客户端,需要使用这个对象来完成具体的文件上传、下载和删除操作
StorageClient storageClient = new StorageClient(trackerServer,storageServer);
/**
* 文件上传
* 参数1:为需要的上传的文件的绝对路径
* 参数2:为需要上传文件的扩展名
* 参数3:为文件的属性文件,通常不上传
*
* 返回一个String数组 这个数组对我们非常重要,必须要妥善保管建议存入到数据库中
*
*/
String[] result = storageClient.upload_file(buffFile,fileExtName,null);
return result;
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
} finally {
if(trackerServer != null){
try {
trackerServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(storageServer != null){
try {
storageServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
7)在CreditorController中添加处理上传文件的方法
/**
* 文件上传
* 参数MultipartFile 为Spring提供的一个类,专门用于封装请求中的文件数据
* 属性名称必须与表单中文件域的名字完全相同,否则无法获取到文件数据
*
* @param id
* @param myFile
* @param model
* @return
* @throws IOException
*/
@PostMapping(value = "/upload")
public String upload(Integer id, MultipartFile myFile,Model model) throws IOException {
System.out.println(myFile.getBytes()); //获得文件对应的字节数组
System.out.println(myFile.getInputStream()); //获得问价对应的输入流
System.out.println(myFile.getContentType()); //获得文件的类型
System.out.println(myFile.getName()); //获得表单的元素名
System.out.println(myFile.getOriginalFilename()); //获得文件名
System.out.println(myFile.getSize()); //获得文件的大小
System.out.println(myFile.isEmpty()); //判断文件是否为空 如果没有上传文件或文件的大小为0 这个值都是true
//获取文件对应的字节数组
byte[] buffFile = myFile.getBytes();
//获取文件的名称
String fileName = myFile.getOriginalFilename();
//获取文件的大小
long fileSize = myFile.getSize();
//获取文件的类型
String fileType = myFile.getContentType();
//获取文件的扩展名
String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
//调用工具类,实现文件的上传
String[] upload = FastDFSUtils.upload(buffFile, fileExtName);
//创建对象,进行封装
CreditorInfo creditorInfo = new CreditorInfo();
creditorInfo.setId(id);
creditorInfo.setFileSize(fileSize);
creditorInfo.setFileType(fileType);
creditorInfo.setOldFilename(fileName);
creditorInfo.setGroupName(upload[0]);
creditorInfo.setRemoteFilePath(upload[1]);
//调用service方法进行上传文件的数据的保存
creditorInfoService.updateFileInfo(creditorInfo);
model.addAttribute("message","文件上传成功,点击确定返回列表页面!");
model.addAttribute("url","/index");
return "success";
}
8)在CreditorInfoService中添加updateCreditorInfo方法
/**
* 更新债权信息
* @param creditorInfo
* @return
*/
int updateCreditorInfo(CreditorInfo creditorInfo);
9)在CreditorInfoServiceImpl中添加updateCreditorInfo方法实现
@Override
public int updateCreditorInfo(CreditorInfo creditorInfo) {
return creditorInfoMapper.updateByPrimaryKeySelective(creditorInfo);
}
10)在upload.html做一个类似ajax的页面不刷新效果
- 在upload.html页面中加一个iframe
- upload.html页面中的form中的target设置为iframe的name
- 在iframe的父页面中,写一个函数,处理上传结果
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>债权合同上传</title>
<link rel="stylesheet" th:href="@{/css/bootstrap-3.3.7.min.css}">
<script th:src="@{/js/jquery-2.1.1.min.js}"></script>
<script th:src="@{/js/bootstrap-3.3.7.min.js}"></script>
</head>
<body>
<form th:action="@{/fastdfs/upload}" class="form-inline" role="form" method="post" target="uploadFrame" enctype="multipart/form-data">
<div class="form-group">
<label class="sr-only" for="fileName">文件输入</label>
<input type="file" id="fileName" name="fileName">
</div>
<input type="hidden" id="id" name="id" th:value="${id}">
<button type="submit" class="btn btn-default">提交</button>
</form>
<iframe name="uploadFrame" style="display: none;"></iframe>
<script type="text/javascript" th:inline="javascript">
function uploadOK(result){
if(result == 0){
//文件上传成功
alert("文件上传成功");
var contextPath = [[${#request.getContextPath()}]];
window.location.href = contextPath + "/fastdfs/index";
}else{
alert("文件上传失败");
}
}
</script>
</body>
</html>
11)如果上传文件超出了1M,需要在application.properties中配置SpringBoot上传文件的最大限制
#SpringBoot上传文件的最大限制
spring.servlet.multipart.max-file-size=10MB
注意:如果提示找不到tracker_server,看看是否编译到target中
5.4.5 功能实现-下载某一个债权合同
1)修改index.html页面,下载加连接,并做判断
<td>
<span th:if="${creditorInfo.getGroupname() ne null && creditorInfo.remotefilepath ne null}">
<a th:href="@{'/fastdfs/download?id=' + ${creditorInfo.id}}">下载</a>
删除
</span>
<span th:unless="${creditorInfo.getGroupname() ne null && creditorInfo.remotefilepath ne null}">
<!--为哪个合同上传,需要将合同的id传递过去-->
<a th:href="@{'/fastdfs/toUpload?id=' + ${creditorInfo.id}}">上传</a>
</span>
</td>
2)在CreditorController中,完成下载的请求
- ResponseEntity通常用于返回文件流
- @ResponseBody可以直接返回Json结果,
- @ResponseEntity不仅可以返回json结果,还可以定义返回的HttpHeaders和HttpStatus
- ResponseEntity的优先级高于@ResponseBody。在不是ResponseEntity的情况下才去检查有没有
@ResponseBody注解。如果响应类型是ResponseEntity可以不写@ResponseBody注解,写了也没有关系。
/**
* 完成下载
* @param id 需要下载的文件主键
* @return ResponseEntity 表示一个响应的实体,这个类时Spring提供的一个类,这个类是Spring响应数据时的一个对象
* 这个对象包含则响应时的编码例如404,100等等 ,以及响应的头文件信息,以及响应时的具体的数据
* 这个数据可以时一段html代码,也可以是一段js,也可以是一段普通的字符串,也可以是一个文件流
*/
@GetMapping(value = "/download/{id}")
public ResponseEntity<byte[]> download(@PathVariable("id") Integer id){
CreditorInfo creditorInfo = creditorInfoService.queryById(id);
//获取文件的组名
String groupName = creditorInfo.getGroupName();
//获取远程的文件名
String remoteFilePath = creditorInfo.getRemoteFilePath();
//调用下载的方法,返回byte数据
byte[] buffFile = FastDFSUtils.download(groupName, remoteFilePath);
HttpHeaders headers = new HttpHeaders();
//设置响应类型为文件类型
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//设置响应时的文件的大小用于自动提供下载进度
headers.setContentLength(creditorInfo.getFileSize());
//设置下载时默认的文件名
headers.setContentDispositionFormData("attachment",creditorInfo.getOldFilename());
/**
* 创建响应实体的对象,Spring会将这个对象返回给浏览器,作为响应数据
* 参数1:为响应时的具体数据
* 参数2:为响应时的头文件信息
* 参数3:为响应时状态码
*/
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(buffFile,headers, HttpStatus.OK);
return responseEntity;
}
3)在CreditorService接口中添加getCreditorInfoById的方法
/**
* 根据合同id获取债权信息
* @param id
* @return
*/
CreditorInfo getCreditorInfoById(Integer id);
4)在CreditorServiceImpl中添加getCreditorInfoById方法的实现
@Override
public CreditorInfo getCreditorInfoById(Integer id) {
return creditorInfoMapper.selectByPrimaryKey(id);
}
5)修改FastDFS类中fileDown方法的实现,传递参数
/**
* 文件下载
*/
public static byte[] download(String groupName,String remoteFileName){
TrackerServer trackerServer = null;
StorageServer storageServer = null;
try {
//读取FastDFS的配置文件用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fdfs_client.conf");
TrackerClient trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = trackerClient.getStoreStorage(trackerServer);
//定义StorageClient的客户端,需要使用这个对象来完成具体的文件上传、下载和删除操作
StorageClient storageClient = new StorageClient(trackerServer,storageServer);
/**
* 文件下载
* 参数1:需要下载文件的组名
* 参数2:需要下载文件的远程文件名
* 参数3:需要保存的本地文件名
*
* 返回一个int类型的数据 返回0 表示文件下载成功其它值表示文件下载失败
*/
byte[] bytes = storageClient.download_file(groupName, remoteFileName);
return bytes;
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
} finally {
if(trackerServer != null){
try {
trackerServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(storageServer != null){
try {
storageServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
6)浏览器访问下载测试效果
5.4.6 功能实现-删除某一个债权合同,使用ajax实现异步删除
1)在index.html页面为删除加超链接
<span th:if="${creditorInfo.getGroupname() ne null && creditorInfo.remotefilepath ne null}">
<a th:href="@{'/fastdfs/download?id=' + ${creditorInfo.id}}">下载</a>
<a th:href="@{'javascript:deleteFile('+ ${creditorInfo.id} +')'}">删除</a>
</span>
2)在index.html页面提供js方法,并发送ajax请求,对响应结果进行处理
<script type="text/javascript" th:inline="javascript">
function deleteFile(id){
//获取项目的上下文根
var contextPath = [[${#request.getContextPath()}]];
$.ajax({
url:contextPath +"/fastdfs/fileDelete",
type:"post",
data:{
"id":id
},
success:function(responseMsg){
if(responseMsg==0){
alert("删除成功");
window.location.reload();
}else{
alert("删除失败");
}
}
});
}
</script>
3)在CreditorController中处理删除请求
注意:删除FastDFS和清除数据库,所以我们将这些业务都放在service中进行事务的处理
@RequestMapping("/fastdfs/fileDelete")
public @ResponseBody String fileDelete(@RequestParam("id") Integer id){
int result = 1;
try {
result = creditorService.deleteContract(id);
} catch (Exception e) {
e.printStackTrace();
}
return String.valueOf(result);
}
4)在CreditorService接口中加删除合同的方法deleteContract
因为目前提供的方法,如果group和remoteFilePath为空就不更新,所以我们需要自己提供
/**
* 删除合同
* @param id
* @return
*/
int deleteContract(Integer id);
5)在CreditorServiceImpl类中对deleteContract方法进行实现
@Override
@Transactional //加上该注解控制事务
public int deleteContract(Integer id) {
// 1 删除失败;0 删除成功
int result = 1;
//根据债权id获取债权信息
CreditorInfo creditorInfo = creditorInfoMapper.selectByPrimaryKey(id);
/**
* 注意:事务控制的数据库,所以我们先对数据库进行更新,在操作FastDFS
* 如果操作FastDFS失败了,那么对数据库的操作回滚
*/
//更新数据库债权表的合同路径及组
int updateRow = creditorInfoMapper.updateConstractById(id);
if(updateRow > 0){
//如果数据库更新成功,那么删除FastDFS上的文件
int num = FastDFS.fileDelete(creditorInfo.getGroupname(),creditorInfo.getRemotefilepath());
if(num == 0){
//如果删除成功,那么将整个操作结果设置为0,表示成功
result = 0;
}else{
//如果删除FastDFS上的文件失败,我们抛出一个运行异常,回滚事务
throw new RuntimeException("FastDFS文件删除失败");
}
}
return result;
}
6)在CreditorMapper类中添加更新的方法
/**
* 根据债权的id,将组和合同路径更新为null
* @param id
* @return
*/
int updateConstractById(Integer id);
7)在CreditorMapper.xml中添加更新的方法
<update id="updateConstractById" parameterType="java.lang.Integer">
update creditor_info
set
groupName = NULL ,
remoteFilePath = NULL
where id = #{id,jdbcType=INTEGER}
</update>
8)修改FastDFS类中的fileDelete方法,提供参数
//删除文件的方法
public static int fileDelete(String group ,String remoteFile){
int num = 1;
try {
//1. 获取StorageClient对象
StorageClient storageClient = getStorageClient();
//2.删除文件 返回0表示成功,其它均表示失败
num = storageClient.delete_file(group,remoteFile);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
} finally {
closeFastDFS();
}
return num;
}
9)在Application类上开启事务支持
@EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
5.4.7 功能实现-弹层组建layer的使用(简单介绍)
官网:https://www.layui.com/
2018开源软件排行比较靠前