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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM