首页 文章 精选 留言 我的

精选列表

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

精通SpringBoot——第四篇:Spring事件 Application Event

Spring的事件为Bean与Bean之间的通信提供了支持,当我们系统中某个Spring管理的Bean处理完某件事后,希望让其他Bean收到通知并作出相应的处理,这时可以让其他Bean监听当前这个Bean所发送的事件。 要实现事件的监听,我们要做两件事:1:自定义事件,继承ApplicationEvent接口2:定义事件监听器,实现ApplicationListener3:事件发布类 /** * @TODO // 自定义事件,继承ApplicationEvent接口 * @Author Lensen * @Date 2018/7/22 * @Description */ public class SendMsgEvent extends ApplicationEvent { private static final long serialVersionID = 1L; // 收件人 public String receiver; // 收件内容 public String content; public SendMsgEvent(Object source) { super(source); } public SendMsgEvent(Object source, String receiver, String content) { super(source); this.receiver = receiver; this.content = content; } public void output(){ System.out.println("I had been sand a msg to " + this.receiver); } } /** * @TODO //定义事件监听器,实现ApplicationListener * @Author Lensen * @Date 2018/7/22 * @Description */@Component public class MsgListener implements ApplicationListener<SendMsgEvent> { @Override public void onApplicationEvent(SendMsgEvent sendMsgEvent) { sendMsgEvent.output(); System.out.println(sendMsgEvent.receiver + "received msg : " + sendMsgEvent.content ); } } 事件发布类 @Component public class Publisher { @Autowired ApplicationContext applicationContext; public void publish(Object source, String receiver, String content){ applicationContext.publishEvent(new SendMsgEvent(source, receiver, content)); } } 测试消息:WebConfig.class主要是为了扫描Publisher 和Listener类。里面有两个注解@ComponenScan和@Configuration。 public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(WebConfig.class); Publisher publisher = applicationContext.getBean(Publisher.class); publisher.publish("Hello,World!","Mr.Lensen", "I Love U"); } 结果: I had been sand a msg to Mr.Lensen Mr.Lensen received msg : I Love U

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

SpringBoot 整合 oauth2(五)实现 jwt 及 扩展

什么是jwt,即 json web token。JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。也是一种token,但是和token有一些不同。 jwt优点: 自包含 防篡改 可自定义扩展 JWT的结构 JWT包含了使用.分割的三部分: Header 头部 Payload 负载 Signature 签名 比如:eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9 三个新东西 什么是自包含? 字符串里包含用户信息。 什么是防篡改? 签名用于验证消息的发送者以及消息是没有经过篡改的。 可扩展是什么意思? 你可以在Payload部分加入自己想加入的json字符串 那我们既然token的实现方式那么优秀,为什么还要有jwt呢,这就需要了解他们的生成机制。 token生成的其实就是一个UUID,和业务没有丝毫的关系,这样带来最大的问题,就是需要人工持久化处理token(像处理分布式下的sessionId一样)。但是jwt就不需要,因为自包含,所以token里有身份验证信息,不需要做后台持久化处理,前端每次请求被保护的资源时请求头里带上该token就可以实现。 好了开始正文。 本文建立在第三节的基础上。这里是顺风车 1. 新增JwtTokenConfig @Configuration public class JwtTokenConfig{ @Bean public TokenStore jwtTokenStore(){ return new JwtTokenStore(jwtAccessTokenConverter()); } /** * token生成处理:指定签名 */ @Bean public JwtAccessTokenConverter jwtAccessTokenConverter(){ JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); accessTokenConverter.setSigningKey("internet_plus"); return accessTokenConverter; } } jwtTokenStore方法返回一个TokenStore对象的子对象JwtTokenStore,供给认证服务器取来给授权服务器端点配置器,通俗点就是让MyAuthorizationServerConfig能注入到值。 jwtAccessTokenConverter方法是根据签名生成JwtToken,同样也需要在MyAuthorizationServerConfig类里注入。 修改MyAuthorizationServerConfig 的 configure方法 /** * 认证服务器 * Created by Fant.J. */ @Configuration @EnableAuthorizationServer public class MyAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private TokenStore tokenStore; @Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { super.configure(security); } /** * 客户端配置(给谁发令牌) * @param clients * @throws Exception */ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient(ConsParams.Auth.GET_CLIENT_ID) .secret(ConsParams.Auth.GET_SECRET) //有效时间 2小时 .accessTokenValiditySeconds(ConsParams.Auth.GET_TOKEN_VALIDITY_SECONDS) //密码授权模式和刷新令牌 .authorizedGrantTypes(ConsParams.Auth.GE_TAUTHORIZED_GRANT_TYPES) .scopes(ConsParams.Auth.GE_TSCOPES); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(tokenStore) .authenticationManager(authenticationManager) .userDetailsService(userDetailsService) .accessTokenConverter(jwtAccessTokenConverter); } } } 和第三节不同的是 endpoints添加了accessTokenConverter属性,它规定了token生成器是jwtAccessTokenConverter,并按照我们设置的签名来生成。 启动项目 给/oauth/token 发送post请求获取token 请求头:Authorization:Basic +clientid:secret 的base64加密字符串 (认证服务器中设置的client信息) 请求参数:username password (用户登陆账号密码) 2. JWT扩展 在前文我们介绍过jwt的可扩展性,一般情况下实现jwt就可以了,但是有一些特殊需求,比如你想在返回的token中附带一些别的信息,这就需要我们对jwt进行扩展。 2.1 修改JwtTokenConfig 新增jwtTokenEnhancer方法 @Configuration public class JwtTokenConfig{ @Bean public TokenStore jwtTokenStore(){ return new JwtTokenStore(jwtAccessTokenConverter()); } /** * token生成处理:指定签名 */ @Bean public JwtAccessTokenConverter jwtAccessTokenConverter(){ JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); accessTokenConverter.setSigningKey("internet_plus"); return accessTokenConverter; } @Bean public TokenEnhancer jwtTokenEnhancer(){ return new JwtTokenEnhancer(); } } jwtTokenEnhancer方法 返回一个JwtTokenEnhancer并交给bean工厂。 2.2 增加JwtTokenEnhancer类 /** * Jwt token 扩展 * Created by Fant.J. */ public class JwtTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) { Map<String,Object> info = new HashMap<>(); info.put("provider","Fant.J"); //设置附加信息 ((DefaultOAuth2AccessToken)oAuth2AccessToken).setAdditionalInformation(info); return oAuth2AccessToken; } } 重写TokenEnhancer的enhance方法,根据需求扩展jwt。 2.3 修改MyAuthorizationServerConfig类 /** * 认证服务器 * Created by Fant.J. */ @Configuration @EnableAuthorizationServer public class MyAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private TokenStore tokenStore; @Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; @Autowired private TokenEnhancer jwtTokenEnhancer; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { super.configure(security); } /** * 客户端配置(给谁发令牌) * @param clients * @throws Exception */ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient(ConsParams.Auth.GET_CLIENT_ID) .secret(ConsParams.Auth.GET_SECRET) //有效时间 2小时 .accessTokenValiditySeconds(ConsParams.Auth.GET_TOKEN_VALIDITY_SECONDS) //密码授权模式和刷新令牌 .authorizedGrantTypes(ConsParams.Auth.GE_TAUTHORIZED_GRANT_TYPES) .scopes(ConsParams.Auth.GE_TSCOPES); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(tokenStore) .authenticationManager(authenticationManager) .userDetailsService(userDetailsService); TokenEnhancerChain enhancerChain = new TokenEnhancerChain(); List<TokenEnhancer> enhancerList = new ArrayList<>(); enhancerList.add(jwtTokenEnhancer); enhancerList.add(jwtAccessTokenConverter); enhancerChain.setTokenEnhancers(enhancerList); endpoints .tokenEnhancer(enhancerChain) .accessTokenConverter(jwtAccessTokenConverter); } } endpoints的tokenEnhancer方法需要我们提供一个token增强器链对象TokenEnhancerChain,所以我们需要在链中加入我们重写的TokenEnhancer和jwtAccessTokenConverter,然后放入endpoints。 启动项目 和上文获取token方式相同。 下图红框便是我添加的扩展。 解析jwt,获取扩展信息 如果我们需要获取jwt本来就有的信息,我们直接请求方法中吧Authentication当做参数,就可以获取到jwt原始信息。 如果我们需要获取jwt扩展的信息,即我们自定义添加的信息,我们需要做这几个操作: pom导入依赖 <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> UserController.java @GetMapping("/me") public ServerResponse getCurrentUser(Authentication user, HttpServletRequest request) throws UnsupportedEncodingException { String s = user.getPrincipal().toString(); String name = user.getName(); String header = request.getHeader("Authorization"); String token = StringUtils.substringAfter(header,"bearer "); Claims body = Jwts.parser().setSigningKey(ConsParams.Auth.GET_SIGNING_KEY.getBytes("UTF-8")) .parseClaimsJws(token).getBody(); String username = (String) body.get("username"); log.info("解析token获取到的username为{}",username); log.info("从Authentication里获取到的username为{}",s); log.info("从Authentication里获取到的username为{}",name); return ServerResponse.createBySuccess(user); } 介绍下我的所有文集: 流行框架 SpringCloudspringbootnginxredis 底层实现原理: Java NIO教程Java reflection 反射详解Java并发学习笔录Java Servlet教程jdbc组件详解Java NIO教程Java语言/版本 研究

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

SOFABoot 4.5.0 发布,蚂蚁开源的基于 Springboot 的服务框架

SOFABoot 是蚂蚁金服开源的基于 Spring Boot 的研发框架,它在 Spring Boot 的基础上,提供了诸如 Readiness Check,类隔离,日志空间隔离等等能力。在增强了 Spring Boot 的同时,SOFABoot 提供了让用户可以在 Spring Boot 中非常方便地使用 SOFA 中间件的能力。 SOFABoot 4.5.0现已发布,具体更新内容包括: 新功能 当组件注册失败时Fast Fail#1374 支持 spring boot 3.5.3#1379 将 OSSRH 更改为Central Portal#1382 错误修复 修复 StandardSofaRuntimeManager 内存泄漏#1373 更改 Maven 用户名和密码的操作#1386 Replenish module name#1388 依赖项升级 将 rpc 版本升级到 5.13.4,将 tracer 版本升级到 4.0.2#1367 将 staging plugin 版本升级到 1.7.0#1381 更新说明:https://github.com/sofastack/sofa-boot/releases/tag/v4.5.0

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

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

用户登录
用户注册