手把手教你用Spring Boot实现上传头像功能

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">
                                &times;
                            </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

复制代码

点击进入Github

THE END
< <上一篇
下一篇>>