资讯头条P3自媒体搭建

自媒体素材管理与文章管理

一.后台搭建

1.1 搭建自媒体网关

导入网关模块>>>在网关模块的pom.xml文件中添加该子模块>>>刷新maven

 	<modules><module>heima-leadnews-app-gateway</module><!--新增--><module>heima-leadnews-wemedia-gateway</module> </modules>

添加nacos配置

spring:cloud:gateway:globalcors:cors-configurations:'[/**]': # 匹配所有请求allowedOrigins: "*" #跨域处理 允许所有的域allowedMethods: # 支持的方法- GET- POST- PUT- DELETEroutes:# 平台管理- id: wemediauri: lb://leadnews-wemediapredicates:- Path=/wemedia/**filters:- StripPrefix= 1

1.2 搭建自媒体微服务

导入自媒体微服务模块>>>微服务模块的pom.xml文件中添加该子模块>>>刷新maven

	<modules><module>heima-leadnews-user</module><module>heima-leadnews-article</module><module>heima-leadnews-wemedia</module></modules>

添加nacos配置

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_wemedia?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCusername: rootpassword: root
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.wemedia.pojos

创建数据库leadnews_wemedia>>>导入sql脚本

1.3 导入实体类

找到xxx-model模块>>>在com.heima.model下导入wemedia包

二.前台搭建

通过nginx的虚拟主机功能,使用同一个nginx访问多个项目

2.1 解压前端工程到指定目录

我的前端工程和nginx都放到了E:\JavaCode\heima-leadnews-front目录下

2.2 新增wemedia前端工程配置文件,并在外围配置文件nginx.conf中引入该配置文件

配置文件

upstream  heima-wemedia-gateway{server localhost:51602; # 自媒体模块网关端口
}server {listen 8802; # 前端访问端口location / {root E:/JavaCode/heima-leadnews-front/wemedia-web/;index index.html;}location ~/wemedia/MEDIA/(.*) {   # 请求映射proxy_pass http://heima-wemedia-gateway/$1;proxy_set_header HOST $host;  # 不改变源请求头的值proxy_pass_request_body on;  #开启获取请求体proxy_pass_request_headers on;  #开启获取请求头proxy_set_header X-Real-IP $remote_addr;   # 记录真实发出请求的客户端IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  #记录代理信息}
}

2.3 启动nginx,启动自媒体微服务和对应网关

三.自媒体素材管理

3.1 自媒体素材管理&图片上传

3.1.1 添加自媒体素材对应的实体类

直接拷贝到对应的包下即可

3.1.2 上传素材实现思路

在这里插入图片描述
(1).前端发送上传图片请求,类型为MultipartFile

(2).网关进行token解析后,把解析后的用户信息存储到header中
需要在网关的全局认证过滤器中添加代码,用于解析用户信息到header中;

		//5.判断token是否有效try {Claims claimsBody = AppJwtUtil.getClaimsBody(token);//是否是过期int result = AppJwtUtil.verifyToken(claimsBody);if (result == 1 || result == 2) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//获得token解析后中的用户信息Object userId = claimsBody.get("id");//----------------------------新增部分------------------------\\//在header中添加新的信息ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {httpHeaders.add("userId", userId + "");}).build();//重置headerexchange.mutate().request(serverHttpRequest).build();//----------------------------新增部分------------------------\\} catch (Exception e) {e.printStackTrace();}

(3).自媒体微服务使用拦截器获取到header中的的用户信息,并放入到threadlocal中

3.1.3 新增ThreadLocal工具类WmThreadLocalUtil

WmThreadLocalUtil工具类会便于操作ThreadLocalUtil对象;

public class WmThreadLocalUtil {private final static ThreadLocal<WmUser> WM_USER_THREAD_LOCAL = new ThreadLocal<>();/*** 添加用户* @param wmUser*/public static void  setUser(WmUser wmUser){WM_USER_THREAD_LOCAL.set(wmUser);}/*** 获取用户*/public static WmUser getUser(){return WM_USER_THREAD_LOCAL.get();}/*** 清理用户*/public static void clear(){WM_USER_THREAD_LOCAL.remove();}}
3.1.4 在heima-leadnews-wemedia中新增拦截器

