谷粒学院项目笔记6——oss、EasyExcel、课程分类、nginx
尚硅谷谷粒學院項目第六天內容之對象存儲oss服務、使用EasyExcel添加課程分類功能、課程列表分類、ningx的使用
對象存儲oss
打開阿里云官網——對象存儲——oss管理控制臺
創建bucket:選擇默認地域、低頻訪問、公共讀
創建oss許可證
對象存儲oss——概覽——常用入口——Access key
?點擊繼續使用Accesskey
創建AccessKey——復制——確定
在service下創建SpringBoot子模塊service_oss
引入依賴
<!-- 阿里云oss依賴 --> <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId> </dependency> <!--日期工具欄依賴--> <dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId> </dependency>配置application.properties
注意:地域節點、key、密鑰要換成你自己的
#服務端口 server.port=8002 #服務名 spring.application.name=service-oss #環境設置:dev、test、prod spring.profiles.active=dev #阿里云 OSS aliyun.oss.file.endpoint=oss-cn-hangzhou.aliyuncs.com aliyun.oss.file.keyid=LTAI5t6R5cWusp7MeWpKgT1W aliyun.oss.file.keysecret=Dd6Ku0j5dQja9jh4d7cl8ULepWcNE7 #bucket aliyun.oss.file.bucketname=bucket--a創建啟動類,啟動模塊
報錯
在啟動類上添加:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)創建一個常量類,用來讀取配置文件中的屬性值
創建utils.ConstantRead類
@Component public class ConstantRead 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 ENDPOINT;public static String KEY_ID;public static String KEY_SECRET;public static String BUCKET_NAME;@Overridepublic void afterPropertiesSet() throws Exception {ENDPOINT=endpoint;KEY_ID=keyId;KEY_SECRET=keySecret;BUCKET_NAME=bucketName;} }創建OssController
@RestController @RequestMapping("/ossservice") public class OssController {@Autowiredprivate OssService ossService;//上傳頭像@PostMapping("uploadAvatar")public R uploadFile(MultipartFile file){String url = ossService.uploadAvatar(file);return R.ok().data("url",url);}}創建OssService
@Service public interface OssService {//上傳頭像String uploadAvatar(MultipartFile file); }創建OssServiceImpl
@Component public class OssServiceImpl implements OssService {@Overridepublic String uploadAvatar(MultipartFile file) {String endpoint = ConstantRead.ENDPOINT;String accessKeyId = ConstantRead.KEY_ID;String accessKeySecret = ConstantRead.KEY_SECRET;String bucketName = ConstantRead.BUCKET_NAME;String filename = file.getOriginalFilename();OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);try {InputStream inputStream = file.getInputStream();// 創建PutObject請求。ossClient.putObject(bucketName, filename, inputStream);} catch (Exception e) {e.printStackTrace();} finally {if (ossClient != null) {ossClient.shutdown();}}return "http://"+bucketName+"."+endpoint+"/"+filename;} }swagger測試
如果多個用戶上傳的文件名字相同,后上傳的文件會把先上傳的文件覆蓋掉
我們在文件名前加上uuid值,讓每個文件名都不同
在OssServiceImpl里添加
String filename = file.getOriginalFilename(); String uuid = UUID.randomUUID().toString().replaceAll("-", ""); filename=uuid+filename;此時上傳的文件都是在bucket的根目錄下
把文件按照日期進行分類
在OssServiceImpl里添加
String date = new DateTime().toString("yyyy/MM/dd"); filename=date+"/"+uuid+filename;測試
nginx:反向代理服務器
功能:請求轉發、負載均衡、動靜分離
下載windows版的nginx,解壓
在cmd中通過nginx.exe命令啟動
關閉cmd窗口,nginx不會關閉
關閉nginx:nginx.exe -s stop
配置nginx實現請求轉發功能
編輯nginx安裝目錄/conf/nginx.conf
將默認端口從80改為81,不改會端口沖突?
添加端口映射規則
server {listen 9001;server_name localhost;location ~ /eduservice/ {proxy_pass http://localhost:8001;}location ~ /ossservice/ {proxy_pass http://localhost:8002;} }?將前端模板中config/dev.env.js中的BASE_API端口號改為9001?
重啟ningx、重啟前后端,測試
講師上傳頭像功能
將組件 ImageCropper和PanThumb 復制到項目中的 src/components 目錄下
在save.vue中添加上傳頭像的組件
<!-- 講師頭像 --><el-form-item label="講師頭像"><!-- 頭銜縮略圖 --><pan-thumb :image="teacher.avatar"/><!-- 文件上傳按鈕 --><el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更換頭像</el-button><!--v-show:這個組件是否顯示:key:類似于id,如果一個頁面多個圖片上傳控件,可以做區分@crop-upload-success:上傳成功后的回調 field:這個組件的name@close:關閉組件時會調用close()方法--><image-cropperv-show="imagecropperShow" :width="300":height="300":key="imagecropperKey":url="BASE_API+'/eduoss/fileoss'"field="file"@close="close"@crop-upload-success="cropSuccess"/></el-form-item>引入組件?
import ImageCropper from '@/components/ImageCropper' import PanThumb from '@/components/PanThumb'聲明組件
?components: { ImageCropper, PanThumb },?
定義變量
imagecropperShow:false,imagecropperKey:0,BASE_API:process.env.BASE_API,修改上傳url
寫兩個方法
close(){this.imagecropperShow=false},cropSuccess(data){ //data是后端返回的數據,相當于response.data,這里做了封裝this.imagecropperShow=falsethis.teacher.avatar=data.url},上傳了頭像后,再次點擊更換頭像,出現上傳成功字樣,而不是“將圖片拖拽至此處”
解決:
改變imagecropperKey的值相當于讓上傳組件初始化?
?課程分類管理模塊
?課程分類使用二級分類:通過parentId實現
創建edu_subject表
CREATE TABLE `edu_subject` (`id` char(19) NOT NULL COMMENT '課程類別ID',`title` varchar(10) NOT NULL COMMENT '類別名稱',`parent_id` char(19) NOT NULL DEFAULT '0' COMMENT '父ID',`sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序字段',`gmt_create` datetime NOT NULL COMMENT '創建時間',`gmt_modified` datetime NOT NULL COMMENT '更新時間',PRIMARY KEY (`id`),KEY `idx_parent_id` (`parent_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='課程科目';向edu_subject表中添加數據
INSERT INTO `edu_subject` VALUES ('1178214681118568449','后端開發','0',1,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681139539969','Java','1178214681118568449',1,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681181483010','前端開發','0',3,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681210843137','JavaScript','1178214681181483010',4,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681231814658','云計算','0',5,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681252786178','Docker','1178214681231814658',5,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681294729217','Linux','1178214681231814658',6,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681324089345','系統/運維','0',7,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681353449473','Linux','1178214681324089345',7,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681382809602','Windows','1178214681324089345',8,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681399586817','數據庫','0',9,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681428946945','MySQL','1178214681399586817',9,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681454112770','MongoDB','1178214681399586817',10,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681483472898','大數據','0',11,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681504444418','Hadoop','1178214681483472898',11,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681529610242','Spark','1178214681483472898',12,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681554776066','人工智能','0',13,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681584136193','Python','1178214681554776066',13,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681613496321','編程語言','0',14,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681626079234','Java','1178214681613496321',14,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178585108407984130','Python','1178214681118568449',2,'2019-09-30 16:19:22','2019-09-30 16:19:22'),('1178585108454121473','HTML/CSS','1178214681181483010',3,'2019-09-30 16:19:22','2019-09-30 16:19:22');EasyExcel
EasyExcel是處理excel表格的工具,將excel里的數據一行一行讀進內存,高效簡單
新建一個SpringBoot模塊用來測試easyexcel
創建excel表格,用于測試
寫操作
首先,引入依賴,easyecxel(2.1.1)+poi(3.17),版本之間有對應關系
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency>創建與excel表對應的實體類
@Data public class Entity {@ExcelProperty("學生編號")private Integer sno;@ExcelProperty("學生姓名")private String name; }使用easyexcel向excel表格中寫入數據
public class WriteTest {public static void main(String[] args) {String filename="F:\\temp\\test.xlsx";EasyExcel.write(filename,Entity.class).sheet("學生列表").doWrite(getData());//會自動關流}public static List<Entity> getData(){ArrayList<Entity> list = new ArrayList<>();for (int i=0;i<10;i++){Entity entity = new Entity();entity.setSno(i);entity.setName("lucy"+i);list.add(entity);}return list;} }執行結果
?讀操作
創建與excel表對應的實體類
@Data public class ReadEntity {@ExcelProperty(value = "學生編號",index = 0)private Integer sno;@ExcelProperty(value = "學生姓名",index = 1)private String sname; }創建監聽器
public class EasyExcelListener extends AnalysisEventListener<ReadEntity> {//一行一行讀取數據(不讀表頭),數據封裝在 readEntity@Overridepublic void invoke(ReadEntity readEntity, AnalysisContext analysisContext) {System.out.println(readEntity);}//讀取表頭@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {System.out.println(headMap);}//讀取完成后的處理@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {} }使用easyexcel讀excel表格的數據
public class ReadTest {public static void main(String[] args) {String filename="F:\\temp\\test.xlsx";EasyExcel.read(filename,ReadEntity.class,new EasyExcelListener()).sheet().doRead();} }?執行結果
課程分類管理功能實現
生成代碼框架:在service_edu模塊,打開之前寫的代碼編輯器:src\test\java\com\jiabei\demo\CodeGenerator.java
修改數據庫表名
?執行后生成代碼框架。
添加依賴
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version></dependency>? ?
創建與xlsx對應的實體類?com\jiabei\eduservice\entity\xlsx\SubjectSort.java
@Data public class SubjectSort {@ExcelProperty(index=0)private String oneSubjectName;@ExcelProperty(index=1)private String twoSubjectName; }在實體類EduSubject中添加屬性自動填充注解
@TableId(value = "id", type = IdType.ID_WORKER_STR)private String id; @TableField(fill=FieldFill.INSERT)private Date gmtCreate;@TableField(fill=FieldFill.INSERT_UPDATE)private Date gmtModified;controller
@RestController @RequestMapping("/eduservice/subject") @CrossOrigin public class EduSubjectController {@Autowiredprivate EduSubjectService subjectService;//添加學科類別:將上傳的xlsx文件添加到數據庫中@PostMapping("addSubjectSort")public R addSubjectSort(MultipartFile file){subjectService.addSubjectSort(file);return R.ok();} }service
public interface EduSubjectService extends IService<EduSubject> {void addSubjectSort(MultipartFile file); }serviceImpl
@Service public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {@Autowiredprivate SubjectSortListener listener;@Overridepublic void addSubjectSort(MultipartFile file) {try {InputStream in = file.getInputStream();EasyExcel.read(in, SubjectSort.class,listener).sheet().doRead();//讀取學科分類數據,listener.invoke()監聽器負責將它們讀到數據庫}catch (Exception e){e.printStackTrace();}} }listener
@Component public class SubjectSortListener extends AnalysisEventListener<SubjectSort> {@Autowiredprivate EduSubjectService subjectService;@Overridepublic void invoke(SubjectSort subjectSort, AnalysisContext analysisContext) {if (subjectSort==null){throw new GuliException(20001,"excel表中沒有數據,讀取失敗");}String pid = addOne(subjectSort.getOneSubjectName());addTwo(subjectSort.getTwoSubjectName(),pid);}//添加一級分類private String addOne(String name){QueryWrapper<EduSubject> queryWrapper = new QueryWrapper<>();queryWrapper.eq("title",name);queryWrapper.eq("parent_id","0");EduSubject subject = subjectService.getOne(queryWrapper);//該分類是否已存在if (subject==null){//不存在時添加EduSubject s = new EduSubject();s.setParentId("0");s.setTitle(name);subjectService.save(s);}return subjectService.getOne(queryWrapper).getId();}//添加二級分類private void addTwo(String name,String pid){QueryWrapper<EduSubject> queryWrapper = new QueryWrapper<>();queryWrapper.eq("title",name);queryWrapper.eq("parent_id",pid);EduSubject subject = subjectService.getOne(queryWrapper);if(subject==null){EduSubject s = new EduSubject();s.setTitle(name);s.setParentId(pid);subjectService.save(s);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) { } }將edu_subject表中數據清空,然后swagger測試,成功把excel表中的數據讀到了數據庫
總結
以上是生活随笔為你收集整理的谷粒学院项目笔记6——oss、EasyExcel、课程分类、nginx的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知乎热议:为什么华为天才计划博士刚毕业2
- 下一篇: html表白代码