首页 文章 精选 留言 我的

精选列表

搜索[java],共10000篇文章
优秀的个人博客,低调大师

从零用 Java 实现小红书 SpringBoot Vue UniApp(23)笔记话题多对多:一条笔记进多个话题池

## [移动端演示](http://8.146.211.120:8081/) ## [管理端演示](http://8.146.211.120:8088/) **前言** 早期实现里,一篇笔记只挂一个 `topic_id`:运营在后台改话题、用户在发现页按话题筛,都够用。但真实社区里常见 **同一篇笔记同时出现在「穿搭」和「好物分享」** 两个话题池——单字段就卡住了。 在不破坏旧数据的前提下,增加关联表 `member_note_topic_rel`,主话题仍写 `member_note.topic_id`(取多选列表第一个),其余话题走关联表;管理端笔记表单支持 **多选话题**,发现流按关联表过滤。 ![移动端:发现页](https://developer.qcloudimg.com/http-save/yehe-12101878/286e43f7a692fc2263cfa195454191e8.png) ![移动端:市集频道](https://developer.qcloudimg.com/http-save/yehe-12101878/e5dc07478f570c1581e2ac92eb013790.png) ![管理端:运营看板](https://developer.qcloudimg.com/http-save/yehe-12101878/b1db43f380cdad495ed9b9b70d2f0bf9.png) ---- ### 单话题与多对多对比 |维度|单话题字段|多对多| |:-:|:-:|:-:| |数据模型|`member_note.topic_id`|`topic_id` + `member_note_topic_rel`| |后台编辑|单选下拉|`el-select` 多选 `topicIds`| |发现页筛选|`WHERE topic_id = ?`|`note_id IN (SELECT … FROM rel WHERE topic_id = ?)`| |兼容历史|—|无 rel 时回退读 `topic_id`| ---- ### 一、表结构(可重复执行) 脚本:`sql/mysql/member_note_topic_rel.sql` - `note_id` + `topic_id` 唯一(含软删) - `sort`:0 表示主话题,与 `member_note.topic_id` 对齐 - 初始化 `INSERT … SELECT`:把已有笔记的主话题灌进 rel,避免上线后旧笔记「消失」 ---- ### 二、后端:保存时先删后插 管理端保存、App 发布带话题时,统一走 `replaceNoteTopics`: ``` private void replaceNoteTopics(Long noteId, List topicIds) { memberNoteTopicRelMapper.deleteByNoteId(noteId); if (CollUtil.isEmpty(topicIds)) { return; } int sort = 0; for (Long topicId : topicIds) { memberNoteTopicRelMapper.insert(MemberNoteTopicRelDO.builder() .noteId(noteId) .topicId(topicId) .sort(sort++) .build()); } } ``` `resolveAdminTopicIds` 校验每个话题属于当前频道后,**第一个 topicId 写回 `member_note.topic_id`**,保证旧接口、旧报表仍有一个「主话题」字段可读。 读详情时 `getNoteTopicIds`:**优先 rel 列表**,没有 rel 再降级 `note.topicId`,H5 不必一次性全量洗数据。 ---- ### 三、发现流 SQL:关联表子查询 `MemberNoteMapper` 在按话题筛选时,条件从单表字段改为: ``` note_id IN (SELECT note_id FROM member_note_topic_rel WHERE deleted = 0 AND topic_id = #{topicId}) ``` 同一套逻辑用于关注频道、同城等多场景列表,避免「后台挂了 B 话题、前台只在 A 话题能看到」的割裂。 ---- ### 四、管理端表单:多选 + 校验 管理端 `views/member/note/NoteForm.vue` - 表单项 `topicIds`:`el-select` `multiple` - 提交:`topicId: topicIds[0]`,同时传 `topicIds` 数组 - 回显:`data.topicIds?.length ? data.topicIds : [data.topicId]` 运营同学一次勾选多个话题即可,不必复制笔记。 ![管理端:笔记话题与站点配置](https://developer.qcloudimg.com/http-save/yehe-12101878/268394db07545a119337e52e5cadf14b.png) ---- ### 五、App 侧 用户发布笔记时,正文 `#话题名` 解析仍会自动挂话题;多对多主要在 **运营纠偏、活动合集** 场景由后台补挂。C 端若只选一个话题,行为与旧版一致。 ---- ### 关键代码位置 |模块|路径| |:-:|:-:| |DO / Mapper|member 模块 `MemberNoteTopicRelDO`、`MemberNoteTopicRelMapper`| |业务|`MemberNoteServiceImpl#replaceNoteTopics`、`getNoteTopicIds`| |管理端 VO|`MemberNoteSaveReqVO.topicIds`、`MemberNoteRespVO.topicIds`| |管理端 UI|`views/member/note/NoteForm.vue`| ---- ### 总结 多对多不是「再加一个下拉」,而是 **关联表 + 主话题兼容 + 列表 SQL 统一走 rel**。这样一条爆款笔记可以同时进多个话题池,后台也不用复制内容。 >源码:https://gitee.com/ddeatrr/springboot_vue_xhs