拦截器的作用,从header中取出登录用户ID存入当前线程;在 com.heima.wemedia.interceptor 包下创建拦截器WmTokenInterceptor

@Slf4j
public class WmTokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//得到header中的信息String userId = request.getHeader("userId");Optional<String> optional = Optional.ofNullable(userId);if(optional.isPresent()){//把用户id存入threadloacl中WmUser wmUser = new WmUser();wmUser.setId(Integer.valueOf(userId));WmThreadLocalUtil.setUser(wmUser);log.info("wmTokenFilter设置用户信息到threadlocal中...");}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("清理threadlocal...");WmThreadLocalUtil.clear();}
}
3.1.5 通过配置类WebMvcConfig配置拦截器生效

拦截所有请求

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new WmTokenInterceptor()).addPathPatterns("/**");}}
3.1.6 自媒体微服务集成heima-file-starter

由于要用到上传minio的功能,因此需要集成heima-file-starter(该模块中提供了上传文件(图片,html文件),下载,删除文件的功能。
在自媒体微服务中导入依赖

	 <dependency><groupId>com.heima</groupId><artifactId>heima-file-starter</artifactId><version>1.0-SNAPSHOT</version></dependency>

自媒体微服务的配置中心添加以下配置

minio:accessKey: miniosecretKey: minio123bucket: leadnewsendpoint: http://47.108.218.130:9000readPath: http://47.108.218.130:9000
3.1.7 具体实现

三步走,mapper>>>service>>>controller;
问题一
中间遇到了一个问题:上传文件到minio时失败

// 报错日志
minio put file error.
The request signature we calculated does not match the signature you provided. 
Check your key and signing method.

报错日志大意如下:

我们计算的请求签名与您提供的签名不匹配。
检查您的密钥和签名方法。

推测大概可能是配置文件中的minio的秘钥与创建minio容器时指定的不一致,我在创建时使用的秘钥是11位,而在配置文件中使用的是8位因此报错,修改后重启。该报错消失返回了fileId;
问题二
在解决了上述错误之后,又遇到了报错信息:

 catch exception:nulljava.lang.NullPointerExceptionat com.heima.wemedia.service.impl.WmMaterialServiceImpl.uploadPicture(WmMaterialServiceImpl.java:56)

这个就不翻译了,推测应该是在业务层中出现了内容为空的情况,根据报错信息定位到对应的代码,经过检查发现并不是上传文件返回结果的问题,文件已经被上传到了minio,并且返回了相应的地址;问题是拦截器无法直接从请求的请求头中获得"userId",那么说明网关在过滤请求的时候确实是从请求中解析了token,但是没有把解析出来的内容userId直接添加到请求头中,因此要在heima-leadnews-wemedia-gateway模块的包com.heima.wemedia.gateway.filter下的AuthorizeFilter中步骤5中添加如下代码:

		//5.判断token是否有效try {Claims claimsBody = AppJwtUtil.getClaimsBody(token);//是否是过期int result = AppJwtUtil.verifyToken(claimsBody);if (result == 1 || result == 2) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//-------------------添加部分--------------------////获得token解析后中的用户信息Object userId = claimsBody.get("id");//在header中添加新的信息ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {httpHeaders.add("userId", userId + "");}).build();//重置headerexchange.mutate().request(serverHttpRequest).build();//-------------------添加部分--------------------//} catch (Exception e) {e.printStackTrace();}

此时图片上传成功,并且可以正常回显,数据库中的数据已经更新:

3.2 自媒体素材管理&素材列表查询

在xxx-model模块对应包下新增WmMaterialDto

@Data
public class WmMaterialDto extends PageRequestDto {/*** 1 收藏* 0 未收藏*/private Short isCollection;
}

三步走mapper>>>service>>>controller
另外,由于用到分页查询,需要在引导类中添加mp的分页拦截器

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;
}

在这里插入图片描述

四.自媒体文章管理

4.1 文章列表查询

在xxx-model模块对应包下新增WmMaterialDto

@Data
public class WmNewsPageReqDto extends PageRequestDto {/*** 状态*/private Short status;/*** 开始时间*/private Date beginPubDate;/*** 结束时间*/private Date endPubDate;/*** 所属频道ID*/private Integer channelId;/*** 关键字*/private String keyword;
}

对应如下:

三步走mapper>>>service>>>controller
主要来说一下业务层逻辑:
在这里插入图片描述
该查询是一个多条件分页查询

  • 1.检查查询条件
  • 2.分页参数检查
  • 3.获取当前登录人的信息
  • 4.使用lambdaQueryWrapper封装多个条件用于查询
  • 5.返回结果

针对一些核心代码进行说明:

		 //2.分页条件查询IPage page = new Page(dto.getPage(),dto.getSize());//创建了LambdaQueryWrapper 对象,并指定了泛型参数为 WmNews,这表示要查询的实体类型为 WmNewsLambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();//状态精确查询if(dto.getStatus() != null){//表示该查询条件为:数据库中字段为"status"且值等于dto.getStatus()的值的WmNewslambdaQueryWrapper.eq(WmNews::getStatus,dto.getStatus());}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2905316.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习:lambda(匿名函数)、装饰器、数据结构

Python Lambda匿名函数 Lambda函数&#xff08;或称为匿名函数&#xff09;是Python中的一种特殊函数&#xff0c;它可以用一行代码来创建简单的函数。Lambda函数通常用于需要一个函数作为输入的函数&#xff08;比如map()&#xff0c;filter()&#xff0c;sort()等&#xff0…

基于SpringBoot和Vue的在线视频教育平台的设计与实现

今天要和大家聊的是一款基于SpringBoot和Vue的在线视频教育平台的设计与实现 &#xff01;&#xff01;&#xff01; 有需要的小伙伴可以通过文章末尾名片咨询我哦&#xff01;&#xff01;&#xff01; &#x1f495;&#x1f495;作者&#xff1a;李同学 &#x1f495;&…

MybatisPlus速成

MybatisPlus快速入门 快速入门入门案例常见注解常见配置 核心功能条件构造器自定义SQLService接口 扩展功能代码生成静态工具逻辑删除枚举处理器JSON处理器 插件功能分页插件通用分页实体 参考文档 mybatis-plus参考文档 全部资料链接 讲义 快速入门 入门案例 <dependency…

打造快乐成长的乐园:探索少儿教育项目的魅力

在当今社会&#xff0c;家长们越来越重视孩子的全面发展和个性培养&#xff0c;少儿教育项目因其独特的魅力吸引着越来越多的关注。本文将探讨少儿教育项目的特点、重要性&#xff0c;以及如何打造一个快乐成长的教育乐园。 ### 少儿教育项目的价值 少儿教育项目不仅仅是传授…

【数据结构】带头双向链表的实现

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;道阻且长&#xff0c;行则将至 前言 带头双向链表是链表的一种&#xff0c;相较于单链表的实现&#xff0c;其更为简单 一.初识带头双向循环链表 带头…

Ribbon简介

目录 一 、概念介绍 1、Ribbon是什么 2、认识负载均衡 2.1 服务器端的负载均衡 2.2 客户端的负载均衡 3、Ribbon工作原理 4、Ribbon的主要组件 IClientConfig ServerList ServerListFilter IRule Iping ILoadBalancer ServerListUpdater 5、Ribbon支持…

I.MX6ULL_Linux_系统篇(25) buildroot文件系统构建

前面我们学习了如何使用 busybox 来构建根文件系统&#xff0c;但是 busybox 构建的根文件系统不齐全&#xff0c;很多东西需要我们自行添加&#xff0c;比如 lib 库文件。在我们后面的驱动开发中很多第三方软件也需要我们自己去移植&#xff0c;这些第三方软件有很多又依赖其他…

CorelDRAW25.0.0.230中文最新开心和谐版本

CorelDRAW是一款非常流行的矢量图形设计软件&#xff0c;其25.0.0.230版本带来了许多新特性和更新内容。以下是我所能提供的相关信息&#xff1a; 首先&#xff0c;关于特性方面&#xff0c;CorelDRAW 25.0.0.230版本具有强大的矢量编辑功能&#xff0c;用户可以轻松创建和编辑…

MoneyPrinterTurbo搭建详细流程(Linux)及常见问题

