我们现在做的项目,移动端和PC端网站访问的是同一套接口,那么如何在接口中区分是手机访问还是PC短访问呢?

核心思想:根据请求头(request header)来判断,如何请求没有header或伪造user agent则无法判断.

先看一些user agent的实例:

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) (Engine, like URL) Mobile/12B440 MicroMessenger/6.0.1 NetType/3G+

Mozilla/5.0 (Linux; U; Android 4.1.1; en-cn; HTC T528d) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.2.58_r984381.520 NetType/WIFI

Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.5.489 U3/0.8.0 Mobile Safari/533.1

Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10

Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; HUAWEI G700-U00 Build/HuaweiG700-U00) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 V1_AND_SQ_5.3.1_196_YYB_D QQ/5.3.1.2335 NetType/WIFI

Mozilla/5.0 (Linux; U; Android 4.0.4; zh-cn; HS-EG906 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/5.3.1.67_r745169.462

Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-Manager Mobile Safari/537.36

以下是我封装的一套方法

ClientOsInfo 是用于保存访问设备信息的,结构如下(省略getter,setter):

Java代码  
  1. public class ClientOsInfo {
  2. /***
  3. * 比如 Android_3.0
  4. */
  5. private String osTypeVersion;
  6. /***
  7. * Pad或Phone
  8. */
  9. private String deviceType;
  10. /***
  11. * os type
  12. */
  13. private String osType;
  14. /***
  15. * 只是版本号,例如"4.1.1"
  16. */
  17. private String version;
  18. private String userAgent;
  19. /***
  20. * 是否是移动设备
  21. * @return
  22. */
  23. public boolean isMobile(){
  24. return (!ValueWidget.isNullOrEmpty(this.deviceType));
  25. }
  26. }

核心方法:

Java代码  
  1. /***
  2. * 当移动端(手机或Pad)访问网页时获取移动端操作系统信息
  3. * @param request
  4. * @return
  5. */
  6. public static ClientOsInfo getMobileOsInfo(HttpServletRequest request){
  7. String userAgent=request.getHeader("user-agent");
  8. if(ValueWidget.isNullOrEmpty(userAgent)){
  9. userAgent=request.getHeader("User-Agent");
  10. }
  11. ClientOsInfo info= HeaderUtil.getMobilOS(userAgent);
  12. info.setUserAgent(userAgent);
  13. return info;
  14. }

核心工具类:用于解析user agent

Java代码  
  1. package com.common.util;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. import com.common.bean.ClientOsInfo;
  5. import com.string.widget.util.ValueWidget;
  6. /***
  7. *
  8. * @author huangwei
  9. * @since 2013-08-15
  10. */
  11. public class HeaderUtil {
  12. public static final String OSTYPE_ANDROID="Android";
  13. public static final String OSTYPE_IOS="Ios";
  14. public static final String OSTYPE_WP="WINDOWS PHONE";
  15. public static final String OSTYPE_BLACKBERRY="BLACKBERRY";
  16. /***
  17. * pad
  18. */
  19. public static final String DEVICE_TYPE_PAD="Pad";
  20. /***
  21. * 手机
  22. */
  23. public static final String DEVICE_TYPE_PHONE="Phone";
  24. /***
  25. * 校验渠道终端版本号是否合法,eg:0.0.0.3
  26. *
  27. * @param clientVersion
  28. * @return true-->合法 ;false-->非法
  29. */
  30. public static boolean verifyClientVersion(String clientVersion) {
  31. boolean result = Pattern.matches("[\\d\\.]+", clientVersion);
  32. if (result) {
  33. result = Pattern.matches("^\\d\\.\\d\\.\\d\\.\\d$", clientVersion);
  34. return result;
  35. } else {
  36. return false;
  37. }
  38. }
  39. /**
  40. * 根据useragent和手机厂商查手机型号
  41. *
  42. * @param UA
  43. * @param vendor
  44. * @return
  45. */
  46. public static String getMobModel(String UA, String operatingSystem) {
  47. if (UA == null) {
  48. return null;
  49. }
  50. // 存放正则表达式
  51. String rex = "";
  52. // 苹果产品
  53. if (operatingSystem.indexOf("IOS") != -1) {
  54. if (UA.indexOf("IPAD") != -1) {// 判断是否为ipad
  55. return "IPAD";
  56. }
  57. if (UA.indexOf("IPOD") != -1) {// 判断是否为ipod
  58. return "IPOD";
  59. }
  60. if (UA.indexOf("IPONE") != -1) {// 判断是否为ipone
  61. return "IPONE";
  62. }
  63. return "IOS DEVICE";
  64. }
  65. // 安卓系统产品
  66. if (operatingSystem.indexOf("ANDROID") != -1) {
  67. String re = "BUILD";
  68. rex = ".*" + ";" + "(.*)" + re;
  69. Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);
  70. Matcher m = p.matcher(UA);
  71. boolean rs = m.find();
  72. if (rs) {
  73. System.out.println("Mobil Model is" + m.group(1));
  74. return m.group(1);
  75. }
  76. }
  77. return null;
  78. }
  79. /**
  80. * 判断手机的操作系统 IOS/android/windows phone/BlackBerry
  81. *
  82. * @param UA
  83. * @return
  84. */
  85. public static ClientOsInfo getMobilOS(String UA) {
  86. UA=UA.toUpperCase();
  87. if (UA == null) {
  88. return null;
  89. }
  90. ClientOsInfo osInfo=new  ClientOsInfo();
  91. // 存放正则表达式
  92. String rex = "";
  93. // IOS 判断字符串
  94. String iosString = " LIKE MAC OS X";
  95. if (UA.indexOf(iosString) != -1) {
  96. if(isMatch(UA, "\\([\\s]*iPhone[\\s]*;", Pattern.CASE_INSENSITIVE)){
  97. osInfo.setDeviceType(DEVICE_TYPE_PHONE);
  98. }else if(isMatch(UA, "\\([\\s]*iPad[\\s]*;", Pattern.CASE_INSENSITIVE)){
  99. osInfo.setDeviceType(DEVICE_TYPE_PAD);
  100. }
  101. rex = ".*" + "[\\s]+(\\d[_\\d]*)" + iosString;
  102. Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);
  103. Matcher m = p.matcher(UA);
  104. boolean rs = m.find();
  105. if (rs) {
  106. String osVersion= m.group(1).replace("_", ".");
  107. osInfo.setVersion(osVersion);
  108. //              System.out.println("Mobil OS is" + " IOS" +osVersion);
  109. osInfo.setOsTypeVersion(OSTYPE_IOS+"_" + osVersion);
  110. }else{
  111. System.out.println("IOS");
  112. osInfo.setOsTypeVersion(OSTYPE_IOS);
  113. }
  114. osInfo.setOsType(OSTYPE_IOS);
  115. return osInfo;
  116. }
  117. // Android 判断
  118. String androidString = "ANDROID";
  119. if (UA.indexOf(androidString) != -1) {
  120. if(isMatch(UA, "\\bMobi", Pattern.CASE_INSENSITIVE)){
  121. osInfo.setDeviceType(DEVICE_TYPE_PHONE);
  122. }else {
  123. osInfo.setDeviceType(DEVICE_TYPE_PAD);
  124. }
  125. rex = ".*" + androidString + "[\\s]*(\\d*[\\._\\d]*)";
  126. Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);
  127. Matcher m = p.matcher(UA);
  128. boolean rs = m.find();
  129. if (rs) {
  130. String version=m.group(1).replace("_", ".");
  131. osInfo.setVersion(version);
  132. System.out.println("Mobil OS is " + OSTYPE_ANDROID + version);
  133. osInfo.setOsTypeVersion(OSTYPE_ANDROID+"_" + version);
  134. }else{
  135. System.out.println("Android");
  136. osInfo.setOsTypeVersion(OSTYPE_ANDROID);
  137. }
  138. osInfo.setOsType(OSTYPE_ANDROID);
  139. return osInfo;
  140. }
  141. // windows phone 判断
  142. String wpString = "WINDOWS PHONE";
  143. if (UA.indexOf(wpString) != -1) {
  144. rex = ".*" + wpString + "[\\s]*[OS\\s]*([\\d][\\.\\d]*)";
  145. Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);
  146. Matcher m = p.matcher(UA);
  147. boolean rs = m.find();
  148. if (rs) {
  149. System.out.println("Mobil OS is " + OSTYPE_WP + m.group(1));
  150. String version=m.group(1);
  151. osInfo.setVersion(version);
  152. osInfo.setOsTypeVersion(OSTYPE_WP+"_" + version);
  153. }else{
  154. System.out.println("WINDOWS PHONE");
  155. osInfo.setOsTypeVersion(OSTYPE_WP);
  156. }
  157. osInfo.setOsType(OSTYPE_WP);
  158. return osInfo;
  159. }
  160. // BlackBerry 黑莓系统判断
  161. String bbString = "BLACKBERRY";
  162. if (UA.indexOf(bbString) != -1) {
  163. rex = ".*" + bbString + "[\\s]*([\\d]*)";
  164. Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);
  165. Matcher m = p.matcher(UA);
  166. boolean rs = m.find();
  167. if (rs) {
  168. System.out.println("Mobil OS is" + " BLACKBERRY " + m.group(1));
  169. String version=m.group(1);
  170. osInfo.setVersion(version);
  171. osInfo.setOsTypeVersion(OSTYPE_BLACKBERRY+"_" + version);
  172. }else{
  173. System.out.println("BLACKBERRY");
  174. osInfo.setOsTypeVersion(OSTYPE_BLACKBERRY);
  175. }
  176. osInfo.setOsType(OSTYPE_BLACKBERRY);
  177. return osInfo;
  178. }
  179. if(UA.contains("LINUX")){//android
  180. if(isMatch(UA, "\\bMobi", Pattern.CASE_INSENSITIVE)){
  181. osInfo.setDeviceType(DEVICE_TYPE_PHONE);
  182. }else {
  183. osInfo.setDeviceType(DEVICE_TYPE_PAD);
  184. }
  185. Pattern p = Pattern.compile("U;\\s*(Adr[\\s]*)?(\\d[\\.\\d]*\\d)[\\s]*;",Pattern.CASE_INSENSITIVE);
  186. Matcher m = p.matcher(UA);
  187. boolean result = m.find();
  188. String find_result = null;
  189. if (result)
  190. {
  191. find_result = m.group(2);
  192. }
  193. if(ValueWidget.isNullOrEmpty(find_result)){
  194. osInfo.setOsTypeVersion(OSTYPE_ANDROID);
  195. return osInfo;
  196. }else{
  197. osInfo.setVersion(find_result);
  198. osInfo.setOsTypeVersion(OSTYPE_ANDROID+"_"+find_result);
  199. return osInfo;
  200. }
  201. }
  202. //UCWEB/2.0 (iOS; U; iPh OS 4_3_2; zh-CN; iPh4)
  203. if(UA.matches(".*((IOS)|(iPAD)).*(IPH).*")){
  204. if(isMatch(UA, "[\\s]*iPh[\\s]*", Pattern.CASE_INSENSITIVE)){
  205. osInfo.setDeviceType(DEVICE_TYPE_PHONE);
  206. }else {
  207. osInfo.setDeviceType(DEVICE_TYPE_PAD);
  208. }
  209. Pattern p = Pattern.compile("U;\\s*(IPH[\\s]*)?(OS[\\s]*)?(\\d[\\._\\d]*\\d)[\\s]*;",Pattern.CASE_INSENSITIVE);
  210. Matcher m = p.matcher(UA);
  211. boolean result = m.find();
  212. String find_result = null;
  213. if (result)
  214. {
  215. find_result = m.group(3);
  216. }
  217. if(ValueWidget.isNullOrEmpty(find_result)){
  218. osInfo.setOsTypeVersion(OSTYPE_IOS);
  219. osInfo.setOsType(OSTYPE_IOS);
  220. return osInfo;
  221. }else{
  222. String version=find_result.replace("_", ".");
  223. osInfo.setVersion(version);
  224. osInfo.setOsTypeVersion(OSTYPE_IOS+"_"+version);
  225. osInfo.setOsType(OSTYPE_IOS);
  226. return osInfo;
  227. }
  228. }
  229. return osInfo;
  230. }
  231. public static boolean isMatch(String source,String regx,int flags){
  232. Pattern p = Pattern.compile(regx,flags);
  233. Matcher m = p.matcher(source);
  234. boolean result = m.find();
  235. return result;
  236. }
  237. }

