关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » HTML5 »单点登录与消息队列以及在J2EE中的实现方案

    单点登录与消息队列以及在J2EE中的实现方案

    2015-09-18 00:00:00 出处:Yonah-潇
    分享

    前言

    很久都没有写博客了,这次为大家简单介绍两个在WEB开发中经常使用的概念——单点登录和消息队列以及具体到J2EE中的一些实现方案。本文原创性的工作比较少,主要是一些总结概括和自己的理解。

    单点登录SSO

    SSO的业务场景

    所谓单点登录就是在一个站点登录之后可以授信给其他站点,这样就可以做到一次登录,到处操作。单点登录的实质就是安全上下文(Security Context)或凭证(Credential)在多个应用系统之间的传递或共享。

    大部分的网站采用Cookie作为登录的一种简单实现方案,在同一个一级域名下面,这样做并无问题,不需要对各个子系统分别验证。但是Cookie无法跨域传递。将用户的登录、凭证取得等解耦处理单独作为一个子系统是合理的选择。

    SSO的核心要素

    共享同一个身份认证系统,也就是说所有站点的身份验证操作在同一个系统下完成 每个子系统从共同的身份认证系统中取得用户凭证,包含用户的身份、权限信息等

    示意图如下:

    SSO结构示意图

    SSO的一种简单实现方案

    下面以采用Cookie的一种方案为例来解释:

    我们首先定义授信服务器A,受信服务器B,客户C;当前的业务是B需要验证C的身份。需要注意的是B和C都会保有session来记录C的登录状态,均会向C 的Header中写入对应自己域名的Cookie以存储凭证信息。Cookie中含有tokenId来标示C,也就是说对于A和B他们的Cookie中对应于同一个C,其tokenId应该一致。

    C向B发起请求后,会有以下几种情形:

    B含有session,C含有Cookie,且session和Cookie中的token一致,那么不需要向A求助 C中对于B无Cookie或Cookie过期或session与Cookie不一致,将向A发起请求。之后根据A的情形,有以下情况: A中session与C中Cookie的token一致,重新生成凭证信息返回给B,B重新写入Cookie与session A中Cookie过期或信息不一致,将重定向到登录页面 对于登录情形,A将更新Cookie与session,然后C再向B发起请求,这时就会变成2中第一种情况,导致A和B的信息完成同步。

    消息队列

    MQ的业务场景

    消息队列本身是简单的,可以直接看做一个队列,重点是如何定义存储在队列中的数据格式,以满足我们对应的操作需求。MQ常常应用于那些并发量大而对于实时性要求不高的情况。举个例子,比如一个用户量较大的社交网站的评论发布,为什么这么说呢?对于这个任务,队列中只用存储评论相关信息,对于从队列中取的一方,只需要进行插入操作,符合前面所说的并发量大且可以有延时,同时并不难实现。

    MQ的两种模式

    消息队列在WEB开发中主要有两种模式:

    生产者/消费者模式:对于一则消息,只有一个消费者线程会去处理它,适用于我们上面所说的评论系统 发布者/订阅者模式:对于所有订阅者,它可以读取所有在它加入之后发布的消息

    在J2EE中加入消息队列,我个人认为应该是这样的:对于特定的HTTP请求,调用生产者/发布者的接口,入队必要消息,这个并不困难。大有蹊跷的我觉得在于处理消息的一方,可以实现listener将其交由容器管理,也可以自己开辟池来调度。举例来说明,对于前者Spring-redis实现的pub/sub模式队列就是直接在配置文件中设定RedisListener的实现类,对于后者,你可以直接独立出来写离线脚本来监听队列。

    MQ的实现方案

    目前业界有比较成熟的MQ解决产品,如下:

    RabbitMQ ActiveMQ kafka Redis

    MQ的Spring+Redis实现简单示例

    在Pom.xml中加入以下依赖

    <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.4.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.6.2</version>
        </dependency>

    在ApplicationContext.xml的头部插入schema

    xmlns:redis="http://www.springframework.org/schema/redis"

    在ApplicationContext中加入Redis的配置

    <!-- 配置redis池,依次为最大实例数,最大空闲实例数,(创建实例时)最大等待时间,(创建实例时)是否验证 -->
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="${redis.maxTotal}"/>
            <property name="maxIdle" value="${redis.maxIdle}"/>
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
            <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        </bean>
    
        <!-- 配置数据源-->
        <bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <property name="hostName" value="127.0.0.1"></property>
            <property name="port" value="6379"></property>
            <property name="usePool" value="true"></property>
        </bean>    
    
        <!-- 配置数据操作 -->
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
            <property name="connectionFactory" ref="redisConnectionFactory"></property>
        </bean>        
        <bean id="jdkSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
    
        <bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
            <property name="delegate" ref="messageDelegateListener" /> <!--这里的messageDelegateListener在后面的文件中注解的,这里对应的具体消息处理类的实现-->
            <property name="serializer" ref="jdkSerializer" />
        </bean>     
    
        <!-- 将消息handler注册 -->
        <redis:listener-container>
            <redis:listener ref="messageListener" method="handleMessage" serializer="jdkSerializer" topic="java"/>
        </redis:listener-container>

    上文在定义Listener的时候采用了注解对象作为实现类,也可以手动在配置文件中再写一个bean,如下

    <bean id="messageDelegateListener" class="***.***.***" />

    最后我们给出一个接收方的实现

    import java.io.Serializable;
    
    import org.springframework.stereotype.Component;
    
    @Component(value="messageDelegateListener")
    public class ListenMessage {
        public void handleMessage(Serializable message){
            System.out.println(message);
        }
    }
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。