• Spring Mobile是如何判断访问设备的类型的


    Spring最近换域名了,去转转,发现了一个有意思的项目:spring mobile。

    http://projects.spring.io/spring-mobile/

    这个项目有很多实用的功能,如识别访问我们网站的设备是什么类型的(手机,平板,PC),据域名或者url来切换不同访问内容,据不同的访问设备转到不同的view中。


    识别访问设备类型的核心代码在org.springframework.mobile.device.LiteDeviceResolver 类中,这个类实际上根据http请求头部的User-Agent的内容来判断设备到底是哪种类型的。

    可以看到,这个类实际上是很简单的。不过字符串的匹配算法可能可以优化下。

    [java] view plaincopy
    1. public class LiteDeviceResolver implements DeviceResolver {  
    2.   
    3.     private final List<String> mobileUserAgentPrefixes = new ArrayList<String>();  
    4.   
    5.     private final List<String> mobileUserAgentKeywords = new ArrayList<String>();  
    6.   
    7.     private final List<String> tabletUserAgentKeywords = new ArrayList<String>();  
    8.   
    9.     private final List<String> normalUserAgentKeywords = new ArrayList<String>();  
    10.   
    11.     public LiteDeviceResolver() {  
    12.         init();  
    13.     }  
    14.   
    15.     public LiteDeviceResolver(List<String> normalUserAgentKeywords) {  
    16.         init();  
    17.         this.normalUserAgentKeywords.addAll(normalUserAgentKeywords);  
    18.     }  
    19.   
    20.     public Device resolveDevice(HttpServletRequest request) {  
    21.         String userAgent = request.getHeader("User-Agent");  
    22.         // UserAgent keyword detection of Normal devices  
    23.         if (userAgent != null) {  
    24.             userAgent = userAgent.toLowerCase();  
    25.             for (String keyword : normalUserAgentKeywords) {  
    26.                 if (userAgent.contains(keyword)) {  
    27.                     return resolveFallback(request);  
    28.                 }  
    29.             }  
    30.         }  
    31.         // UAProf detection  
    32.         if (request.getHeader("x-wap-profile") != null || request.getHeader("Profile") != null) {  
    33.             return LiteDevice.MOBILE_INSTANCE;  
    34.         }  
    35.         // User-Agent prefix detection  
    36.         if (userAgent != null && userAgent.length() >= 4) {  
    37.             String prefix = userAgent.substring(04).toLowerCase();  
    38.             if (mobileUserAgentPrefixes.contains(prefix)) {  
    39.                 return LiteDevice.MOBILE_INSTANCE;  
    40.             }  
    41.         }  
    42.         // Accept-header based detection  
    43.         String accept = request.getHeader("Accept");  
    44.         if (accept != null && accept.contains("wap")) {  
    45.             return LiteDevice.MOBILE_INSTANCE;  
    46.         }  
    47.         // UserAgent keyword detection for Mobile and Tablet devices  
    48.         if (userAgent != null) {  
    49.             userAgent = userAgent.toLowerCase();  
    50.             // Android special case   
    51.             if (userAgent.contains("android") && !userAgent.contains("mobile")) {  
    52.                 return LiteDevice.TABLET_INSTANCE;  
    53.             }  
    54.             // Kindle Fire special case   
    55.             if (userAgent.contains("silk") && !userAgent.contains("mobile")) {  
    56.                 return LiteDevice.TABLET_INSTANCE;  
    57.             }  
    58.             for (String keyword : tabletUserAgentKeywords) {  
    59.                 if (userAgent.contains(keyword)) {  
    60.                     return LiteDevice.TABLET_INSTANCE;  
    61.                 }  
    62.             }  
    63.             for (String keyword : mobileUserAgentKeywords) {  
    64.                 if (userAgent.contains(keyword)) {  
    65.                     return LiteDevice.MOBILE_INSTANCE;  
    66.                 }  
    67.             }  
    68.         }  
    69.         // OperaMini special case  
    70.         @SuppressWarnings("rawtypes")  
    71.         Enumeration headers = request.getHeaderNames();  
    72.         while (headers.hasMoreElements()) {  
    73.             String header = (String) headers.nextElement();  
    74.             if (header.contains("OperaMini")) {  
    75.                 return LiteDevice.MOBILE_INSTANCE;  
    76.             }  
    77.         }  
    78.         return resolveFallback(request);  
    79.     }  
    80.   
    81.     // subclassing hooks  
    82.   
    83.     /** 
    84.      * List of user agent prefixes that identify mobile devices. 
    85.      * Used primarily to match by operator or handset manufacturer. 
    86.      */  
    87.     protected List<String> getMobileUserAgentPrefixes() {  
    88.         return mobileUserAgentPrefixes;  
    89.     }  
    90.   
    91.     /** 
    92.      * List of user agent keywords that identify mobile devices. 
    93.      * Used primarily to match by mobile platform or operating system. 
    94.      */  
    95.     protected List<String> getMobileUserAgentKeywords() {  
    96.         return mobileUserAgentKeywords;  
    97.     }  
    98.   
    99.     /** 
    100.      * List of user agent keywords that identify tablet devices. 
    101.      * Used primarily to match by tablet platform or operating system. 
    102.      */  
    103.     protected List<String> getTabletUserAgentKeywords() {  
    104.         return tabletUserAgentKeywords;  
    105.     }  
    106.   
    107.     /** 
    108.      * List of user agent keywords that identify normal devices. 
    109.      * Any items in this list take precedence over the mobile and 
    110.      * tablet user agent keywords, effectively overriding those.  
    111.      */  
    112.     protected List<String> getNormalUserAgentKeywords() {  
    113.         return normalUserAgentKeywords;  
    114.     }  
    115.   
    116.     /** 
    117.      * Initialize this device resolver implementation. 
    118.      * Registers the known set of device signature strings. 
    119.      * Subclasses may override to register additional strings. 
    120.      */  
    121.     protected void init() {  
    122.         getMobileUserAgentPrefixes().addAll(Arrays.asList(KNOWN_MOBILE_USER_AGENT_PREFIXES));  
    123.         getMobileUserAgentKeywords().addAll(Arrays.asList(KNOWN_MOBILE_USER_AGENT_KEYWORDS));  
    124.         getTabletUserAgentKeywords().addAll(Arrays.asList(KNOWN_TABLET_USER_AGENT_KEYWORDS));  
    125.     }  
    126.   
    127.     /** 
    128.      * Fallback called if no mobile device is matched by this resolver. 
    129.      * The default implementation of this method returns a "normal" {@link Device} that is neither mobile or a tablet. 
    130.      * Subclasses may override to try additional mobile or tablet device matching before falling back to a "normal" device. 
    131.      */  
    132.     protected Device resolveFallback(HttpServletRequest request) {  
    133.         return LiteDevice.NORMAL_INSTANCE;  
    134.     }  
    135.   
    136.     // internal helpers  
    137.   
    138.     private static final String[] KNOWN_MOBILE_USER_AGENT_PREFIXES = new String[] { "w3c ""w3c-""acs-""alav",  
    139.             "alca""amoi""audi""avan""benq""bird""blac""blaz""brew""cell""cldc""cmd-""dang",  
    140.             "doco""eric""hipt""htc_""inno""ipaq""ipod""jigs""kddi""keji""leno""lg-c""lg-d",  
    141.             "lg-g""lge-""lg/u""maui""maxo""midp""mits""mmef""mobi""mot-""moto""mwbp""nec-",  
    142.             "newt""noki""palm""pana""pant""phil""play""port""prox""qwap""sage""sams""sany",  
    143.             "sch-""sec-""send""seri""sgh-""shar""sie-""siem""smal""smar""sony""sph-""symb",  
    144.             "t-mo""teli""tim-""tosh""tsm-""upg1""upsi""vk-v""voda""wap-""wapa""wapi""wapp",  
    145.             "wapr""webc""winw""winw""xda ""xda-" };  
    146.   
    147.     private static final String[] KNOWN_MOBILE_USER_AGENT_KEYWORDS = new String[] { "blackberry""webos""ipod",  
    148.             "lge vx""midp""maemo""mmp""mobile""netfront""hiptop""nintendo DS""novarra""openweb",  
    149.             "opera mobi""opera mini""palm""psp""phone""smartphone""symbian""up.browser""up.link",  
    150.             "wap""windows ce" };  
    151.   
    152.     private static final String[] KNOWN_TABLET_USER_AGENT_KEYWORDS = new String[] { "ipad""playbook""hp-tablet",  
    153.             "kindle" };  
    154.   
    155. }  


  • 相关阅读:
    中国大概可用NTPserver地址
    ROOT android 原则。 基于(zergRush)
    Struts2他们拦截器实例定义—登陆权限验证
    引用与指针
    address_space 从哪里来
    C++ 可以多个函数声明
    linux下远程管理利器-tmux
    内核空间和用户空间的分界 PAGE_OFFSET
    io端口
    C中程序的内存分配
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/5696476.html
Copyright © 2020-2023  润新知