应用场景:

通过user agent判断是否是手机

Java代码  
  1. /***
  2. * 判断是否是手机(移动端)
  3. * @param userAgent
  4. * @return
  5. */
  6. public static boolean isMobile(String userAgent)
  7. {
  8. userAgent=userAgent.toLowerCase();
  9. String []mobile_agents = {"240x320","acer","acoon","acs-","abacho","ahong","airness","alcatel","amoi","android","anywhereyougo.com","applewebkit/525","applewebkit/532","asus","audio","au-mic","avantogo","becker","benq","bilbo","bird","blackberry","blazer","bleu","cdm-","compal","coolpad","danger","dbtel","dopod","elaine","eric","etouch","fly ","fly_","fly-","go.web","goodaccess","gradiente","grundig","haier","hedy","hitachi","htc","huawei","hutchison","inno","ipad","ipaq","ipod","jbrowser","kddi","kgt","kwc","lenovo","lg ","lg2","lg3","lg4","lg5","lg7","lg8","lg9","lg-","lge-","lge9","longcos","maemo","mercator","meridian","micromax","midp","mini","mitsu","mmm","mmp","mobi","mot-","moto","nec-","netfront","newgen","nexian","nf-browser","nintendo","nitro","nokia","nook","novarra","obigo","palm","panasonic","pantech","philips","phone","pg-","playstation","pocket","pt-","qc-","qtek","rover","sagem","sama","samu","sanyo","samsung","sch-","scooter","sec-","sendo","sgh-","sharp","siemens","sie-","softbank","sony","spice","sprint","spv","symbian","tablet","talkabout","tcl-","teleca","telit","tianyu","tim-","toshiba","tsm","up.browser","utec","utstar","verykool","virgin","vk-","voda","voxtel","vx","wap","wellco","wig browser","wii","windows ce","wireless","xda","xde","zte"};
  10. boolean is_mobile = false;
  11. for (String device : mobile_agents) {
  12. if(userAgent.contains(device)){
  13. is_mobile=true;
  14. break;
  15. }
  16. }
  17. return is_mobile;
  18. }

