上传头像
存在阿里的oss储存功能
添加课程分类功能,使用easyexcel读取excel内容数据
树形显示
nginx使用
https://www.aliyun.com/product/oss?spm=5176.20989247.J_3207526240.33.ef146f25Hh7WZ1
创建bucket(水桶)
可以先看看上面的oss新手入门
bucket新建
上传一些图片文件:
都上传成功了
点击继续使用
直接创建然后手机验证
复制id与密钥好好保存
文档链接:
https://help.aliyun.com/document_detail/32008.html?spm=5176.208357.1107607.21.2417390f5G5DXs
依赖:
<dependency>
<groupId>com.aliyun.ossgroupId>
<artifactId>aliyun-sdk-ossartifactId>
<version>3.1.0version>
dependency>
创建模块service_oss
修改启动类名字,还有里面的内容
SpringApplication.run(OssApplication.class,args);
添加application.yml
引入依赖:
//好像只能下3.1.0的依赖
在service_oss(或service)的pom.xml引入
注意写好自己的id与密钥
server:
port: 8002
spring:
application:
name: service-oss
profiles:
active: dev
#阿里云服务器
aliyun
oss
file
endpoint:
keyid:
keysecret:
bucketname:
注意空格是不是复制进来了
endpoint找不到可以再创建一个butket就可以显示
添加启动类注解:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ComponentScan(basePackages = {"com.lkw"})
启动先发现yml识别失败,可以先注释掉
再启动说的是没加数据库
解决方法:
添加上数据库的配置
或者启动类添加属性(上面启动类注解写了)
创建utils.ConstandPropertiesUtils
package com.lkw.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;
}
}
记得把注释掉的yml改回来
创建service.OssService的interface
package com.lkw.oss.service;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.lkw.oss.utils.ConstantPropertiesUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
@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;
}
}
}
创建controller.OssController
package com.lkw.oss.controller;
import com.lkw.commonutils.R;
import com.lkw.oss.service.OssService;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/eduoss/fileoss")
@CrossOrigin
public class OssController {
@Autowired
private OssService ossService;
//上传头像的方法
@PostMapping(value = "/", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R uploadOssFile(@ApiParam(value = "讲师图片", required = true)@RequestPart("file")MultipartFile file){
//获取文件上传 MultipartFile
//返回上传到oss的路径
System.out.println("12312312");
System.out.println(file.getName());
String url = ossService.uploadFileAvatar(file);
return R.ok().data("url",url);
}
}
创建service.OssServiceImpl
package com.lkw.oss.service;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.lkw.oss.utils.ConstantPropertiesUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
@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;
}
}
}
不能正常启动可以注释掉yml里的aliyun…
然后手动在Utils改代码:
丝袜哥地址:http://localhost:8002/swagger-ui/#/oss-controller
丝袜哥点这里就有传文件的了
由于springboot默认上传文件大小是1M
我们可以修改yml,来提高上传文件的大小
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
比较方便的日期工具栏
joda-time
joda-time
添加到service_oss的pom.xml
ossserviceImpl
package com.lkw.oss.service;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.lkw.oss.utils.ConstantPropertiesUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.UUID;
@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();
//uuid,替换
String uuid = UUID.randomUUID().toString().replace("_","");
//拼接:
fileName = uuid+fileName;
//文件按照日期分类
String datePath = new DateTime().toString("yyyy/MM/dd");
//拼接
fileName=datePath+fileName;//2022/11/22/12dew313dqe.jpg
//调用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;
}
}
}
测试:
!!!本人配置失败,最好暂时跳过,等看看gateway能不能代替
反向代理服务器:
1.请求转发
2.负载均衡(后面使用网关代替)89
3.动静分离
特性:打开窗口,关闭窗口,但是进程还在运行
要重启要使用命令
关闭:nginx.exe -s stop
启动:nginx.exe
在nginx.conf就行配置
修改默认端口,80改81
配置转发规则:
这里的注释去掉
,然后变成这样
前端地址全改成9001nginx地址
这里的localhost:8001全删了
src\api\user.js
src\api\teacher\teacher.js
前面不能进行的记得恢复,跳过
在添加讲师页面,添加组件(这里用的element-ui)
src\views\edu\teacher\save.vue代码:
讲师添加
保存
点击上传
只能上传jpg/png文件,且不超过500kb
效果:
有点缺陷
使用的sql是edu_subject
parentId等于0是一级分类
阿里巴巴的开源的excel的工具
操作excel进行读写的操作
一行一行进行解析,极大提高效率(老式的是一次性读写)(io时间换内存)
在service_edu引入依赖:
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcel artifactId>
<version>2.1.1version>
dependency>
在guli_parent引入poi依赖:(注意版本对应)
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>${poi.version}version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>${poi.version}version>
dependency>
代码略
用第一种,不复杂,不用关流:
继承AnalysisEventListener
两个Override方法(一行一行读取,读取完成之后方法):invoke,doAfterAllAnalysed
一个读取表头方法:invokeHeadMap
只是多了一个监听器
两个id设置改用varchar长度32
使用mabatisX生成
注意把这个改成Integer,还有自动填充注解
EduSubjectController
package com.lkw.eduservice.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lkw.eduservice.entity.EduSubject;
import com.lkw.eduservice.entity.excel.SubjectData;
import com.lkw.eduservice.service.EduSubjectService;
import com.lkw.servicebase.exceptionhandler.GuliException;
import java.util.Map;
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {
//SubjectExcelListener不能被spring托管,不能注入
public EduSubjectService subjectService;
//有参无参
public SubjectExcelListener(){}
public SubjectExcelListener(EduSubjectService subjectService){
this.subjectService=subjectService;
}
@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);
}
//查询二级分类
//获取一级分类的id
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<EduSubject> wrapper=new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id","0");
EduSubject oneSubject=subjectService.getOne(wrapper);
return oneSubject;
}
//判断二级分类不能重复添加//多了pid
private EduSubject existTwoSubject(EduSubjectService subjectService,String name,String pid){
QueryWrapper<EduSubject> 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) {
}
}
SubjectData
package com.lkw.eduservice.entity.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
//实体类
@Data
public class SubjectData {
@ExcelProperty(index=0)
private String oneSubjectName;
@ExcelProperty(index=1)
private String twoSubjectName;
}
EduSubject
package com.lkw.eduservice.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import lombok.Data;
/**
* 课程科目
* @TableName edu_subject
*/
@TableName(value ="edu_subject")
@ApiModel(value="EduSubject对象",description = "课程科目")
@Data
public class EduSubject implements Serializable {
/**
* 课程类别ID
*/
private String id;
/**
* 类别名称
*/
private String title;
/**
* 父ID
*/
private String parentId;
/**
* 排序字段
*/
private Integer sort;
/**
* 创建时间
*/
@TableField(fill= FieldFill.INSERT)
private Date gmtCreate;
/**
* 更新时间
*/
@TableField(fill=FieldFill.INSERT_UPDATE)
private Date gmtModified;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
EduSubject other = (EduSubject) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getTitle() == null ? other.getTitle() == null : this.getTitle().equals(other.getTitle()))
&& (this.getParentId() == null ? other.getParentId() == null : this.getParentId().equals(other.getParentId()))
&& (this.getSort() == null ? other.getSort() == null : this.getSort().equals(other.getSort()))
&& (this.getGmtCreate() == null ? other.getGmtCreate() == null : this.getGmtCreate().equals(other.getGmtCreate()))
&& (this.getGmtModified() == null ? other.getGmtModified() == null : this.getGmtModified().equals(other.getGmtModified()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode());
result = prime * result + ((getParentId() == null) ? 0 : getParentId().hashCode());
result = prime * result + ((getSort() == null) ? 0 : getSort().hashCode());
result = prime * result + ((getGmtCreate() == null) ? 0 : getGmtCreate().hashCode());
result = prime * result + ((getGmtModified() == null) ? 0 : getGmtModified().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", title=").append(title);
sb.append(", parentId=").append(parentId);
sb.append(", sort=").append(sort);
sb.append(", gmtCreate=").append(gmtCreate);
sb.append(", gmtModified=").append(gmtModified);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}
SubjectExcelListener
package com.lkw.eduservice.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lkw.eduservice.entity.EduSubject;
import com.lkw.eduservice.entity.excel.SubjectData;
import com.lkw.eduservice.service.EduSubjectService;
import com.lkw.servicebase.exceptionhandler.GuliException;
import java.util.Map;
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {
//SubjectExcelListener不能被spring托管,不能注入
public EduSubjectService subjectService;
//有参无参
public SubjectExcelListener(){}
public SubjectExcelListener(EduSubjectService subjectService){
this.subjectService=subjectService;
}
@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);
}
//查询二级分类
//获取一级分类的id
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<EduSubject> wrapper=new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id","0");
EduSubject oneSubject=subjectService.getOne(wrapper);
return oneSubject;
}
//判断二级分类不能重复添加//多了pid
private EduSubject existTwoSubject(EduSubjectService subjectService,String name,String pid){
QueryWrapper<EduSubject> 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) {
}
}
EduSubjectServiceImpl
package com.lkw.eduservice.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lkw.eduservice.entity.EduSubject;
import com.lkw.eduservice.entity.excel.SubjectData;
import com.lkw.eduservice.listener.SubjectExcelListener;
import com.lkw.eduservice.service.EduSubjectService;
import com.lkw.eduservice.mapper.EduSubjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
/**
* @author 李可文
* @description 针对表【edu_subject(课程科目)】的数据库操作Service实现
* @createDate 2022-09-20 21:04:48
*/
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject>
implements EduSubjectService{
@Override
public void saveSubject(MultipartFile file, EduSubjectService subjectService) {
try {
//输入流
InputStream inputStream=file.getInputStream();
//调用方法读取
EasyExcel.read(inputStream, SubjectData.class,new SubjectExcelListener(subjectService)).sheet().doRead();
} catch (Exception e) {
e.printStackTrace();
}
}
}
EduSubjectService
package com.lkw.eduservice.service;
import com.lkw.eduservice.entity.EduSubject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;
/**
* @author 李可文
* @description 针对表【edu_subject(课程科目)】的数据库操作Service
* @createDate 2022-09-20 21:04:48
*/
public interface EduSubjectService extends IService<EduSubject> {
//添加课程分类
void saveSubject(MultipartFile file,EduSubjectService subjectService);
}
#####丝袜哥测试: