目录
一、内容介绍
二、对象存储
三、实现文件上传
四、nginx(返现代理服务器)
五、添加讲师实现上传头像前端整合
六、课程分类管理
七、EasyExcel
7.1使用EasyExcel进行写操作
7.2 使用EasyExcel进行读操作
八、课程分类添加功能
1、添加讲师实现头像上传功能
阿里云oss存储服务
2、添加课程分类功能
使用EasyExcel读取excel内容添加数据
3、课程分类列表
树形结构显示
1、打开阿里云网站https://www.aliyun.com/
2、注册阿里云账户 最好使用支付宝,需要实名认证
3、使用注册的用户登录阿里云里面
4、找到阿里云oss
5、开通 对象存储
6、阿里云oss管理控制台的使用
(1)使用oss,首先创建bucket
java代码操作阿里云oss上传文件到阿里云oss操作
1、准备工作:创建操作阿里云oss许可证(阿里云颁发id和秘钥)
文档位置
引入依赖
1、在service下创建service_oss
2、配置pom.xml(service_oss)
com.aliyun.oss
aliyun-sdk-oss
joda-time
joda-time
3、配置application.properties
#服务端口
server.port=8002
#服务名
spring.application.name=service-oss
#环境设置:dev、test、prod
spring.profiles.active=dev
#阿里云 OSS
#不同的服务器,地址不同
aliyun.oss.file.endpoint=your endpoint
aliyun.oss.file.keyid=your accessKeyId
aliyun.oss.file.keysecret=your accessKeySecret
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=guli-file
4、创建启动类,启动报错了
启动时候,找数据库配置,但是现在模块因为不需要操作数据库,只是做上传到oss功能,没有找到数据库
解决方式
(1)添加上数据库配置
(2)在启动类添加属性,默认不去加载数据库配置(主要使用)
1、从配置文件读取常量
创建常量读取工具类:ConstantPropertiesUtil.java
使用@Value读取application.properties里的配置内容
用spring的 InitializingBean 的 afterPropertiesSet 来初始化配置信息,这个方法将在所有的属性被初始化 后调用
package com.atguigu.oss.utils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//当项目启动,spring接口,spring加载之后,执行接口一个方法
@Component
public class ConstantPropertiesUtils implements InitializingBean {
//读取配置文件内容
@Value("${aliyun.oss.file.endpoint}")
private String endpoint;
@Value("${aliyun.oss.file.keyid}")
private String keyId;
@Value("${aliyun.oss.file.keysecret}")
private String keySecret;
@Value("${aliyun.oss.file.bucketname}")
private String bucketName;
//定义公开静态常量
public static String END_POINT;
public static String ACCESS_KEY_ID;
public static String ACCESS_KEY_SECRET;
public static String BUCKET_NAME;
@Override
public void afterPropertiesSet() throws Exception {
END_POINT = endpoint;
ACCESS_KEY_ID = keyId;
ACCESS_KEY_SECRET = keySecret;
BUCKET_NAME = bucketName;
}
}
2、文件上传
创建controller,创建service
@RestController
@RequestMapping("/eduoss/fileoss")
@CrossOrigin
public class OssController {
@Autowired
private OssService ossService;
//上传头像的方法
@PostMapping
public R uploadOssFile(MultipartFile file){
//获取文件上传 MultipartFile
//返回上传到oss的路径
String url = ossService.uploadFileAvatar(file);
return R.ok().data("url",url);
}
}
3、在servcie实现文件上传到oss过程
OssService代码
public interface OssService {
String uploadFileAvatar(MultipartFile file);
}
OsserviceImpl代码
@Service
public class OssServiceImpl implements OssService {
//上传头像到oss
@Override
public String uploadFileAvatar(MultipartFile file) {
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
String endpoint = ConstantPropertiesUtils.END_POINT;
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
// 填写Bucket名称,例如examplebucket。
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
try {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//获取上传上传文件输入流
InputStream inputStream = file.getInputStream();
//获取文件名称
String fileName = file.getOriginalFilename();
//调用oss方法实现上传
//第一个参数 Bucket名称
//第二个参数 上传到oss文件路径和文件名称
//第三个参数 上传文件输入流
ossClient.putObject(bucketName,fileName,inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//把上传之后的文件路径返回
//需要把上传到阿里云oss路径手动拼接出来
// https://edu-htz.oss-cn-beijing.aliyuncs.com/CSDN.png
String url = "https://"+bucketName+"."+endpoint+"/"+fileName;
return url;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
swagger测试
成功返回
在阿里oss也查到了图片
存在的问题
1、多次上传相同名称文件,造成,最后一次上传把之前上传文件覆盖
在文件名称添加随机唯一值,让每个文件名称不同
//1在文件名称里面添加随机唯一的值
String uuid = UUID.randomUUID().toString().replaceAll("-","");
//
fileName = uuid+fileName;
2、把文件进行分类管理
根据日期进行分类
实现年月日分类
//2、把文件按照日期进行分类
//获取当前日期
String datePath = new DateTime().toString("yyyy/MM/dd");
//拼接
//2021//09/15/01.jpg
fileName = datePath + "/" + fileName;
最终效果
1、请求转发
2、负载均衡
3、动静分离
特点:cmd启动nginx,如果关闭cmd窗口,nginx不会停止的。
配置nginx实现请求转发的功能
3.1找到nginx配置文件
3.2、在nginx.conf进行配置
(1)修改nginx默认端口 把80 修改 81
(2)配置nginx转发规则
在http {}里面创建配置
(3) 修改前端请求地址改为nginx
(4)需要把nginx重启启动先把nginx停止,再启动
测试成功
1 在添加讲师页面,创建上传组件,实现上传
使用element-ui实现
到源码里面找到组件,复制到前端项目src 下 components
2在添加讲师页面,创建上传组件,实现上传
使用element-ui实现
更换头像
3使用组件
4引入组件和声明组件
5、修改上传接口地址
6、编写close方法和上传成功的方法
效果展示
上传成功后
解决一个小bug 上传成功点击更换没有效果
课程名称:java基础开发课程 分类 后端开发
课程名称:vue高级开发课程 分类 前端开发
课程分类存储结构
EasyExcel操作excel进行读和写操作
7.1.1、pom引入xml相关依赖
com.alibaba
easyexcel
2.1.1
还需要poi依赖
7.1.2、创建实体类,和excel数据相对应
@Data
public class DemoData {
//设置excel表头名称
@ExcelProperty("学生编号")
private Integer sno;
@ExcelProperty("学生姓名")
private String name;
}
写操作代码
public class TestEasyExcel {
public static void main(String[] args) {
//实现excel写的操作
//1 设置写入文件夹地址和excel文件名称
String filename = "E:\\write.xlsx";
//调用easeyExcel里面的方法实现写操作
//write方法两个参数:第一个参数文件路径名称,第二个参数实体类class
EasyExcel.write(filename,DemoData.class).sheet("学生列表").doWrite(getData());
}
//创建方法返回list集合
private static List getData(){
List list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setSno(i);
data.setName("lucy" + i);
list.add(data);
}
return list;
}
}
7.1.3效果展示
7.2.1 创建和excel对应的实体类,标记对应关系
7.2.2 创建监听进行excel进行读取
public class ExcelListener extends AnalysisEventListener {
//一行一行读取excel内容
@Override
public void invoke(DemoData data, AnalysisContext analysisContext) {
System.out.println("****"+data);
}
//读取表头内容
@Override
public void invokeHeadMap(Map headMap, AnalysisContext context) {
System.out.println("表头:" + headMap);
}
//读取完成之后
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
7.2.3、最终方法调用
7.2.4测试
第一步 引入easyexcel依赖
第二步 使用代码生成器生成代码
第三步 创建实体类和excel对应关系
@Data
public class SubjectData {
@ExcelProperty(index = 0)
private String oneSubjectName;
@ExcelProperty(index = 1)
private String twoSubjectName;
}
EduSubjectController代码
@RestController
@RequestMapping("/eduservice/subject")
@CrossOrigin
public class EduSubjectController {
@Autowired
private EduSubjectService subjectService;
//添加课程分类
//获取上传过来的文件,把文件内容读取出来
@PostMapping("addSubject")
public R addSubject(MultipartFile file){
//上传excel文件
subjectService.saveSubject(file,subjectService);
return R.ok();
}
}
SubjectData代码
@Data
public class SubjectData {
@ExcelProperty(index = 0)
private String oneSubjectName;
@ExcelProperty(index = 1)
private String twoSubjectName;
}
EduSubject代码(gmtCreate加上 @TableField(fill = FieldFill.INSERT);
gmtModified加上@TableField(fill = FieldFill.INSERT_UPDATE))
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduSubject对象", description="课程科目")
public class EduSubject implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程类别ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "类别名称")
private String title;
@ApiModelProperty(value = "父ID")
private String parentId;
@ApiModelProperty(value = "排序字段")
private Integer sort;
@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}
subjectExcelListener代码
public class SubjectExcelListener extends AnalysisEventListener {
//因为SubjectExcelListener不能交给spring进行管理,需要自己new,不能注入其他对象
//不能实现数据库操作
public EduSubjectService subjectService;
public SubjectExcelListener() {}
public SubjectExcelListener(EduSubjectService subjectService) {
this.subjectService = subjectService;
}
//读取excel内容
@Override
public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
if(subjectData == null){
throw new GuliException(20001,"文件数据为空");
}
//一行一行读取,每次读取两个值,第一个值一级分类,第二个值二级分类
//判断一级分类是否重复
EduSubject existOneSubject = this.existOneSubject(subjectService, subjectData.getOneSubjectName());
if(existOneSubject == null){ // 没有相同一级分类,进行添加
existOneSubject = new EduSubject();
existOneSubject.setParentId("0");
existOneSubject.setTitle(subjectData.getOneSubjectName());//一级分类名称
subjectService.save(existOneSubject);
}
String pid = existOneSubject.getId();
//添加二级分类
//判断二级分类是否重复
EduSubject existTwoSubject = this.existTwoSubject(subjectService, subjectData.getTwoSubjectName(), pid);
if(existTwoSubject == null){
existTwoSubject = new EduSubject();
existTwoSubject.setParentId(pid);
existTwoSubject.setTitle(subjectData.getTwoSubjectName());//二级分类名称
subjectService.save(existTwoSubject);
}
}
//判断一级分类不能重复添加
private EduSubject existOneSubject(EduSubjectService subjectService,String name){
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id","0");
EduSubject oneSubject = subjectService.getOne(wrapper);
return oneSubject;
}
//判断二级分类不能重复添加
private EduSubject existTwoSubject(EduSubjectService subjectService,String name,String pid){
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id",pid);
EduSubject twoSubject = subjectService.getOne(wrapper);
return twoSubject;
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
EduSubjectService代码
public interface EduSubjectService extends IService {
//添加课程分类
void saveSubject(MultipartFile file,EduSubjectService eduSubjectService);
}
EduSubjectServiceImpl代码
@Service
public class EduSubjectServiceImpl extends ServiceImpl implements EduSubjectService {
//添加课程分类
@Override
public void saveSubject(MultipartFile file,EduSubjectService eduSubjectService) {
try {
//文件输入流
InputStream in = file.getInputStream();
//调用方法进行读取
EasyExcel.read(in, SubjectData.class,new SubjectExcelListener(eduSubjectService)).sheet().doRead();
}catch (Exception e){
e.printStackTrace();
}
}
}
Swagger测试上传Excel
Excel数据
数据库显示(先删除edu_subject内容 对应sql DELETE FROM edu_subject)