自定义MongoDB的Spring Social Connect框架

在上一篇文章中 ,我谈到了我面临的第一个挑战是更改数据模型并添加连接框架。 在这里,我想提供有关我如何做的更多详细信息。 Spring Social项目已经提供了基于jdbc的连接存储库实现,以将用户连接数据持久保存到关系数据库中。 但是,我使用的是MongoDB,因此我需要自定义代码,并且发现这样做相对容易。 用户连接数据将另存为UserSocialConnection对象,它是一个MongoDB文档:

@SuppressWarnings('serial')
@Document(collection = 'UserSocialConnection')
public class UserSocialConnection extends BaseEntity {private String userId;private String providerId;private String providerUserId;private String displayName;private String profileUrl;private String imageUrl;private String accessToken;private String secret;private String refreshToken;private Long expireTime;//Getter/Setter omitted.public UserSocialConnection() {super();}public UserSocialConnection(String userId, String providerId, String providerUserId, int rank,String displayName, String profileUrl, String imageUrl, String accessToken, String secret,String refreshToken, Long expireTime) {super();this.userId = userId;this.providerId = providerId;this.providerUserId = providerUserId;this.displayName = displayName;this.profileUrl = profileUrl;this.imageUrl = imageUrl;this.accessToken = accessToken;this.secret = secret;this.refreshToken = refreshToken;this.expireTime = expireTime;}
}

BaseEntity仅具有“ id”。 借助于Spring Data项目,我不需要为UserSocialConnection编写任何CRUD操作代码,只需扩展MongoRepository

public interface UserSocialConnectionRepository extends MongoRepository<UserSocialConnection, String>{List<UserSocialConnection> findByUserId(String userId);List<UserSocialConnection> findByUserIdAndProviderId(String userId, String providerId);List<UserSocialConnection> findByProviderIdAndProviderUserId(String providerId, String providerUserId);UserSocialConnection findByUserIdAndProviderIdAndProviderUserId(String userId, String providerId, String providerUserId);List<UserSocialConnection> findByProviderIdAndProviderUserIdIn(String providerId, Collection<String> providerUserIds);
}

在拥有数据库UserSocialConnectionRepository ,我们将实现Spring Social所需的ConnectionRepositoryUsersConnectionRepository 。 我只是从JdbcConnectionRepositoryJdbcUsersConnectionRepository复制了代码,并创建了自己的MongoConnectionRepositoryMongoUsersConnectionRepository

public class MongoUsersConnectionRepository implements UsersConnectionRepository{private final UserSocialConnectionRepository userSocialConnectionRepository;private final SocialAuthenticationServiceLocator socialAuthenticationServiceLocator;private final TextEncryptor textEncryptor;private ConnectionSignUp connectionSignUp;public MongoUsersConnectionRepository(UserSocialConnectionRepository userSocialConnectionRepository, SocialAuthenticationServiceLocator socialAuthenticationServiceLocator, TextEncryptor textEncryptor){this.userSocialConnectionRepository = userSocialConnectionRepository;this.socialAuthenticationServiceLocator = socialAuthenticationServiceLocator;this.textEncryptor = textEncryptor;}/*** The command to execute to create a new local user profile in the event no user id could be mapped to a connection.* Allows for implicitly creating a user profile from connection data during a provider sign-in attempt.* Defaults to null, indicating explicit sign-up will be required to complete the provider sign-in attempt.* @see #findUserIdsWithConnection(Connection)*/public void setConnectionSignUp(ConnectionSignUp connectionSignUp) {this.connectionSignUp = connectionSignUp;}public List<String> findUserIdsWithConnection(Connection<?> connection) {ConnectionKey key = connection.getKey();List<UserSocialConnection> userSocialConnectionList = this.userSocialConnectionRepository.findByProviderIdAndProviderUserId(key.getProviderId(), key.getProviderUserId());List<String> localUserIds = new ArrayList<String>();for (UserSocialConnection userSocialConnection : userSocialConnectionList){localUserIds.add(userSocialConnection.getUserId());}if (localUserIds.size() == 0 && connectionSignUp != null) {String newUserId = connectionSignUp.execute(connection);if (newUserId != null){createConnectionRepository(newUserId).addConnection(connection);return Arrays.asList(newUserId);}}return localUserIds;}public Set<String> findUserIdsConnectedTo(String providerId, Set<String> providerUserIds) {final Set<String> localUserIds = new HashSet<String>();List<UserSocialConnection> userSocialConnectionList = this.userSocialConnectionRepository.findByProviderIdAndProviderUserIdIn(providerId, providerUserIds);for (UserSocialConnection userSocialConnection : userSocialConnectionList){localUserIds.add(userSocialConnection.getUserId());}return localUserIds;}public ConnectionRepository createConnectionRepository(String userId) {if (userId == null) {throw new IllegalArgumentException('userId cannot be null');}return new MongoConnectionRepository(userId, userSocialConnectionRepository, socialAuthenticationServiceLocator, textEncryptor);}}