测试代码:

Java代码  
  1. @Test
  2. public void test_userAgent()
  3. {
  4. String userAgent="Mozilla/5.0 (Linux; U; Android 4.1.1; en-cn; HTC T528d) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.2.58_r984381.520 NetType/WIFI";
  5. System.out.println(HeaderUtil.isMobile(userAgent));
  6. userAgent="Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10";
  7. System.out.println(HeaderUtil.isMobile(userAgent));
  8. }

判断是否是手机访问及手机操作系统相关推荐

  1. 华为手机访问文件服务器,手机访问云服务器文件

    手机访问云服务器文件 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 云服务器创 ...

  2. php怎么判断是否手机网站,php,js判断网站是不是手机访问

    Warning: strncmp() has been disabled for security reasons in /www/web/default/blog/public_html/wp-in ...

  3. 自动切换电脑或手机版(php aspx),ASP程序自动判断是电脑或手机访问网站。

    很早就知道百度可以用电脑和手机访问同一个地址,但是网站会自动根据使用的上网终端选择跳转到不同的页面. 曾经试着用JS去判断,但是JS只是浏览器脚本,似乎没有这么强大的功能去获取电脑和手机各种不同浏览器 ...

  4. php判断电脑浏览器模拟手机访问网页,在PC上测试移动端网站和模拟手机浏览器的5大方法...

    查了很多资料,尝试了大部分方法,下面将这一天的努力总结下分享给大家,也让大家免去看那么多文章,以下介绍的方法,都是本人亲自测试成功的方法,测试环境winxp. 一.Chrome*浏览器 chrome模 ...

  5. PHP CodeBase: 判断用户是否手机访问

    转载地址:http://www.nowamagic.net/librarys/veda/cate/PHP 随着移动设备的普及,网站也会迎来越来越多移动设备的访问.用适应PC的页面,很多时候对手机用户不 ...

  6. 判断用户用手机访问还是用电脑访问网页

    C# 判断用户用手机访问还是用电脑访问网页 string osPat = "mozilla|m3gate|winwap|openwave|Windows NT|Windows 3.1|95| ...

  7. 通过PHP自带的$_SERVER判断 手机访问网站自动跳转到手机版

    需要有PC版网站和移动版网站,当手机访问域名的时候,通过PHP自带的$_SERVER判断浏览设备并跳转到移动版页面.如果是PC电脑打开网址,则不跳转直接访问pc版. 1 <?php 2 //ph ...

  8. java 判断手机访问_下面java代码判断是手机访问还是PC访问什么地方出错了,手机跳转不到制定页面,等待解答...

    最近在做一个项目,要在判断用户是否是通过手机访问网站的,如果是手机访问网站跳到一个登录页面,如果是用户用电脑访问网站跳到另外一个登录页面.我写了以下代码,但是用手机访问网站的时候,跳转不到制定页面,请 ...

  9. django项目内部的views层判断手机访问还是电脑访问

    在做网站时,一般都会通过打包html来制作两个界面,一个提供给电脑端,一个提供给手机端,避免因为兼容性差的问题,界面会变得很丑.当然,如果能保证纯bootstrap开发html界面,则不需要考虑这个问 ...