优秀的个人博客,低调大师

java版spring cloud+spring boot+redis社交电子商务平台-SSO单点登录之OAuth2.0登录认证

之前写了很多关于spring cloud的文章,今天我们对OAuth2.0的整合方式做一下笔记,首先我从网上找了一些关于OAuth2.0的一些基础知识点,帮助大家回顾一下知识点: 一、oauth中的角色 client:调用资源服务器API的应用 Oauth 2.0 Provider:包括Authorization Server和Resource Server (1)Authorization Server:认证服务器,进行认证和授权 (2)Resource Server:资源服务器,保护受保护的资源 user:资源的拥有者 二、下面详细介绍一下Oauth 2.0 Provider Authorization Server: (1)AuthorizationEndpoint:进行授权的服务,Default URL: /oauth/authorize (2)TokenEndpoint:获取token的服务,Default URL: /oauth/token Resource Server: OAuth2AuthenticationProcessingFilter:给带有访问令牌的请求加载认证 三、下面再来详细介绍一下Authorization Server: 一般情况下,创建两个配置类,一个继承AuthorizationServerConfigurerAdapter,一个继承WebSecurityConfigurerAdapter,再去复写里面的方法。 主要出现的两种注解: 1、@EnableAuthorizationServer:声明一个认证服务器,当用此注解后,应用启动后将自动生成几个Endpoint:(注:其实实现一个认证服务器就是这么简单,加一个注解就搞定,当然真正用到生产环境还是要进行一些配置和复写工作的。) /oauth/authorize:验证 /oauth/token:获取token /oauth/confirm_access:用户授权 /oauth/error:认证失败 /oauth/check_token:资源服务器用来校验token /oauth/token_key:如果jwt模式则可以用此来从认证服务器获取公钥 以上这些endpoint都在源码里的endpoint包里面。 2、@Beans:需要实现AuthorizationServerConfigurer AuthorizationServerConfigurer包含三种配置: ClientDetailsServiceConfigurer:client客户端的信息配置,client信息包括:clientId、secret、scope、authorizedGrantTypes、authorities (1)scope:表示权限范围,可选项,用户授权页面时进行选择 (2)authorizedGrantTypes:有四种授权方式 Authorization Code:用验证获取code,再用code去获取token(用的最多的方式,也是最安全的方式) Implicit: 隐式授权模式 Client Credentials (用來取得 App Access Token) Resource Owner Password Credentials (3)authorities:授予client的权限 这里的具体实现有多种,in-memory、JdbcClientDetailsService、jwt等。 AuthorizationServerSecurityConfigurer:声明安全约束,哪些允许访问,哪些不允许访问 AuthorizationServerEndpointsConfigurer:声明授权和token的端点以及token的服务的一些配置信息,比如采用什么存储方式、token的有效期等 client的信息的读取:在ClientDetailsServiceConfigurer类里面进行配置,可以有in-memory、jdbc等多种读取方式。 jdbc需要调用JdbcClientDetailsService类,此类需要传入相应的DataSource. 下面再介绍一下如何管理token: AuthorizationServerTokenServices接口:声明必要的关于token的操作 (1)当token创建后,保存起来,以便之后的接受访问令牌的资源可以引用它。 (2)访问令牌用来加载认证 接口的实现也有多种,DefaultTokenServices是其默认实现,他使用了默认的InMemoryTokenStore,不会持久化token; token存储方式共有三种分别是:(1)InMemoryTokenStore:存放内存中,不会持久化 (2)JdbcTokenStore:存放数据库中 (3)Jwt: json web token 授权类型: 可以通过AuthorizationServerEndpointsConfigurer来进行配置,默认情况下,支持除了密码外的所有授权类型。相关授权类型的一些类: (1)authenticationManager:直接注入一个AuthenticationManager,自动开启密码授权类型 (2)userDetailsService:如果注入UserDetailsService,那么将会启动刷新token授权类型,会判断用户是否还是存活的 (3)authorizationCodeServices:AuthorizationCodeServices的实例,auth code 授权类型的服务 (4)implicitGrantService:imlpicit grant (5)tokenGranter: endpoint的URL的配置: (1)AuthorizationServerEndpointsConfigurer的pathMapping()方法,有两个参数,第一个是默认的URL路径,第二个是自定义的路径 (2)WebSecurityConfigurer的实例,可以配置哪些路径不需要保护,哪些需要保护。默认全都保护。 自定义UI: (1)有时候,我们可能需要自定义的登录页面和认证页面。登陆页面的话,只需要创建一个login为前缀名的网页即可,在代码里,设置为允许访问,这样,系统会自动执行你的登陆页。此登陆页的action要注意一下,必须是跳转到认证的地址。 (2)另外一个是授权页,让你勾选选项的页面。此页面可以参考源码里的实现,自己生成一个controller的类,再创建一个对应的web页面即可实现自定义的功能。 下面梳理一下授权获取token流程: (1)端口号换成你自己的认证服务器的端口号,client_id也换成你自己的,response_type类型为code。 localhost:8080/uaa/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com(2)这时候你将获得一个code值:http://www.baidu.com/?code=G0C20Z (3)使用此code值来获取最终的token: curl -X POST -H “Cant-Type: application/x-www-form-urlencoded” -d ‘grant_type=authorization_code&code=G0C20Z&redirect_uri=http://www.baidu.com’ “http://client:secret@localhost:8080/uaa/oauth/token” 返回值: {“access_token”:“b251b453-cc08-4520-9dd0-9aedf58e6ca3”,“token_type”:“bearer”,“expires_in”:2591324,“scope”:“app”} (4)用此token值来调用资源服务器内容(如果资源服务器和认证服务器在同一个应用中,那么资源服务器会自己解析token值,如果不在,那么你要自己去做处理) curl -H “Authorization: Bearer b251b453-cc08-4520-9dd0-9aedf58e6ca3” “localhost:8081/service2(此处换上你自己的url)” 四、Resource Server:保护资源,需要令牌才能访问 在配置类上加上注解@EnableResourceServer即启动。使用ResourceServerConfigurer进行配置: (1)tokenServices:ResourceServerTokenServices的实例,声明了token的服务 (2)resourceId:资源Id,由auth Server验证。 (3)其它一些扩展点,比如可以从请求中提取token的tokenExtractor (4)一些自定义的资源保护配置,通过HttpSecurity来设置 使用token的方式也有两种: (1)Bearer Token(https传输方式保证传输过程的安全):主流 (2)Mac(http+sign) 如何访问资源服务器中的API? 如果资源服务器和授权服务器在同一个应用程序中,并且您使用DefaultTokenServices,那么您不必太考虑这一点,因为它实现所有必要的接口,因此它是自动一致的。如果您的资源服务器是一个单独的应用程序,那么您必须确保您匹配授权服务器的功能,并提供知道如何正确解码令牌的ResourceServerTokenServices。与授权服务器一样,您可以经常使用DefaultTokenServices,并且选项大多通过TokenStore(后端存储或本地编码)表示。 (1)在校验request中的token时,使用RemoteTokenServices去调用AuthServer中的/auth/check_token。 (2)共享数据库,使用Jdbc存储和校验token,避免再去访问AuthServer。 (3)使用JWT签名的方式,资源服务器自己直接进行校验,不借助任何中间媒介。 五、oauth client 在客户端获取到token之后,想去调用下游服务API时,为了能将token进行传递,可以使用RestTemplate.然后使用restTemplate进行调用Api。 注: scopes和authorities的区别: scopes是client权限,至少授予一个scope的权限,否则报错。 authorities是用户权限。 以上是我从网上找到的一篇写的不错的博客,希望可以帮助大家快速了解OAuth2.0,下一篇文章我们正式介绍OAuth2.0在当前框架中的使用。 从现在开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精髓记录下来,帮助更多有兴趣研发spring cloud框架的朋友,大家来一起探讨spring cloud架构的搭建过程及如何运用于企业项目。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册