先附上链接: MoneyPrinterTurbohttps://github.com/harry0703/MoneyPrinterTurboMoneyPrinterTurbo是一款合成视频的软件。 你只需要提供一个主题或者关键字,就可以全自动生成视频文案、视频素材、视频字幕、视频背景音乐,然后合成一个高清的短视频。 接下来讲解详细的搭…

动态规划刷题(算法竞赛、蓝桥杯)--导弹拦截(线性DP)

1、题目链接&#xff1a;[NOIP1999 提高组] 导弹拦截 - 洛谷 #include <bits/stdc.h> using namespace std; const int N2e55; int a[N],x,n; int b[N],len;int main(){while(cin>>x)a[n]x;//求最长不上升子序列 b[0]2e9;//初始化为无穷大for(int i1;i<n;i){if(…

金属氧化物压敏电阻的冲击破坏机理高能压敏电阻分析

以氧化锌为主的金属氧化物阀片在一定的电压和电流作用下的破坏可分为热破坏和冲击破坏两类。 热破坏是指氧化锌电阻在交流电压持续作用时发生的破坏,即由于阀片在交流作用下的发热超过了其散热能力而导致的热平衡失控的现象。交流引起的热破坏可以分为几种不同情况:一种是由于…

康耐视visionpro-CogFindCircleTool工具详细说明

CogFindCircleTool功能说明: 通过用多个卡尺找到多个点来拟合所要找的圆 CogFindCircleTool操作说明: ①.打开工具栏,双击或点击鼠标拖拽添加CogFindCircleTool工具 ②.添加输入图像,右键“链接到”或以连线拖拽的方式选择相应输入源 ③.预期的圆弧:设置预期圆弧的中心点…

Zookeeper的选主流程

Zookeeper的核心是原子广播&#xff0c;这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式&#xff0c;它们分别是恢复模式&#xff08;选主&#xff09;和广播模式&#xff08;同步&#xff09;。当服务启动或者在领导者崩溃后&#xff…

【RISC-V】如何使用release的risc-v gnu toolchain

riscv64-elf-ubuntu-22.04-gcc-nightly-2024.03.01-nightly.tar.gz 首先去release页面中获取相应的压缩包 将压缩包解压到想解压的位置&#xff0c;这里我选择了 mv Downloads/riscv64-elf-ubuntu-22.04-gcc-nightly-2024.03.01-nightly.tar.gz riscv64-tool-chain/然后解压…

稀碎从零算法笔记Day26-LeetCode:跳跃游戏

断更多天&#xff0c;懒狗ex 题型&#xff1a;数组、模拟、类似双指针&#xff1f; 链接&#xff1a;55. 跳跃游戏 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组…

【实现报告】学生信息管理系统(顺序表)

目录 实验一 线性表的基本操作 一、实验目的 二、实验内容 三、实验提示 四、实验要求 五、实验代码如下&#xff1a; &#xff08;一&#xff09;顺序表的构建及初始化 &#xff08;二&#xff09;检查顺序表是否需要扩容 &#xff08;三&#xff09;根据指定学生个…

PHP图床程序优化版:图片外链服务、图床API服务、图片CDN加速与破解防盗链

图片免费上传 支持本地储存、FTP储存、第三方云储存&#xff08;阿里云 OSS、腾讯云 COS、七牛云等&#xff09;。 图片外链加速 一键转换第三方网站的图片外链地址为图床可分享的图片地址&#xff08;支持CDN&#xff09;。 图片解析服务 直接将第三方外链图片地址显示为…

【spring】AbstractApplicationContext 的refresh() 方法学习

上一篇我们一起学习了【spring】FileSystemXmlApplicationContext 类学习 AbstractApplicationContext 的refresh() 方法介绍 AbstractApplicationContext的refresh()方法仍然是整个Spring应用程序上下文初始化的核心流程入口。大体上的刷新生命周期依然保持一致。 refresh(…

基于Spring boot + Vue协同过滤算法的电影推荐系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

[RoarCTF 2019]Online Proxy --不会编程的崽

这几天也是ctf做得有点头疼了。好些序列化的题没碰&#xff0c;一直做些sql注入类的题目。闲来无事&#xff0c;在更一次sql注入吧。 整个页面就这点信息。首先想想为什么他能获取你的ip。猜测是数据包X-Forwarded-For。 它还输出上次访问页面客户端的ip。很明显了&#xff0c…