学成在线第七天

保存发布信息、页面静态化

点击某课程数据后的 发布 链接(审核状态为通过),即可对该课程进行发布
在这里插入图片描述
需要使用的表:
在这里插入图片描述

YAPI文档:
在这里插入图片描述
代码展示:

web层

    //保存发布信息
    @PostMapping("/publish/{courseBaseId}")
    public ResponseResult saveCoursePubMessages(@PathVariable("courseBaseId") Long courseBaseId){
        return coursePubService.saveCoursePubMessages(courseBaseId);
    }

serviceImpl层

    @Autowired
    private BasicClient basicClient;
    @Autowired
    private TeachplanService teachplanService;
    @Autowired
    private CourseBaseMapper courseBaseMapper;
    @Autowired
    private CourseTeacherMapper courseTeacherMapper;
    @Autowired
    private Configuration configuration;
    @Autowired
    private MinioService minioService;

  @Override
    @Transactional
    public ResponseResult saveCoursePubMessages(Long courseBaseId) {
        //是否以前存在课程发布信息
        LambdaQueryWrapper<CoursePub> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CoursePub::getCourseId,courseBaseId);
        CoursePub one1 = this.getOne(queryWrapper);
        if (one1 !=null){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //查询课程基本信息
        CourseBase one = courseBaseMapper.selectById(courseBaseId);
        if (one == null) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        one.setAuditStatus(CourseConstants.AUDIT_PUBLISHED_STATUS);
        courseBaseMapper.updateById(one);
        //查询课程计划信息
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getCourseId, courseBaseId);
        List<Teachplan> teachplanList = teachplanService.list(wrapper);
        if (teachplanList.size() == 0) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        String teachplanJSON = JSON.toJSONString(teachplanList);
        //课程讲师信息
        LambdaQueryWrapper<CourseTeacher> qw = new LambdaQueryWrapper<>();
        qw.eq(CourseTeacher::getCourseId, courseBaseId);
        List<CourseTeacher> courseTeachers = courseTeacherMapper.selectList(qw);
        String courseTeachersJSON = "";
        if (courseTeachers.size() != 0) {
            courseTeachersJSON = JSON.toJSONString(courseTeachers);
        }
        CoursePub coursePub = BeanHelper.copyProperties(one, CoursePub.class);
        //补全信息
        coursePub.setCourseId(courseBaseId);
        coursePub.setTeachplan(teachplanJSON);
        if (StrUtil.isNotBlank(courseTeachersJSON)) {
            coursePub.setTeachers(courseTeachersJSON);
        }
        String mt = one.getMt();
        String st = one.getSt();
        //根据id,调用feign接口查询mt、st名称
        String mtName = getMtNameOrStName(mt);
        String stName = getMtNameOrStName(st);
        coursePub.setMtName(mtName);
        coursePub.setStName(stName);
        coursePub.setCreateDate(new Date());
        boolean save = this.save(coursePub);
        if (!save) {
            throw new BusinessException(ErrorCode.COURSEPUBSHRRROR);
        }
        ResponseResult<TeachplanVo> rr = teachplanService.treeNodes(courseBaseId);
        TeachplanVo teachplanVo = rr.getData();
        //生成html页面
        try {
            HashMap<String, Object> map = new HashMap<>();
            map.put("coursePub",coursePub);
            map.put("teachplanNode",teachplanVo);
            Template template = configuration.getTemplate("learing_article.ftl");
            String htmlStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(htmlStr.getBytes());
            String filename = courseBaseId + ".html";
            minioService.uploadFreemarkerHtmlByMinio(inputStream, filename);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        return ResponseResult.okResult();
    }

效果展示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在页面搜索:http://www.xuecheng.com/pages/47.html,查看生成的静态页面
在这里插入图片描述
时间问题
在这里插入图片描述

#安装ntpdate工具
yum -y install ntp ntpdate
#自动同步时间
ntpdate ntp.ubuntu.com

代码优化
以前是真没在意,我的代码又长又烂,= =现在优化以下

