CAS 界面根据不同的域名显示不同的界面
概要
在实际需求中,客户想通过不同的域名显示不同的登录界面,比如输入 manage.aps.cn 显示运维管理登录,business.aps.cn 显示业务管理登录。
实现方法
1.准备两套登录UI
在cas目录 WEB-INF/view/jsp目录下整两份UI。

增加两个属性文件,这些属性文件和UI有关系。

查看一下 business.properties

cas 默认显示界面是在cas.properties 文件中配置,配置完成后,不能再变更了,因此需要能够实现切换UI。

2.代码实现
我的思路是通过根据域名动态改变 这个basename。在过滤器中获取域名,并动态改变basename。
实现方式在过滤器中,判断当前的访问域名,判定需要访问哪个UI并进行切换。
修改源码:
org.springframework.web.servlet.view.ResourceBundleViewResolver,
这个代码原本是不能实现UI切换的。
package org.springframework.web.servlet.view; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.View; public class ResourceBundleViewResolver extends AbstractCachingViewResolver
implements Ordered, InitializingBean, DisposableBean
{
public static final String DEFAULT_BASENAME = "views";
private int order = 2147483647; private ThreadLocal<String> baseNameLocal= new ThreadLocal<>(); private ClassLoader bundleClassLoader = Thread.currentThread().getContextClassLoader();
private String defaultParentView;
private Locale[] localesToInitialize;
private final Map<Locale, BeanFactory> localeCache = new HashMap(); private final Map<List<ResourceBundle>, ConfigurableApplicationContext> bundleCache = new HashMap(); public void setOrder(int order)
{
this.order = order; } public int getOrder() {
return this.order;
} public void setBasename(String basename)
{
this.baseNameLocal.set(basename);
} public void setBundleClassLoader(ClassLoader classLoader)
{
this.bundleClassLoader = classLoader;
} protected ClassLoader getBundleClassLoader()
{
return this.bundleClassLoader;
} public void setDefaultParentView(String defaultParentView)
{
this.defaultParentView = defaultParentView;
} public void setLocalesToInitialize(Locale[] localesToInitialize)
{
this.localesToInitialize = localesToInitialize;
} public void afterPropertiesSet()
throws BeansException
{
if (this.localesToInitialize != null)
for (Locale locale : this.localesToInitialize)
initFactory(locale);
} protected View loadView(String viewName, Locale locale)
throws Exception
{
BeanFactory factory = initFactory(locale);
try {
return (View)factory.getBean(viewName, View.class);
}
catch (NoSuchBeanDefinitionException ex) {
}
return null;
} protected synchronized BeanFactory initFactory(Locale locale)
throws BeansException
{ List<ResourceBundle> bundles = new LinkedList(); String baseName="manage"; if(this.baseNameLocal.get()!=null){
baseName=this.baseNameLocal.get();
} ResourceBundle bundle = getBundle(baseName, locale);
bundles.add(bundle); GenericWebApplicationContext factory = new GenericWebApplicationContext();
factory.setParent(getApplicationContext());
factory.setServletContext(getServletContext()); PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(factory);
reader.setDefaultParentBean(this.defaultParentView);
reader.registerBeanDefinitions(bundle); factory.refresh(); return factory;
} protected ResourceBundle getBundle(String basename, Locale locale)
throws MissingResourceException
{
return ResourceBundle.getBundle(basename, locale, getBundleClassLoader());
} public void destroy()
throws BeansException
{
for (ConfigurableApplicationContext factory : this.bundleCache.values()) {
factory.close();
}
this.localeCache.clear();
this.bundleCache.clear();
}
}
增加一个过滤器,根据域名修改 页面视图目录。
package com.redxun.cas; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import org.springframework.web.servlet.view.ResourceBundleViewResolver; public class ViewSelectFilter implements Filter{ @Override
public void destroy() { } @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)req;
ResourceBundleViewResolver resolver=(ResourceBundleViewResolver) SpringContextHolder.getBean("viewResolver");
String serverName=request.getServerName();
String pre=serverName.substring(0,serverName.indexOf("."));
resolver.setBasename(pre); chain.doFilter(req, res);
} @Override
public void init(FilterConfig arg0) throws ServletException { } }
修改 cas-servlet.xml配置。
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"
p:order="0">
<property name="basename" value="${cas.viewResolver.basename}" />
<property name="cache" value="false"></property>
</bean>
配置过滤器
<filter>
<filter-name>ViewSelectFilter</filter-name>
<filter-class>com.redxun.cas.ViewSelectFilter</filter-class>
</filter> <filter-mapping>
<filter-name>ViewSelectFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
测试效果
在host添加域名映射
192.168.1.77 manage.aps.cn
192.168.1.77 business.aps.cn
测试效果如下:
访问:manage.aps.cn

business.aps.cn

另外一个知识点,我们在过滤器中需要获取,spring mvc的上下文。
我们需要实现一个获取上下文的类。实现接口:ApplicationContextAware
package com.redxun.cas; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext _ctx; @Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
_ctx=ctx;
}
public static Object getBean(String beanId){
return _ctx.getBean(beanId);
}
public static Object getBean(Class cls){
return _ctx.getBean(cls);
}
}
这里配置也是有要求的需要配置 cas-servlet.xml配置文件中。
配置如下:
<bean id="springContextHolder" class="com.redxun.cas.SpringContextHolder"></bean>
CAS 界面根据不同的域名显示不同的界面的更多相关文章
- OpenStack配置串口显示虚机界面
OpenStack配置串口显示虚机界面 OpenStack的horizon能够显示虚拟机的界面.horizon是web界面,在我们的电脑上,姑且称之为本地,虚拟机运行在远端服务器上,称之为远端.本地显 ...
- 直接拨号、将电话号码传入拨号程序、调用拨号程序、调用系统浏览器浏览网页、调用系统程序查看联系人、显示系统设置界面和显示Wi-Fi设置界面代码
直接拨号.将电话号码传入拨号程序.调用拨号程序.调用系统浏览器浏览网页.调用系统程序查看联系人.显示系统设置界面和显示Wi-Fi设置界面代码 拨打号码的代码如下: Intent callIntent= ...
- wxPython制作跑monkey工具(python3)-带显示设备列表界面
一. wxPython制作跑monkey工具(python3)-带显示设备列表界面 源代码 Run Monkey.py #!/usr/bin/env python import wx import ...
- iOS从当前隐藏导航界面push到下一个显示导航界面出现闪一下的问题
本文转载至 http://blog.csdn.net/woaifen3344/article/details/41284319 navios 如果有朋友遇到从当前隐藏导航界面push到下一个显示导航界 ...
- Android图形显示系统——上层显示1:界面绘制大纲
Android显示之应用界面绘制 越到上层,跟业务关联越直接.代码就越繁杂.Android上层显示的代码正是如此.此外,java语言本身繁复的特点(比C语言多了满屏的try-catch,比C++少了析 ...
- swift项目实战--微博的未登录界面的实现,和监听未登录界面两个按钮的两种实现方法
1.未登录界面的实现 微博项目中,用户不登录的话,显示的是未登录的界面.项目中TabBarVC的子控制器都是tableViewVC,所以抽取了父类,让父类判断用户是否登录,决定显示什么样的界面.loa ...
- WinForm开发-界面控件到实体,实体到界面控件自动绑定
在WinForm开发中,我们是不是为绑定界面控件的数据而每个控件每个控件的赋值?在保存修改时是不是也是每个控件每个控件的赋值到实体中?字段一多,那简直就是噩梦.有没有像Web中那样方便的方法直接就自动 ...
- .NetCore 下开发独立的(RPL)含有界面的组件包 (三)构建界面
.NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...
- 【iOS开发】IOS界面开发使用viewWithTag:(int)findTag方法获取界面元素
http://blog.csdn.net/lxp1021/article/details/43952551 今天在开发OS界面的时候,遇到通过界面UIview viewWithTag:(int)fin ...
随机推荐
- Python词云(词频统计,掩膜显示)
Python2.7 anaconda.安装Wordcloud,网上有许多下载路径,说一下掩模,就是在这个膜的区域才会有东西,当然这个与实际的掩模还有一定区别,这个词频显示是把所有统计的词,显示在这个掩 ...
- 20165315 实验一 Java开发环境的熟悉
# 20165315 实验一 Java开发环境的熟悉 一.实验内容及步骤 (一)使用JDK编译.运行简单的Java程序 macOS命令行下运行Java 打开终端 输入mkdir 20165315exp ...
- Java_7.1 ArrayList应用点名器
1.ArrayList同样可以添加自定义的类 将学生类添加到ArrayList集合中,其中学生类包括学生姓名,年龄 自定义学生类 package demo1; public class Student ...
- GridView(网格视图)+MotionEvent(触控事件)实现可以拖动排序的网格图
1.一触碰,就回调onInterceptTouchEvent(MotionEvent ev)事件,每次的触碰都只回调一次,接着只要还没有放手,就一直回调onTouchEvent(MotionEvent ...
- first H5
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- docker-ce-17.09 容器创建,运行,进入,删除,导入/导出
docker容器是镜像运行的一个运行实例,带有额外的可写文件层. 一.创建容器 > docker create -it centos:latest create命令新建的容器处于停止状态,可以使 ...
- 在windows7中配置ant环境变量
假设本地以及安装好JDK并且配置好环境变量. 新建/修改系统环境变量 ANT_HOME D:\develop\apache-ant-1.10.3 PATH %ANT_HOME%\bin ...
- jQuery 作业三个按钮
作业三个按钮 <!--声明 文档--> <!DOCTYPE html> <!--定义字符集--> <html lang="zh-CN"&g ...
- python 面向对象编程 之 上下文管理协议
with open('path', 'r' ,encoding='utf-8') as f: 代码块 上述就叫做上线文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明 ...
- Fiddler抓包使用教程-安装配置
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72876628 本文出自[赵彦军的博客] Fiddler是什么? Fiddler是一 ...