15.上传文件和下载文件

 

文件下载方式:

  1. 直接通过文件路径下载

  2. 后端: Servlet方式

  3. 后端: ResponseEntity方式

项目目录结构:

项目依赖包:

Vo

Vo: DataGripObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.course.vo;

import java.util.List;

public class DataGripObject {

private long total;
private List<?> rows;

public DataGripObject() {
super();
}

public DataGripObject(long total, List<?> rows) {
super();
this.total = total;
this.rows = rows;
}

public long getTotal() {
return total;
}

public void setTotal(long total) {
this.total = total;
}

public List<?> getRows() {
return rows;
}

public void setRows(List<?> rows) {
this.rows = rows;
}

}

Vo: UploadFile.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package com.course.vo;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;

public class UploadFile {
private Integer id;

private String fileName;

private String contentType;

private Integer size;

private String relativePath;

private String absolutePath;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date uploadTime;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getFileName() {
return fileName;
}

public void setFileName(String fileName) {
this.fileName = fileName == null ? null : fileName.trim();
}

public String getContentType() {
return contentType;
}

public void setContentType(String contentType) {
this.contentType = contentType == null ? null : contentType.trim();
}

public Integer getSize() {
return size;
}

public void setSize(Integer size) {
this.size = size;
}

public String getRelativePath() {
return relativePath;
}

public void setRelativePath(String relativePath) {
this.relativePath = relativePath == null ? null : relativePath.trim();
}

public String getAbsolutePath() {
return absolutePath;
}

public void setAbsolutePath(String absolutePath) {
this.absolutePath = absolutePath == null ? null : absolutePath.trim();
}

public Date getUploadTime() {
return uploadTime;
}

public void setUploadTime(Date uploadTime) {
this.uploadTime = uploadTime;
}
}

Vo: UploadFileVo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.course.vo;

public class UploadFileVo extends UploadFile {

// pageIndex
private Integer page;
// pageSize
private Integer rows;

public Integer getPage() {
return page;
}

public void setPage(Integer page) {
this.page = page;
}

public Integer getRows() {
return rows;
}

public void setRows(Integer rows) {
this.rows = rows;
}

}

Util

Util: FileUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.course.util;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileUtil {

public static String makeUploadDirByDate(String uploadDir) {
// 获取当前系统时间
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
String dateStr = simpleDateFormat.format(date);
String year = dateStr.substring(0, 4);
String month = dateStr.substring(4, 6);
String day = dateStr.substring(6, 8);

String dateDir = year + "/" + month + "/" + day;
File uploadDirByDate = new File(uploadDir, dateDir);
if (!uploadDirByDate.exists()) {
uploadDirByDate.mkdirs();
}

String uploadPath = uploadDirByDate.getAbsolutePath();
return uploadPath;
}

}

Util: RandomUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.course.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

public class RandomUtil {

private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");

private static Random random = new Random();

// 当前时间+ 4位随机数
public static String getRandomFileName1(String originalFileName) {
// 获取文件名类型
int lastDotIndex = originalFileName.lastIndexOf(".");
String suffix = originalFileName.substring(lastDotIndex, originalFileName.length());

// 时间字符串
String timeStr = simpleDateFormat.format(new Date());
// 4位随机数
int randomNum = random.nextInt(9000) + 1000;

String fileName = timeStr + randomNum + suffix;
System.out.println("fileName = " + fileName);
// fileName = 202205082358344585135.jar

return fileName;
}

// uuid
public static String getRandomFileName2(String originalFileName) {
// 获取文件名类型
int lastDotIndex = originalFileName.lastIndexOf(".");
String suffix = originalFileName.substring(lastDotIndex, originalFileName.length());

// 时间字符串
String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String fileName = uuid + suffix;
System.out.println("fileName = " + fileName);
// fileName = 14f2ef3b183b420f9e4d173b6012f2e7.jar

return fileName;
}

// 当前时间毫秒数+ 4位随机数
public static String getRandomFileName3(String originalFileName) {
// 获取文件名类型
int lastDotIndex = originalFileName.lastIndexOf(".");
String suffix = originalFileName.substring(lastDotIndex, originalFileName.length());

// 时间字符串
String time1 = String.valueOf(System.currentTimeMillis());
System.out.println("time1 = " + time1);
String time2 = String.valueOf(new Date().getTime());
System.out.println("time2 = " + time2);
// 4位随机数
String randomNum = String.valueOf(random.nextInt(9000) + 1000);
System.out.println("randomNum = " + randomNum);

String fileName = time1 + randomNum + suffix;
System.out.println("fileName = " + fileName);

/*
* time1 = 1652061343031
* time2 = 1652061343031
* randomNum = 2365
* fileName = 16520613430312365.jar
*/

return fileName;
}

}

Dao

UploadFileMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.course.dao;

import java.util.List;

import com.course.vo.UploadFile;

public interface UploadFileMapper {
int deleteByPrimaryKey(Integer id);

int insert(UploadFile record);

int insertSelective(UploadFile record);

UploadFile selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(UploadFile record);

int updateByPrimaryKey(UploadFile record);

public List<UploadFile> getAllUploadFile();

}

Mapper.xml

UploadFileMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.course.dao.UploadFileMapper" >
<resultMap id="BaseResultMap" type="com.course.vo.UploadFile" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="file_name" property="fileName" jdbcType="VARCHAR" />
<result column="content_type" property="contentType" jdbcType="VARCHAR" />
<result column="size" property="size" jdbcType="INTEGER" />
<result column="relative_path" property="relativePath" jdbcType="VARCHAR" />
<result column="absolute_path" property="absolutePath" jdbcType="VARCHAR" />
<result column="upload_time" property="uploadTime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Base_Column_List" >
id, file_name, content_type, size, relative_path, absolute_path, upload_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from upload_file
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from upload_file
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.course.vo.UploadFile" >
insert into upload_file (id, file_name, content_type,
size, relative_path, absolute_path,
upload_time)
values (#{id,jdbcType=INTEGER}, #{fileName,jdbcType=VARCHAR}, #{contentType,jdbcType=VARCHAR},
#{size,jdbcType=INTEGER}, #{relativePath,jdbcType=VARCHAR}, #{absolutePath,jdbcType=VARCHAR},
#{uploadTime,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="com.course.vo.UploadFile" >
insert into upload_file
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="fileName != null" >
file_name,
</if>
<if test="contentType != null" >
content_type,
</if>
<if test="size != null" >
size,
</if>
<if test="relativePath != null" >
relative_path,
</if>
<if test="absolutePath != null" >
absolute_path,
</if>
<if test="uploadTime != null" >
upload_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="fileName != null" >
#{fileName,jdbcType=VARCHAR},
</if>
<if test="contentType != null" >
#{contentType,jdbcType=VARCHAR},
</if>
<if test="size != null" >
#{size,jdbcType=INTEGER},
</if>
<if test="relativePath != null" >
#{relativePath,jdbcType=VARCHAR},
</if>
<if test="absolutePath != null" >
#{absolutePath,jdbcType=VARCHAR},
</if>
<if test="uploadTime != null" >
#{uploadTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.course.vo.UploadFile" >
update upload_file
<set >
<if test="fileName != null" >
file_name = #{fileName,jdbcType=VARCHAR},
</if>
<if test="contentType != null" >
content_type = #{contentType,jdbcType=VARCHAR},
</if>
<if test="size != null" >
size = #{size,jdbcType=INTEGER},
</if>
<if test="relativePath != null" >
relative_path = #{relativePath,jdbcType=VARCHAR},
</if>
<if test="absolutePath != null" >
absolute_path = #{absolutePath,jdbcType=VARCHAR},
</if>
<if test="uploadTime != null" >
upload_time = #{uploadTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.course.vo.UploadFile" >
update upload_file
set file_name = #{fileName,jdbcType=VARCHAR},
content_type = #{contentType,jdbcType=VARCHAR},
size = #{size,jdbcType=INTEGER},
relative_path = #{relativePath,jdbcType=VARCHAR},
absolute_path = #{absolutePath,jdbcType=VARCHAR},
upload_time = #{uploadTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=INTEGER}
</update>

<!-- 查询得到所有的上传文件 -->
<select id="getAllUploadFile" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from upload_file
</select>

</mapper>

Service

UploadFileService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.course.service;

import com.course.vo.DataGripObject;
import com.course.vo.UploadFile;
import com.course.vo.UploadFileVo;

public interface UploadFileService {

public void saveUploadFileInfo(UploadFile uploadFile);

public DataGripObject queryAllUploadFile(UploadFileVo uploadFileVo);

public UploadFile getUploadFileById(Integer id);

}

UploadFileServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.course.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.course.dao.UploadFileMapper;
import com.course.service.UploadFileService;
import com.course.vo.DataGripObject;
import com.course.vo.UploadFile;
import com.course.vo.UploadFileVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

@Service
public class UploadFileServiceImpl implements UploadFileService {

@Autowired
private UploadFileMapper uploadFileMapper;

@Override
public void saveUploadFileInfo(UploadFile uploadFile) {
uploadFileMapper.insert(uploadFile);
}

@Override
public DataGripObject queryAllUploadFile(UploadFileVo uploadFileVo) {
int pageIndex = uploadFileVo.getPage();
int pageSize = uploadFileVo.getRows();
Page<UploadFile> page = PageHelper.startPage(pageIndex, pageSize);

List<UploadFile> uploadFileList = uploadFileMapper.getAllUploadFile();

long total = page.getTotal();
List<?> rows = uploadFileList;
DataGripObject dataGripObject = new DataGripObject(total, rows);

return dataGripObject;
}

@Override
public UploadFile getUploadFileById(Integer id) {
UploadFile uploadFile = uploadFileMapper.selectByPrimaryKey(id);
return uploadFile;
}

}

Controller

FileController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package com.course.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Date;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.course.service.UploadFileService;
import com.course.util.FileUtil;
import com.course.util.RandomUtil;
import com.course.vo.DataGripObject;
import com.course.vo.UploadFile;
import com.course.vo.UploadFileVo;

@Controller
@RequestMapping("file")
public class FileController {

@Autowired
private UploadFileService uploadFileService;

// 1.上传单个文件(并将上传的文件信息保存到数据库中)
@RequestMapping("upload")
public String upload(MultipartFile testfile, HttpServletRequest httpServletRequest) {
// 1.1 文件原始文件名
String originalFilename = testfile.getOriginalFilename();
// 1.2 获取随机文件名
String randomFileName = RandomUtil.getRandomFileName1(originalFilename);
// 2.1 获取文件上传路径
String fileDir = httpServletRequest.getServletContext().getRealPath("/upload");
// 2.2 获取根据日期分类的文件夹
String uploadDirByDate = FileUtil.makeUploadDirByDate(fileDir);
// 3.创建文件对象
File upFile = new File(uploadDirByDate, randomFileName);
// 4.把文件流写到目的文件中
try {
testfile.transferTo(upFile);
} catch (IOException e) {
e.printStackTrace();
}

// 将上传文件的信息保存到数据库表中
String contentType = testfile.getContentType();
long size = testfile.getSize();
String absolutePath = upFile.getAbsolutePath();
int beginIndex = absolutePath.lastIndexOf("upload");
String relativePath = absolutePath.substring(beginIndex);

UploadFile uploadFile = new UploadFile();
uploadFile.setFileName(originalFilename);
uploadFile.setContentType(contentType);
uploadFile.setSize((int)size);
uploadFile.setRelativePath(relativePath);
uploadFile.setAbsolutePath(absolutePath);
uploadFile.setUploadTime(new Date());
uploadFileService.saveUploadFileInfo(uploadFile);

return "success";
}

@RequestMapping("queryUploadFileList")
@ResponseBody
public DataGripObject queryUploadFileList(UploadFileVo uploadFileVo) {
DataGripObject dataGripObject = uploadFileService.queryAllUploadFile(uploadFileVo);
return dataGripObject;
}

@RequestMapping("downloadFile2")
public void downloadFile2(UploadFileVo uploadFileVo, HttpSession httpSession, HttpServletResponse httpServletResponse) {
Integer id = uploadFileVo.getId();
UploadFile uploadFile = uploadFileService.getUploadFileById(id);
String absolutePath = uploadFile.getAbsolutePath();
String fileName = uploadFile.getFileName();
String contentType = uploadFile.getContentType();

File file = new File(absolutePath);
try {
if (file.exists()) {
// 对原始文件名进行编码,防止中文文件名乱码
String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
httpServletResponse.setContentType(contentType);
httpServletResponse.setHeader("Content-Disposition", "uploadFile; filename=\"" + encodeFileName + "\"");
long fileLength = file.length();
httpServletResponse.setContentLength((int)fileLength);
if (fileLength > 0) {
// 创建输入流
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[4096];
// 创建输出流
ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
int readLength = fileInputStream.read(buffer);
while (readLength != -1) {
servletOutputStream.write(buffer, 0, readLength);
readLength = fileInputStream.read(buffer);
}
fileInputStream.close();
servletOutputStream.flush();
servletOutputStream.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}

}

@RequestMapping("downloadFile3")
public ResponseEntity downloadFile3(UploadFileVo uploadFileVo, HttpSession httpSession, HttpServletResponse httpServletResponse) {
ResponseEntity responseEntity = null;

Integer id = uploadFileVo.getId();
UploadFile uploadFile = uploadFileService.getUploadFileById(id);
String fileName = uploadFile.getFileName();

String relativePath = uploadFile.getRelativePath();
// 获取项目部署的所在路径
String contextPath = httpSession.getServletContext().getRealPath("");
String filePath = contextPath + relativePath;

File file = new File(filePath);
if (file.exists()) {
byte[] buffer = null;
try {
buffer = FileUtils.readFileToByteArray(file);
} catch (IOException e) {
e.printStackTrace();
}
// 创建封装响应头信息的对象
HttpHeaders httpHeaders = new HttpHeaders();
// 相应内容类型,APPLICATION_OCTET_STREAM: 相应的内容不限定
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
Charset charset = Charset.forName("UTF-8");
httpHeaders.setContentDispositionFormData("uploadFile", fileName, charset);

// 创建ResponseEntity对象
responseEntity = new ResponseEntity(buffer, httpHeaders, HttpStatus.CREATED);
}

return responseEntity;

}

}

config

log4j.properties

1
2
3
4
5
6
7
8
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

db.properties

1
2
3
4
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/springmvc_test
username=root
password=123456

mybatis.cfg.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<!-- MyBatis的整体配置 -->
<configuration>

<settings>
<!-- 让log4j去记录sql日志,打印mybatis执行的sql语句 -->
<setting name="logImpl" value="LOG4J"/>
<!-- https://mybatis.org/mybatis-3/zh/configuration.html#properties -->
</settings>

<!-- 使用plugin: PageHelper,不能在application-dao.xml中注入,必须在mybatis.cfg.xml中添加插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

</configuration>

springmvc.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8"?>

<!-- 头文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">


<!--
配置控制器
包扫描
-->
<context:component-scan base-package="com.course.controller"></context:component-scan>

<!--
合并注解的控制器映射器和控制器适配器的配置
对控制器映射器和控制器适配器进行加强,如把对象转化为json字符串
-->
<mvc:annotation-driven></mvc:annotation-driven>

<!-- 配置文件上传的二进制流的解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 指定文件上传的编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 指定文件上传的临时目录 -->
<property name="uploadTempDir" value="/upload/temp"></property>
<!-- 指定文件上传的最大大小(byte) -->
<property name="maxUploadSize" value="20971520"></property>
</bean>

<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/WEB-INF/view/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>

</beans>

application-dao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?xml version="1.0" encoding="UTF-8"?>
<!-- 头文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">


<!-- 解析配置文件 -->
<!--
${username}在Spring里默认取的是当前的主机名,
如果想禁用取主机名可以使用system-properties-mode="FALLBACK"
-->
<context:property-placeholder location="classpath:db.properties" system-properties-mode="FALLBACK"/>

<!-- 声明数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 注入相关属性 -->
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>

<!-- 声明sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 注入mybatis.cfg.xml -->
<property name="configLocation" value="classpath:mybatis.cfg.xml"></property>


<property name="mapperLocations">
<array>
<value>classpath:com/course/mapper/*.xml</value>
</array>
</property>

<!-- 使用plugin: PageHelper,不能在application-dao.xml中注入,必须在mybatis.cfg.xml中添加插件 -->
<!--
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor"></bean>
</array>
</property>
-->

</bean>

<!--
配置接口扫描
因为UserMapper.java没有实现类,所以必须依靠cglib在内存中构造代理对象
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入mapper接口所在的包 -->
<property name="basePackage" value="com.course.dao"></property>

<!--
如果有多个mapper接口,value可以为数组,用逗号或者换行分割
<property name="basePackage" value="com.course.dao,com.course.dao2"></property>

<property name="basePackage">
<value>
com.course.dao
com.course.dao2
</value>
</property>
-->

<!--
注入sqlSessionFactory
因为是BeanName,所以是value,不是ref
-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>

</beans>

application-service.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="UTF-8"?>
<!-- 头文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">


<!-- 声明式事务的配置开始 -->
<!-- 1.声明事务管理器 -->
<!-- 用Spring自带的事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 2.声明通知方式 -->
<tx:advice id="advice" transaction-manager="transactionManager">
<!-- 配置那些方法要加入事务 -->
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="borrow*" propagation="REQUIRED"/>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="query*" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>

<!-- 3.进行AOP配置 -->
<aop:config>
<!-- 声明切面 -->
<!-- 事务应该加在service层,不应该加在dao层 -->
<aop:pointcut id="pc" expression="execution(* com.course.service.impl.*.*(..))"/>
<!-- 织入 -->
<aop:advisor advice-ref="advice" pointcut-ref="pc"/>
</aop:config>
<!-- 声明式事务的配置结束 -->

<!-- 声明Service -->
<!-- <bean id="userService" class="com.course.service.impl.UserServiceImpl" autowire="byType"></bean> -->

<context:component-scan base-package="com.course.service"></context:component-scan>

</beans>

applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<!-- 头文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">


<import resource="classpath:application-dao.xml"/>
<import resource="classpath:application-service.xml"/>

</beans>

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>05_ssm</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<!-- 配置SpringMVC编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 配置编码的值 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<!--
方法1: <url-pattern>*.do</url-pattern>
<url-pattern>/*</url-pattern>
-->
<!-- 指定某个servlet去过滤 -->
<servlet-name>springmvc</servlet-name>
</filter-mapping>

<!-- 配置Spring的监听器,在项目启动时加载applicationContext.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置applicationContext.xml的地址 -->
<context-param>
<!-- ContextLoaderListener的父类ContextLoader的属性 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

<!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!-- 加载springmvc.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>

<!-- 启动加载 -->
<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

</web-app>

jsp

uploadFile.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<h2>1.上传单个文件(并将上传的文件信息保存到数据库中)</h2>
<form action="file/upload.do" method="post" enctype="multipart/form-data">
选择文件: <input type="file" name="testfile">
<br/>
<input type="submit" value="提交">
</form>

</body>
</html>

success.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p>上传成功!</p>
</body>
</html>

uploadFileList.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Basic CRUD Application - jQuery EasyUI CRUD Demo</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/easyui/themes/metro/easyui.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/easyui/themes/icon.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/easyui/themes/color.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/easyui/demo/demo.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/easyui/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/easyui/locale/easyui-lang-zh_CN.js"></script>
</head>
<body>
<h2 align="center">所有用户</h2>
<table id="dg" title="所有用户" iconCls="icon-help" class="easyui-datagrid" style="width:100%;height:550px"
url="${pageContext.request.contextPath}/file/queryUploadFileList.do"
toolbar="#toolbar" pagination="true"
rownumbers="true" fitColumns="true" singleSelect="true">
<thead>
<tr>
<th field="id" width="50" align="center">ID</th>
<th field="fileName" width="50">文件名</th>
<th field="contentType" width="50">文件类型</th>
<th field="size" width="50">文件大小(B)</th>
<th field="absolutePath" width="200">文件路径</th>
<th field="uploadTime" width="50">上传时间</th>
</tr>
</thead>
</table>
<div id="toolbar">
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="downloadFile1()">下载文件【直接路径】</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" plain="true" onclick="downloadFile2()">下载文件【HttpServletResponse】</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" plain="true" onclick="downloadFile3()">下载文件【ResponseEntity】</a>
</div>
</body>
<script type="text/javascript">
function downloadFile1() {
var row = $("#dg").datagrid("getSelected");
if (row) {
window.location.href = "${pageContext.request.contextPath}/" + row.relativePath;
} else {
$.messager.show({
title: "提示",
iconCls: "icon-no",
msg: "请选中一行"
});
}
}

function downloadFile2() {
var row = $("#dg").datagrid("getSelected");
if (row) {
window.location.href = "${pageContext.request.contextPath}/file/downloadFile2.do?id=" + row.id;
} else {
$.messager.show({
title: "提示",
iconCls: "icon-no",
msg: "请选中一行"
});
}
}

function downloadFile3() {
var row = $("#dg").datagrid("getSelected");
if (row) {
window.location.href = "${pageContext.request.contextPath}/file/downloadFile3.do?id=" + row.id;
} else {
$.messager.show({
title: "提示",
iconCls: "icon-no",
msg: "请选中一行"
});
}
}

</script>

</html>

打开浏览器