存在的问题:
在这里插入图片描述
同步:就是在发出一个调用时,在没有得到结果之前, 该调用就不返回

异步:调用在发出之后,这个调用就直接返回了,没有返回结果

常见的异步处理有两类:

  • 在同一应用(微服务)内部:使用多线程
  • 设计到夸应用调用(微服务调用):基于消息中间件

@Async是Spring提供的异步处理注解,被此注解标注的方法会在新的线程中执行,其实就相当于我们自己new Thread。此注解使用起来也比较简单。

  • 引导类中使用@EnableAsync注解开启异步调用
    在这里插入图片描述

  • 在方法上加上@Async注解(标明要异步调用)

将需要多线程处理的业务逻辑,抽取到一个新的java类中,配置方法。在方法上添加@Async注解

在这里插入图片描述

package com.xuecheng.content.service.impl;

import com.xuecheng.basic.api.BasicClient;
import com.xuecheng.content.mappers.CourseBaseMapper;
import com.xuecheng.content.mappers.CourseTeacherMapper;
import com.xuecheng.content.service.MinioService;
import com.xuecheng.content.service.PublishHtmlService;
import com.xuecheng.content.service.TeachplanService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Service
public class PublishHtmlServiceImpl implements PublishHtmlService {
    @Autowired
    private Configuration configuration;
    @Autowired
    private MinioService minioService;

    @Override
    @Async
    public void publish(Map map, Long courseBaseId) {
        try {
            Template template = configuration.getTemplate("learing_article.ftl");
            String htmlStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(htmlStr.getBytes());
            String filename = courseBaseId + ".html";
            minioService.uploadFreemarkerHtmlByMinio(inputStream, filename);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }
}

修改CoursePubServiceImpl.class
在这里插入图片描述
效果演示:
需要删除之前的信息

发送MQ消息

课程发布对于该项目来说是一个核心业务,除了页面生成之外,一般都需要扩展其他操作,这些逻辑若都在课程发布中接入,那课程发布的实现将耦合所有下游业务。且下游模块出现问题,将会影响该核心业务。

  • 搜索服务:在门户网站使用ElasticSearch进行搜索,同步es索引
  • 短信服务:当订阅了某个教育机构,发布新课程时,会受到课程通知。
    在这里插入图片描述
    存在的问题:
  1. 耦合度高:每次加入新的需求,都要修改原来的代码
  2. 性能下降:调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和。
  3. 资源浪费:调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源
  4. 级联失败:如果服务提供者出现问题,所有调用方都会跟着出问题,如同多米诺骨牌一样,迅速导致整个微服务群故障

为了解决上诉问题,我们使用RabbitMQ消息中间件来完成。
在这里插入图片描述
访问mq:
管理后台地址:http://192.168.136.150:15672/

用户名/密码:guest/guest

和使用Mysql类似,Java代码操作时一般不会使用超级管理员账号

  • 一个项目分配一个账号
  • 一个项目分配一个虚拟主机
  • 分配此账号对此虚拟主机的操作权限
  • 本次课程:我们设置的用户名-密码-虚拟机均为xuecheng
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

在这里插入图片描述

rabbitmq:
  host: 192.168.136.150
  virtual-host: xuecheng
  username: xuecheng
  password: xuecheng

在这里插入图片描述

发送消息

CoursePubServiceImpl:

    @Autowired
    private RabbitTemplate rabbitTemplate;
rabbitTemplate.convertAndSend("content-exchange","course.pub",coursePub.getId());

在这里插入图片描述
测试消息
在这里插入图片描述
在这里插入图片描述
编写监听器:
在这里插入图片描述

package com.xuecheng.search.listener;

import cn.hutool.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class MessageListener {

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "course.index.queue"),
            exchange = @Exchange(
                    value = "content-exchange",
                    type = ExchangeTypes.TOPIC
            ),
            key = "course.*"
    ))
    public void updateIndex(Long coursePubId){
        log.info("获取的课程发布id为:"+coursePubId);
        //更新es,下次做
    }
}