MongoUsersConnectionRepository非常类似于JdbcUsersConnectionRepository 。 但是对于MongoConnectionRepository ,我需要进行一些更改:

public class MongoConnectionRepository implements ConnectionRepository {private final String userId;private final UserSocialConnectionRepository userSocialConnectionRepository;private final SocialAuthenticationServiceLocator socialAuthenticationServiceLocator;private final TextEncryptor textEncryptor;public MongoConnectionRepository(String userId, UserSocialConnectionRepository userSocialConnectionRepository,SocialAuthenticationServiceLocator socialAuthenticationServiceLocator, TextEncryptor textEncryptor) {this.userId = userId;this.userSocialConnectionRepository = userSocialConnectionRepository;this.socialAuthenticationServiceLocator = socialAuthenticationServiceLocator;this.textEncryptor = textEncryptor;}public MultiValueMap<String, Connection<?>> findAllConnections() {List<UserSocialConnection> userSocialConnectionList = this.userSocialConnectionRepository.findByUserId(userId);MultiValueMap<String, Connection<?>> connections = new LinkedMultiValueMap<String, Connection<?>>();Set<String> registeredProviderIds = socialAuthenticationServiceLocator.registeredProviderIds();for (String registeredProviderId : registeredProviderIds) {connections.put(registeredProviderId, Collections.<Connection<?>> emptyList());}for (UserSocialConnection userSocialConnection : userSocialConnectionList) {String providerId = userSocialConnection.getProviderId();if (connections.get(providerId).size() == 0) {connections.put(providerId, new LinkedList<Connection<?>>());}connections.add(providerId, buildConnection(userSocialConnection));}return connections;}public List<Connection<?>> findConnections(String providerId) {List<Connection<?>> resultList = new LinkedList<Connection<?>>();List<UserSocialConnection> userSocialConnectionList = this.userSocialConnectionRepository.findByUserIdAndProviderId(userId, providerId);for (UserSocialConnection userSocialConnection : userSocialConnectionList) {resultList.add(buildConnection(userSocialConnection));}return resultList;}@SuppressWarnings('unchecked')public <A> List<Connection<A>> findConnections(Class<A> apiType) {List<?> connections = findConnections(getProviderId(apiType));return (List<Connection<A>>) connections;}public MultiValueMap<String, Connection<?>> findConnectionsToUsers(MultiValueMap<String, String> providerUsers) {if (providerUsers == null || providerUsers.isEmpty()) {throw new IllegalArgumentException('Unable to execute find: no providerUsers provided');}MultiValueMap<String, Connection<?>> connectionsForUsers = new LinkedMultiValueMap<String, Connection<?>>();for (Iterator<Entry<String, List<String>>> it = providerUsers.entrySet().iterator(); it.hasNext();) {Entry<String, List<String>> entry = it.next();String providerId = entry.getKey();List<String> providerUserIds = entry.getValue();List<UserSocialConnection> userSocialConnections = this.userSocialConnectionRepository.findByProviderIdAndProviderUserIdIn(providerId, providerUserIds);List<Connection<?>> connections = new ArrayList<Connection<?>>(providerUserIds.size());for (int i = 0; i < providerUserIds.size(); i++) {connections.add(null);}connectionsForUsers.put(providerId, connections);for (UserSocialConnection userSocialConnection : userSocialConnections) {String providerUserId = userSocialConnection.getProviderUserId();int connectionIndex = providerUserIds.indexOf(providerUserId);connections.set(connectionIndex, buildConnection(userSocialConnection));}}return connectionsForUsers;}public Connection<?> getConnection(ConnectionKey connectionKey) {UserSocialConnection userSocialConnection = this.userSocialConnectionRepository.findByUserIdAndProviderIdAndProviderUserId(userId, connectionKey.getProviderId(),connectionKey.getProviderUserId());if (userSocialConnection != null) {return buildConnection(userSocialConnection);}throw new NoSuchConnectionException(connectionKey);}@SuppressWarnings('unchecked')public <A> Connection<A> getConnection(Class<A> apiType, String providerUserId) {String providerId = getProviderId(apiType);return (Connection<A>) getConnection(new ConnectionKey(providerId, providerUserId));}@SuppressWarnings('unchecked')public <A> Connection<A> getPrimaryConnection(Class<A> apiType) {String providerId = getProviderId(apiType);Connection<A> connection = (Connection<A>) findPrimaryConnection(providerId);if (connection == null) {throw new NotConnectedException(providerId);}return connection;}@SuppressWarnings('unchecked')public <A> Connection<A> findPrimaryConnection(Class<A> apiType) {String providerId = getProviderId(apiType);return (Connection<A>) findPrimaryConnection(providerId);}public void addConnection(Connection<?> connection) {//check cardinalitySocialAuthenticationService<?> socialAuthenticationService = this.socialAuthenticationServiceLocator.getAuthenticationService(connection.getKey().getProviderId());if (socialAuthenticationService.getConnectionCardinality() == ConnectionCardinality.ONE_TO_ONE ||socialAuthenticationService.getConnectionCardinality() == ConnectionCardinality.ONE_TO_MANY){List<UserSocialConnection> storedConnections = this.userSocialConnectionRepository.findByProviderIdAndProviderUserId(connection.getKey().getProviderId(), connection.getKey().getProviderUserId());if (storedConnections.size() > 0){//not allow one providerId connect to multiple userIdthrow new DuplicateConnectionException(connection.getKey());}}UserSocialConnection userSocialConnection = this.userSocialConnectionRepository.findByUserIdAndProviderIdAndProviderUserId(userId, connection.getKey().getProviderId(), connection.getKey().getProviderUserId());if (userSocialConnection == null) {ConnectionData data = connection.createData();userSocialConnection = new UserSocialConnection(userId, data.getProviderId(), data.getProviderUserId(), 0,data.getDisplayName(), data.getProfileUrl(), data.getImageUrl(), encrypt(data.getAccessToken()),encrypt(data.getSecret()), encrypt(data.getRefreshToken()), data.getExpireTime());this.userSocialConnectionRepository.save(userSocialConnection);} else {throw new DuplicateConnectionException(connection.getKey());}}public void updateConnection(Connection<?> connection) {ConnectionData data = connection.createData();UserSocialConnection userSocialConnection = this.userSocialConnectionRepository.findByUserIdAndProviderIdAndProviderUserId(userId, connection.getKey().getProviderId(), connection.getKey().getProviderUserId());if (userSocialConnection != null) {userSocialConnection.setDisplayName(data.getDisplayName());userSocialConnection.setProfileUrl(data.getProfileUrl());userSocialConnection.setImageUrl(data.getImageUrl());userSocialConnection.setAccessToken(encrypt(data.getAccessToken()));userSocialConnection.setSecret(encrypt(data.getSecret()));userSocialConnection.setRefreshToken(encrypt(data.getRefreshToken()));userSocialConnection.setExpireTime(data.getExpireTime());this.userSocialConnectionRepository.save(userSocialConnection);}}public void removeConnections(String providerId) {List<UserSocialConnection> userSocialConnectionList = this.userSocialConnectionRepository.findByUserIdAndProviderId(userId, providerId);for (UserSocialConnection userSocialConnection : userSocialConnectionList) {this.userSocialConnectionRepository.delete(userSocialConnection);}}public void removeConnection(ConnectionKey connectionKey) {UserSocialConnection userSocialConnection = this.userSocialConnectionRepository.findByUserIdAndProviderIdAndProviderUserId(userId, connectionKey.getProviderId(), connectionKey.getProviderUserId());this.userSocialConnectionRepository.delete(userSocialConnection);}// internal helpersprivate Connection<?> buildConnection(UserSocialConnection userSocialConnection) {ConnectionData connectionData = new ConnectionData(userSocialConnection.getProviderId(),userSocialConnection.getProviderUserId(), userSocialConnection.getDisplayName(),userSocialConnection.getProfileUrl(), userSocialConnection.getImageUrl(),decrypt(userSocialConnection.getAccessToken()), decrypt(userSocialConnection.getSecret()),decrypt(userSocialConnection.getRefreshToken()), userSocialConnection.getExpireTime());ConnectionFactory<?> connectionFactory = this.socialAuthenticationServiceLocator.getConnectionFactory(connectionData.getProviderId());return connectionFactory.createConnection(connectionData);}private Connection<?> findPrimaryConnection(String providerId) {List<UserSocialConnection> userSocialConnectionList = this.userSocialConnectionRepository.findByUserIdAndProviderId(userId, providerId);return buildConnection(userSocialConnectionList.get(0));}private <A> String getProviderId(Class<A> apiType) {return socialAuthenticationServiceLocator.getConnectionFactory(apiType).getProviderId();}private String encrypt(String text) {return text != null ? textEncryptor.encrypt(text) : text;}private String decrypt(String encryptedText) {return encryptedText != null ? textEncryptor.decrypt(encryptedText) : encryptedText;}}

首先,我将JdbcTemplate替换为UserSocialConnectionRepository以从数据库中检索UserSocialConnection对象。 然后从spring-social-security模块中用SocialAuthenticationServiceLocator替换ConnectionFactoryLocator 。 最大的变化是addConnection方法(上面已突出显示),它首先检查连接基数。 如果connectionCardinalitysocialAuthenticationServiceONE_TO_ONE (这意味着一个用户id与一个且仅一个对providerId / providerUserId的),或ONE_TO_MANY (这意味着一个用户id可以连接到一个或多个providerId / providerUserId,但一对providerId / providerUserId的只能连接到一个userId)。

完成所有这些自定义之后,最后一步是在spring config中将它们粘合在一起:

@Configuration
public class SocialAndSecurityConfig {@Injectprivate Environment environment;@InjectAccountService accountService;@Injectprivate AuthenticationManager authenticationManager;@Injectprivate UserSocialConnectionRepository userSocialConnectionRepository;@Beanpublic SocialAuthenticationServiceLocator socialAuthenticationServiceLocator() {SocialAuthenticationServiceRegistry registry = new SocialAuthenticationServiceRegistry();//add googleOAuth2ConnectionFactory<Google> googleConnectionFactory = new GoogleConnectionFactory(environment.getProperty('google.clientId'),environment.getProperty('google.clientSecret'));OAuth2AuthenticationService<Google> googleAuthenticationService = new OAuth2AuthenticationService<Google>(googleConnectionFactory);googleAuthenticationService.setScope('https://www.googleapis.com/auth/userinfo.profile');registry.addAuthenticationService(googleAuthenticationService);//add twitterOAuth1ConnectionFactory<Twitter> twitterConnectionFactory = new TwitterConnectionFactory(environment.getProperty('twitter.consumerKey'),environment.getProperty('twitter.consumerSecret'));OAuth1AuthenticationService<Twitter> twitterAuthenticationService = new OAuth1AuthenticationService<Twitter>(twitterConnectionFactory);registry.addAuthenticationService(twitterAuthenticationService);//add facebookOAuth2ConnectionFactory<Facebook> facebookConnectionFactory = new FacebookConnectionFactory(environment.getProperty('facebook.clientId'),environment.getProperty('facebook.clientSecret'));OAuth2AuthenticationService<Facebook> facebookAuthenticationService = new OAuth2AuthenticationService<Facebook>(facebookConnectionFactory);facebookAuthenticationService.setScope('');registry.addAuthenticationService(facebookAuthenticationService);return registry;}/*** Singleton data access object providing access to connections across all users.*/@Beanpublic UsersConnectionRepository usersConnectionRepository() {MongoUsersConnectionRepository repository = new MongoUsersConnectionRepository(userSocialConnectionRepository,socialAuthenticationServiceLocator(), Encryptors.noOpText());repository.setConnectionSignUp(autoConnectionSignUp());return repository;}/*** Request-scoped data access object providing access to the current user's connections.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public ConnectionRepository connectionRepository() {UserAccount user = AccountUtils.getLoginUserAccount();return usersConnectionRepository().createConnectionRepository(user.getUsername());}/*** A proxy to a request-scoped object representing the current user's primary Google account.* * @throws NotConnectedException*             if the user is not connected to Google.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public Google google() {Connection<Google> google = connectionRepository().findPrimaryConnection(Google.class);return google != null ? google.getApi() : new GoogleTemplate();}@Bean@Scope(value='request', proxyMode=ScopedProxyMode.INTERFACES)   public Facebook facebook() {Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class);return facebook != null ? facebook.getApi() : new FacebookTemplate();}@Bean@Scope(value='request', proxyMode=ScopedProxyMode.INTERFACES)   public Twitter twitter() {Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class);return twitter != null ? twitter.getApi() : new TwitterTemplate();}@Beanpublic ConnectionSignUp autoConnectionSignUp() {return new AutoConnectionSignUp(accountService);}@Beanpublic SocialAuthenticationFilter socialAuthenticationFilter() {SocialAuthenticationFilter filter = new SocialAuthenticationFilter(authenticationManager, accountService,usersConnectionRepository(), socialAuthenticationServiceLocator());filter.setFilterProcessesUrl('/signin');filter.setSignupUrl(null); filter.setConnectionAddedRedirectUrl('/myAccount');filter.setPostLoginUrl('/myAccount');return filter;}@Beanpublic SocialAuthenticationProvider socialAuthenticationProvider(){return new SocialAuthenticationProvider(usersConnectionRepository(), accountService);}@Beanpublic LoginUrlAuthenticationEntryPoint socialAuthenticationEntryPoint(){return new LoginUrlAuthenticationEntryPoint('/signin');}}

accountService是我自己的用户帐户服务,提供与帐户相关的功能,它实现了SocialUserDetailsServiceUserDetailsServiceUserIdExtractor

还有很多地方需要改进,例如重构MongoConnectionRepositoryMongoUsersConnectionRepository以使用Spring Data Repository接口来实现抽象的社交连接存储库实现。 而且我发现有人已经对此提出了一个问题: 为UsersConnectionRepository利用Spring数据 。

参考:来自我们的JCG合作伙伴 Yuan Ji在Jiwhiz博客上为MongoDB定制Spring Social Connect Framework 。

翻译自: https://www.javacodegeeks.com/2013/03/customize-spring-social-connect-framework-for-mongodb.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法题:输入aaaabbbcccccc输出a4b3c6。

今日在地铁上浏览今日头条的时候看到这么个小题目&#xff0c;说是输出一长串字符串&#xff0c;输出字母串类别并且统计其出现次数&#xff0c;然后按照顺序将其输出来。例如输入aaaabbbcccccc&#xff0c;输出a4b3c6。 最近也一直在学习&#xff0c;所以就想着就Matlab来试了…

Java World中的GraphQL简介

许多人认为GraphQL仅适用于前端和JavaScript&#xff0c;它在Java等后端技术中没有定位&#xff0c;但事实确实如此。 还经常将GraphQL与REST进行比较&#xff0c;但是这种比较是否合理&#xff1f; 首先&#xff0c;让我开始回答其中最重要的问题。 什么是GraphQL&#xff1…

算法题:在一个字符串中找到只出现一次的字符。如输入abaccdeeff,则输出bd。

今天的算法学习还是和字符串有关&#xff0c;这个题目据说是以前的某公司面试的笔试题目。题目意思就是说&#xff0c;在一个字符串中找到只出现了一次的那些字符&#xff0c;并且输出来。 作为非IT的我&#xff0c;平时使用Matlab比较多。不是科班出身&#xff0c;对于这个题…

Kafka的Spring Cloud Stream

总览 该示例项目演示了如何使用事件驱动的体系结构 &#xff0c; Spring Boot &#xff0c;Spring Cloud Stream&#xff0c; Apache Kafka和Lombok构建实时流应用程序。 在本教程结束时&#xff0c;您将运行一个简单的基于Spring Boot的Greetings微服务 从REST API获取消息 …

使用JShell的Java 9 Streams API

这篇文章着眼于使用JShell的Java 9 Streams API。 Streams API的更改以Java 8中Streams的成功为基础&#xff0c;并引入了许多实用程序方法– takeWhile&#xff0c;dropWhile和iterate。 这篇文章延续了My Top Java 9功能&#xff0c;并使用Jshell探索了这些方法。 流API Str…

常见的股票技术因子学习以及计算

最近在看《量化投资数据挖掘技术与实践&#xff08;MATLAB版&#xff09;》。学习了其中的常见的股票衍生变量&#xff0c;并且利用WIND金融数据终端的matlab借口windmatlab导出一些数据进行了一个简单的学习。特此记录。 下面是我对于书中提到的几个因子的学习总结&#xff1…

算法题:输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串“12345”,则输出整数“12345”

今天这道算法题比较简单&#xff0c;主要考察的思考问题的全面性。这个需要考虑的几种情况。 如果输入的整数字符串是个负数&#xff0c;怎么处理&#xff1f; 如果输入的第一个字符是0&#xff0c;则怎么处理&#xff1f; 如果输入的是非0~9之间的字符怎么处理&#xff1f;…

排序算法一:冒泡排序,插入排序以及选择排序原理与MATLAB实现

最近在学习排序算法的一些知识。还是比较有趣的。所以好好研究了一下各个算法。并且使用matlab进行了个基本的实现&#xff0c;目前仅仅是实现吧&#xff0c;优化什么的可能目前的水平达不到吧&#xff0c;毕竟是用matlab实现&#xff0c;还是比较简单。以后还是希望使用C/C&am…

Java – HashMap详细说明

HashMap基于哈希算法工作&#xff0c;根据Java文档HashMap具有以下四个构造函数&#xff0c; 建设者 描述 HashMap ​() 构造一个空的 具有默认初始容量&#xff08;16&#xff09;和默认加载因子&#xff08;0.75&#xff09;的HashMap 。 HashMap ​(int initialCapaci…

Python实现石头-剪刀-布小游戏

近日在学习Python的一些基础知识&#xff0c;觉得还是很有趣的一个一门语言&#xff01;就目前的学习的一些知识&#xff0c;编写了一些一个简单的石头剪刀布的游戏。主要是熟悉一些Python的一些控制语句。 import random while 1:sint(random.randint(1,3))print(s)print()if…

Python:递归输出斐波那契数列

今天学习Python的时候做一道练习题&#xff0c;题目是这样的&#xff1a; 题目 导入 问题 有一对兔子&#xff0c;从出生后第3个月起每个月都生一对兔子&#xff0c;小兔子长到第三个月后每个月又生一对兔子&#xff0c;假如兔子都不死&#xff0c;问每个月的兔子总对数为多…

Spring Webflux –编写过滤器

Spring Webflux是Spring 5的一部分提供的新的响应式Web框架。 在传统的基于Spring MVC的应用程序&#xff08; Servlet Filter &#xff0c; HandlerInterceptor &#xff09;中编写过滤器的方式与在基于Spring Webflux的应用程序中编写过滤器的方式非常不同&#xff0c;本文将…

排序算法二:快速排序算法原理以及MATLAB与Python实现

今天继续学习排序算法。今天的主角是快速排序算法。 1. 快速排序基本原理 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略&#xff0c;通常称其为分治法(Divide-and-ConquerMethod)。 该方法的基本思想是&#xff1a; 1&#xff0e;先从数列…

排序算法三:堆排序基本原理以及Python实现

1. 基本原理 堆排序就是利用堆的特性进行一个无序序列的排序工作。 堆的特点 堆分为最大堆和最小堆&#xff0c;其实就是完全二叉树。 最大堆要求节点的元素都要不小于其孩子最小堆要求节点元素都不大于其左右孩子。 两者对左右孩子的大小关系不做任何要求&#xff0c;其实…

spring jms 消息_Spring JMS,消息自动转换,JMS模板

spring jms 消息在我的一个项目中&#xff0c;我应该创建一个消息路由器&#xff0c;就像所有路由器一样&#xff0c;它应该从一个主题获取JMS消息并将其放入另一个主题。 该消息本身是JMS文本消息&#xff0c;实际上包含XML消息。 收到消息后&#xff0c;我还应该添加一些其他…

排序算法四:归并排序基本原理以及Python实现

1. 基本原理 归并排序建立在归并操作上的一种算法。该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。归并排序是将两 个已经有序的序列合成一个有序的序列的过程。 因此&#xff0c;对于一个待排序的序列来说&#xff0c;首先要将其进行…

如何将JAR添加到Jetbrains MPS项目

Jetbrains MPS是创建DSL的绝佳工具。 我们喜欢它&#xff0c;并在我们的咨询工作中定期使用它。 因此&#xff0c;我们之前已经写过关于Jetbrains MPS的文章 。 作为投影编辑器&#xff0c;您可以轻松创建可通过图形界面或数学公式之类使用的DSL。 尽管所有这些功能都需要做一…

Python 3实现k-邻近算法以及 iris 数据集分类应用

前言 这个周基本在琢磨这个算法以及自己利用Python3 实现自主编程实现该算法。持续时间比较长&#xff0c;主要是Pyhton可能还不是很熟练&#xff0c;走了很多路&#xff0c;基本是一边写一边学。不过&#xff0c;总算是基本搞出来了。不多说&#xff0c;进入正题。 1. K-邻近…

spring mvc 异步_DeferredResult – Spring MVC中的异步处理

spring mvc 异步DeferredResult是一个可能尚未完成的计算的容器&#xff0c;它将在将来提供。 Spring MVC使用它来表示异步计算&#xff0c;并利用Servlet 3.0 AsyncContext异步请求处理。 简要介绍一下它是如何工作的&#xff1a; RequestMapping("/") ResponseBod…

切换表达式到Java吗?

已创建一个标题为“ Java语言的开关表达式”的JEP草案 。 当前的“摘要”状态为&#xff1a;“扩展switch语句&#xff0c;以便可以将其用作语句或表达式&#xff0c;并改善switch处理null的方式。 这些将简化日常编码&#xff0c;并为在switch使用模式匹配做好准备。” 除了启…