最新文章

  1. TF-IDF与余弦相似性的应用(一):自动提取关键词
  2. blockly和Java交互_blockly 基础学习(一)
  3. html2image乱码问题,HtmlImageGenerator字体乱码问题解决、html2image放linux上乱码问题解决...
  4. c++ stl 容器 迭代器 stl用法示例
  5. 信息学奥赛C++语言:哥德巴赫猜想
  6. XAMPP修改80和443端口及创建虚拟目录
  7. Codeforces Round #263 (Div.1) B. Appleman and Tree
  8. Redhat(Linux)上的JBoss管理配置
  9. 《数据库系统概念》14-静态散列
  10. 人有多大懒,才有多大闲 (评论『卓有成效的程序员』)
  11. Eclipse使用Git上传新项目到GitHub
  12. 金蝶KIS专业版V14.1生产任务单|销售单等单据图片打印
  13. 【Qt】Qt5.14.2配置yaml-cpp
  14. TFIDF的原理及实现
  15. 点云采样FPS原理及实现
  16. Python实现的简易HTTP代理服务器
  17. java使用aspose打印pdf、word文件
  18. html加水平线紧挨文字,html怎么设置水平线与文字的距离
  19. 十大最佳外国Android游戏下载平台
  20. SAP FICO 第一节 后台配置

热门文章

  1. 【VBS】整点报时,代码超级简单哦
  2. 字数统计方式统计字数(简单版)中文算1个,英文算0.5个,全角字符算1个,半角字符算0.5个。
  3. Qt之实现QQ天气预报窗体翻转效果
  4. option43选项
  5. 史上最全的Java进阶书籍推荐,你看了几本?
  6. plsql 基础教程(二)
  7. 数据结构排序算法——选择排序(简单选择排序)
  8. 为王菲写的第三首歌《中华情》
  9. 有刷电机的速度pid-位置pid算法
  10. 微信小程序自定义loading加载动画(2)