效果展示:
删除以前的数据,重新发布
在这里插入图片描述
今天的任务完成,突然觉得自己的代码写的跟shi山一样…
需要资料的私聊我

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《现代密码学第五版 杨波pdf》是一本关于现代密码学的学术著作,由杨波教授编写而成。这本书是针对密码学领域的学生、研究人员以及安全专家而设计的。 书中首先介绍了密码学的基本概念和历史背景,包括对称密码学和公钥密码学的介绍以及它们在实际应用中的差异。随后,作者详细讲解了密码学的数学基础,包括模运算、离散对数和椭圆曲线等内容,这些概念对于理解密码算法的实现和分析至关重要。 在接下来的章节中,书中探讨了各类常见的密码算法,包括对称密码算法(如DES和AES)、哈希函数(如MD5和SHA-2)以及公钥密码算法(如RSA和椭圆曲线密码学)。对于每种算法,作者都提供了详细的原理和实际应用的案例分析,使读者能够全面了解其设计原则、安全性和适用场景。 此外,书中还涵盖了密码协议、数字签名、身份验证和密钥管理等密码学的相关主题。读者可以通过阅读这些章节来深入了解密码学在实际应用中的应用场景、攻击方法以及保障信息安全的方法。 总的来说,《现代密码学第五版 杨波pdf》是一本系统全面的密码学参考书,不仅深入浅出地介绍了密码学的基础知识,还涵盖了密码算法的实现和应用。对于想要深入了解密码学理论和实践的读者来说,这本书是一本非常好的学习资料。 ### 回答2: 《现代密码学第五版》是由杨波所著的一本关于密码学的教材,是该领域的经典之作。本书系统地介绍了密码学的基本理论、方法和应用。杨波在本书中对密码学的概念、原理和算法进行了深入浅出的讲解,使读者能够深入理解密码学的基本概念和技术。 《现代密码学第五版》分为七个部分:基础知识、对称密码体制、数据完整性和数字签名、公钥密码体制、安全协议、密码应用与系统安全、密码分析与实现,每个部分都对相关的概念和方法进行了详细的介绍。作者使用了大量的示例和图表,有助于读者更好地理解和掌握密码学的核心内容。 该书在密码学领域具有较高的权威性,无论是对学术研究者还是对密码学从业人员来说,都是一本必备的工具书。《现代密码学第五版》涵盖了密码学的主要方向和最新的研究成果,对于读者的学习和研究具有很大的参考价值。 总之,杨波的《现代密码学第五版》是一本权威、系统和实用的密码学教材,内容丰富、条理清晰。无论是对于密码学初学者还是对于专业领域内的研究人员来说,都是一本不可多得的参考书籍。它对于理解密码学的基本原理和应用,以及掌握密码学算法和技术都具有重要的作用。 ### 回答3: 《现代密码学第五版》是杨波教授所著的一本关于现代密码学领域的权威性教材。该教材系统地介绍了密码学的基本概念、算法和应用,是学习密码学领域的必备参考书。 《现代密码学第五版》以清晰的逻辑结构和深入浅出的讲解方式贯穿整本书。首先,书中介绍了密码学的基础知识,包括经典密码学和现代密码学的基本概念和原则。然后,详细阐述了对称密码和非对称密码算法,包括DES、AES、RSA等常见的密码算法。 此外,《现代密码学第五版》还讨论了密码学在网络安全、数字签名、身份验证和电子支付等领域的应用。同时,书中还专门介绍了量子密码学和密码协议等前沿内容,使读者对密码学的发展趋势有更深入的了解。 杨波教授作为国内著名密码学专家,他在该领域的研究和贡献深受学术界的认可。他不仅在书中详细介绍密码学的理论知识,还分享了自己的研究经验和实际应用案例,使这本教材更具权威性和实用性。 总的来说,《现代密码学第五版》凭借其全面而系统的内容,简洁明了的讲解方式以及权威的作者,成为了现代密码学领域的经典教材。无论是学习密码学的初学者还是从事密码学研究的专业人士,都会从中获得丰富的知识和实践经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皇家小黄

创作不易!!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值