Spring Mobile是如何判断访问设备的类型的
Spring最近换域名了,去转转,发现了一个有意思的项目:spring mobile。
http://projects.spring.io/spring-mobile/
这个项目有很多实用的功能,如识别访问我们网站的设备是什么类型的(手机,平板,PC),据域名或者url来切换不同访问内容,据不同的访问设备转到不同的view中。
识别访问设备类型的核心代码在org.springframework.mobile.device.LiteDeviceResolver 类中,这个类实际上根据http请求头部的User-Agent的内容来判断设备到底是哪种类型的。
可以看到,这个类实际上是很简单的。不过字符串的匹配算法可能可以优化下。
- public class LiteDeviceResolver implements DeviceResolver {
- private final List<String> mobileUserAgentPrefixes = new ArrayList<String>();
- private final List<String> mobileUserAgentKeywords = new ArrayList<String>();
- private final List<String> tabletUserAgentKeywords = new ArrayList<String>();
- private final List<String> normalUserAgentKeywords = new ArrayList<String>();
- public LiteDeviceResolver() {
- init();
- }
- public LiteDeviceResolver(List<String> normalUserAgentKeywords) {
- init();
- this.normalUserAgentKeywords.addAll(normalUserAgentKeywords);
- }
- public Device resolveDevice(HttpServletRequest request) {
- String userAgent = request.getHeader("User-Agent");
- // UserAgent keyword detection of Normal devices
- if (userAgent != null) {
- userAgent = userAgent.toLowerCase();
- for (String keyword : normalUserAgentKeywords) {
- if (userAgent.contains(keyword)) {
- return resolveFallback(request);
- }
- }
- }
- // UAProf detection
- if (request.getHeader("x-wap-profile") != null || request.getHeader("Profile") != null) {
- return LiteDevice.MOBILE_INSTANCE;
- }
- // User-Agent prefix detection
- if (userAgent != null && userAgent.length() >= 4) {
- String prefix = userAgent.substring(0, 4).toLowerCase();
- if (mobileUserAgentPrefixes.contains(prefix)) {
- return LiteDevice.MOBILE_INSTANCE;
- }
- }
- // Accept-header based detection
- String accept = request.getHeader("Accept");
- if (accept != null && accept.contains("wap")) {
- return LiteDevice.MOBILE_INSTANCE;
- }
- // UserAgent keyword detection for Mobile and Tablet devices
- if (userAgent != null) {
- userAgent = userAgent.toLowerCase();
- // Android special case
- if (userAgent.contains("android") && !userAgent.contains("mobile")) {
- return LiteDevice.TABLET_INSTANCE;
- }
- // Kindle Fire special case
- if (userAgent.contains("silk") && !userAgent.contains("mobile")) {
- return LiteDevice.TABLET_INSTANCE;
- }
- for (String keyword : tabletUserAgentKeywords) {
- if (userAgent.contains(keyword)) {
- return LiteDevice.TABLET_INSTANCE;
- }
- }
- for (String keyword : mobileUserAgentKeywords) {
- if (userAgent.contains(keyword)) {
- return LiteDevice.MOBILE_INSTANCE;
- }
- }
- }
- // OperaMini special case
- @SuppressWarnings("rawtypes")
- Enumeration headers = request.getHeaderNames();
- while (headers.hasMoreElements()) {
- String header = (String) headers.nextElement();
- if (header.contains("OperaMini")) {
- return LiteDevice.MOBILE_INSTANCE;
- }
- }
- return resolveFallback(request);
- }
- // subclassing hooks
- /**
- * List of user agent prefixes that identify mobile devices.
- * Used primarily to match by operator or handset manufacturer.
- */
- protected List<String> getMobileUserAgentPrefixes() {
- return mobileUserAgentPrefixes;
- }
- /**
- * List of user agent keywords that identify mobile devices.
- * Used primarily to match by mobile platform or operating system.
- */
- protected List<String> getMobileUserAgentKeywords() {
- return mobileUserAgentKeywords;
- }
- /**
- * List of user agent keywords that identify tablet devices.
- * Used primarily to match by tablet platform or operating system.
- */
- protected List<String> getTabletUserAgentKeywords() {
- return tabletUserAgentKeywords;
- }
- /**
- * List of user agent keywords that identify normal devices.
- * Any items in this list take precedence over the mobile and
- * tablet user agent keywords, effectively overriding those.
- */
- protected List<String> getNormalUserAgentKeywords() {
- return normalUserAgentKeywords;
- }
- /**
- * Initialize this device resolver implementation.
- * Registers the known set of device signature strings.
- * Subclasses may override to register additional strings.
- */
- protected void init() {
- getMobileUserAgentPrefixes().addAll(Arrays.asList(KNOWN_MOBILE_USER_AGENT_PREFIXES));
- getMobileUserAgentKeywords().addAll(Arrays.asList(KNOWN_MOBILE_USER_AGENT_KEYWORDS));
- getTabletUserAgentKeywords().addAll(Arrays.asList(KNOWN_TABLET_USER_AGENT_KEYWORDS));
- }
- /**
- * Fallback called if no mobile device is matched by this resolver.
- * The default implementation of this method returns a "normal" {@link Device} that is neither mobile or a tablet.
- * Subclasses may override to try additional mobile or tablet device matching before falling back to a "normal" device.
- */
- protected Device resolveFallback(HttpServletRequest request) {
- return LiteDevice.NORMAL_INSTANCE;
- }
- // internal helpers
- private static final String[] KNOWN_MOBILE_USER_AGENT_PREFIXES = new String[] { "w3c ", "w3c-", "acs-", "alav",
- "alca", "amoi", "audi", "avan", "benq", "bird", "blac", "blaz", "brew", "cell", "cldc", "cmd-", "dang",
- "doco", "eric", "hipt", "htc_", "inno", "ipaq", "ipod", "jigs", "kddi", "keji", "leno", "lg-c", "lg-d",
- "lg-g", "lge-", "lg/u", "maui", "maxo", "midp", "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-",
- "newt", "noki", "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage", "sams", "sany",
- "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem", "smal", "smar", "sony", "sph-", "symb",
- "t-mo", "teli", "tim-", "tosh", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi", "wapp",
- "wapr", "webc", "winw", "winw", "xda ", "xda-" };
- private static final String[] KNOWN_MOBILE_USER_AGENT_KEYWORDS = new String[] { "blackberry", "webos", "ipod",
- "lge vx", "midp", "maemo", "mmp", "mobile", "netfront", "hiptop", "nintendo DS", "novarra", "openweb",
- "opera mobi", "opera mini", "palm", "psp", "phone", "smartphone", "symbian", "up.browser", "up.link",
- "wap", "windows ce" };
- private static final String[] KNOWN_TABLET_USER_AGENT_KEYWORDS = new String[] { "ipad", "playbook", "hp-tablet",
- "kindle" };
- }
Spring Mobile是如何判断访问设备的类型的的更多相关文章
- Java判断访问设备为手机、微信、PC工具类
package com.lwj.util; import javax.servlet.http.HttpServletRequest; /** * 判断访问设备为PC或者手机--工具类 * * @de ...
- JS判断访问设备、客户端操作系统类型
先给出一个实例:判断windows.linux.android 复制以下代码另存为html文件即可. <html> <head> <title>判断操作系统< ...
- [转]JS判断访问设备、客户端操作系统类型
本文转自:http://www.cnblogs.com/duanguyuan/p/3534470.html 先给出一个实例:判断windows.linux.android 复制以下代码另存为html文 ...
- JS判断访问设备(userAgent)加载不同页面 JS判断客户端操作系统类型(platform)
//平台.设备和操作系统 var system ={ win : false, mac : false, xll : false }; //检测平台 var p = navigator.platfor ...
- PHP和js判断访问设备是否是微信浏览器实例
PHP和js判断访问设备是否是微信浏览器实例,代码非常精简,适合新手学习. js判断是否是微信浏览器: 1 function is_weixin() { 2 var ua = window.navig ...
- 判断访问浏览器客户端类型(pc,mac,ipad,iphone,android)
<script type="text/javascript"> //平台.设备和操作系统 var system = { win: false, mac: false, ...
- JS判断访问设备是移动设备还是pc
<scripttype="text/javascript"> function browserRedirect() { var sUserAgent= navigato ...
- 如何判断 ios设备的类型(iphone,ipod,ipad)
功能函数: -(bool)checkDevice:(NSString*)name { NSString* deviceType = [UIDevice currentDevice].model; NS ...
- Spring Mobile——探测客户端设备和系统
Spring Mobile--探测客户端设备和系统 今天闲来无事,浏览Spring的官方网站,发现了Spring Mobile项目,之前也看到过,还以为是针对手机端的项目,并没有细看.今天仔细看了一下 ...
随机推荐
- caffe神经网络框架的辅助工具(将图片转换为leveldb格式)
caffe中负责整个网络输入的datalayer是从leveldb里读取数据的,是一个google实现的很高效的kv数据库. 因此我们训练网络必须先把数据转成leveldb的格式. 这里我实现的是把一 ...
- android Graphics(二):路径及文字
前言:今天项目进入攻关期,他们改Bug要改疯掉了,主管为了激励大家,给大家发了一封邮件,讲到他对项目和学习的理解,一个很好的图形模型,分享给大家,如图在下面给出:(不便给出原文,我仅做转述)无论是学习 ...
- UVA 1619 Feel Good(DP)
Bill is developing a new mathematical theory for human emotions. His recent investigations are dedic ...
- iOS MBProgressHUD 之带底板的加载提示
文章来自:http://blog.csdn.net/ryantang03/article/details/7877120 MBProgressHUD是一个开源项目,实现了很多种样式的提示框,使用上简单 ...
- unity学习中经常要碰到的几种数据结构
常碰到的几种数据结构:1.Array,2.ArrayList,3.List<T>,4.LinkedList<T>,5.Queue<T>,6.Stack<T&g ...
- Altera FPGA中的pin简介
第一步要看的肯定是pin planner ,这个是黑金四代EP4CE15F17C8的视图 先就是发现他们pin有不同的颜色区域,分别对应不同的bank,应该是有的设计里面要求pin在同一个bank吧( ...
- docker学习笔记14:Dockerfile 指令 ENV介绍
ENV指令用来在镜像构建过程中设置环境变量.我们来看一个Dockerfile的例子: #test FROM ubuntu MAINTAINER hello ENV MYDIR /mydir RUN m ...
- SilkTest天龙八部系列7-动态对象识别
在测试web应用时,我们常常需要面对web页面对象变化频繁,并且使用预定义方式识别对象慢的困难.为了解决这些问题,SilkTest引入了dynamic object recognition技术,它使用 ...
- swift 关于 toolbar 学习笔记
import UIKit class ViewController: UIViewController { @IBOutlet weak var toolBar: UIToolbar! @IBOutl ...
- Linux之shell编程基础
一.变量 变量在shell中分为:本地变量.环境变量.位置参数: 本地变量:仅可在用户当前shell生命期的脚本中使用的变量,本地变量随着shell进程的消亡而无效,本地变量在新启动的shell中依旧 ...