1.前言
上传文件的功能在开发中很常见,趁着刚做完一个项目中上传头像的功能,将流程记录下来方便以后复用,也有利于加深印象。
为了避免影响理解,做了简化,用户类只设置了两个字段,一个是用户id,一个是用户头像存储路径。
2.目录结构
3.功能实现
controller层
- UploadController
@Controller
public class UploadController {
@Autowired
UserService userService;
@PostMapping("/upload")
public String upload(MultipartFile file, HttpSession session) throws IOException {
//获取文件的内容
InputStream is = file.getInputStream();
//获取原始文件名
String originalFilename = file.getOriginalFilename();
//生成一个uuid名称出来
String uuidFilename = UploadUtils.getUUIDName(originalFilename);
//产生一个随机目录
String randomDir = UploadUtils.getDir();
File fileDir = new File("D:/uploadfiles" + randomDir);
//若文件夹不存在,则创建出文件夹
if (!fileDir.exists()) {
fileDir.mkdirs();
}
//创建新的文件夹
File newFile = new File("D:/uploadfiles" + randomDir, uuidFilename);
//将文件输出到目标的文件中
file.transferTo(newFile);
//将保存的文件路径更新到用户信息headimg中
String savePath = randomDir + "/" + uuidFilename;
//获取当前的user
User user = (User) session.getAttribute("user");
//设置头像图片路径
user.setAvatar(savePath);
//调用业务更新user
userService.update(user);
//生成响应 : 跳转去用户详情页面
return "redirect:/userInfo";
}
@Autowired
ResourceLoader resourceLoader;
@GetMapping("/get/{dir1}/{dir2}/{filename:.+}")
public ResponseEntity get(@PathVariable String dir1,
@PathVariable String dir2,
@PathVariable String filename) {
//1.根据用户名去获取相应的图片
Path path = Paths.get("D:/uploadfiles" + "/" + dir1 + "/" + dir2, filename);
//2.将文件加载进来
Resource resource = resourceLoader.getResource("file:" + path.toString());
//返回响应实体
return ResponseEntity.ok(resource);
}
}
- UserController
@Controller
public class UserController {
@Autowired
UserService userservice;
@GetMapping("/userInfo")
public String userInfo(HttpSession session) {
//从session获取User对象
User user = (User) session.getAttribute("user");
//如果用户为空,则创建新的对象
if (user == null) {
user = new User();
user.setUid(UUID.randomUUID().toString());
//设置默认头像
String avatar = "/0/D/359EC8DE4BE24833A4BAFA98136E0A67.jpeg";
user.setAvatar(avatar);
session.setAttribute("user",user);
}
//否则直接进入用户信息页面
return "userInfo";
}
}
dao层
public interface UserRepository extends JpaRepository<User,String> {
}
service层接口
public interface UserService {
//更新用户信息
void update(User user);
}
service层实现类
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserRepository userRepository;
@Override
public void update(User user) {
userRepository.save(user);
}
}
entity层
@Entity
@Table(name = "user")
public class User {
//用户id
@Id
private String uid;
//用户头像路径
private String avatar;
public User() {
}
public User(String uid, String username, String password, String avatar) {
this.uid = uid;
this.avatar = avatar;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
@Override
public String toString() {
return "User{" +
"uid='" + uid + '\'' +
", avatar='" + avatar + '\'' +
'}';
}
}
工具类
public class UploadUtils {
/**
* 获取文件真实名称
* 由于浏览器的不同获取的名称可能为:c:/upload/1.jpg或者1.jpg
* 最终获取的为 1.jpg
* @param name 上传上来的文件名称
* @return 真实名称
*/
public static String getRealName(String name) {
//获取最后一个"/"
int index = name.lastIndexOf("\\");
return name.substring(index + 1);
}
/**
* 获取随机名称
*
* @param realName 真实名称
* @return uuid 随机名称
*/
public static String getUUIDName(String realName) {
//realname 可能是 1sfasdf.jpg 也可能是 1sfasdf 1
//获取后缀名
int index = realName.lastIndexOf(".");
if (index == -1) {
return UUID.randomUUID().toString().replace("-", "").toUpperCase();
} else {
return UUID.randomUUID().toString().replace("-", "").toUpperCase() + realName.substring(index);
}
}
/**
* 获取文件目录,可以获取256个随机目录
* @return 随机目录
*/
public static String getDir() {
String s = "0123456789ABCDEF";
Random r = new Random();
// /A/A
return "/" + s.charAt(r.nextInt(16)) + "/" + s.charAt(r.nextInt(16));
}
}
启动类
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
用户信息页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>上传头像</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"/>
<!--导入jquery的文件-->
<script type="text/javascript" th:src="@{/js/jquery-1.11.0.js}"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script th:src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<div class="container-fluid">
<!--用户信息栏-->
<div class="row">
<div class="col-md-12 text-center">
<div class="row">
<img th:src="|@{/get}${session.user.avatar}|"
class="img-circle img-thumbnail" style="width:100px;height:100px"/>
</div>
<div class="row">
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal">上传头像
</button>
</div>
//弹出框
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<!--content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">
×
</button>
</div>
<!--body-->
<div class="modal-body">
<form action="/upload" method="post" enctype="multipart/form-data">
<div class="row">
<input type="file" name="file"/><br/>
<input type="submit" value="文件上传" class="btn btn-primary"/><br/>
</div>
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
</div>
</div>
</div>
</body>
</html>
配置文件
server:
port: 8090
spring:
#使用H2数据库方便测试
h2:
console:
enabled: true
settings:
web-allow-others: true
path: /h2
datasource:
url: jdbc:h2:file:./user;DB_CLOSE_ON_EXIT=FALSE
driverClassName: org.h2.Driver
username: sa
password: 123
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update