在java中登录时获取来访者的ip及mac地址,需要速度快一点的,外网情况下,希望获取速度快点的,因为现在的方法缺点就是获取速度慢,本机登录都得两三秒,部署到正式服务器上更慢,所以现在希望优化一下,希望大神们指教,有点啰嗦,请不要介意
可以先锁定下登录时慢的原因,确定是不是获取ip等信息的时候导致的慢。
可以锁定不是获取ip慢的原因,我走断点的时候很明显的事获取mac地址这个方法慢
问这个问题,最好的方法是提供你怎么获取来访者mac地址的代码。
我google了一下java 获取mac地址,发现大部分是无聊无趣的代码。
简单的说,就是老板要个这功能,我就写一个这功能。
除此之外,没有任何价值。
我不只是说JAVA语言,
任何通过Web浏览器得到MAC地址的想法都是。
package com.sview.web.tools; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; /** * 获取系统的信息 * @author liuyazhuang * */ public final class SystemUtils { /** * 获取访问者IP * 在一般情况下使用Request.getRemoteAddr()即可,但是经过nginx等反向代理软件后,这个方法会失效。 * * 本方法先从Header中获取X-Real-IP,如果不存在再从X-Forwarded-For获得第一个IP(用,分割), * 如果还不存在则调用Request .getRemoteAddr()。 * @param request * @return */ public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-Real-IP"); if (ip!= null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) { return ip; } ip = request.getHeader("X-Forwarded-For"); if (ip!= null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) { // 多次反向代理后会有多个IP值,第一个为真实IP。 int index = ip.indexOf(','); if (index != -1) { return ip.substring(0, index); } else { return ip; } } else { return request.getRemoteAddr(); } } /** * 获取来访者的浏览器版本 * @param request * @return */ public static String getRequestBrowserInfo(HttpServletRequest request){ String browserVersion = null; String header = request.getHeader("user-agent"); if(header == null || header.equals("")){ return ""; } if(header.indexOf("MSIE")>0){ browserVersion = "IE"; }else if(header.indexOf("Firefox")>0){ browserVersion = "Firefox"; }else if(header.indexOf("Chrome")>0){ browserVersion = "Chrome"; }else if(header.indexOf("Safari")>0){ browserVersion = "Safari"; }else if(header.indexOf("Camino")>0){ browserVersion = "Camino"; }else if(header.indexOf("Konqueror")>0){ browserVersion = "Konqueror"; } return browserVersion; } /** * 获取系统版本信息 * @param request * @return */ public static String getRequestSystemInfo(HttpServletRequest request){ String systenInfo = null; String header = request.getHeader("user-agent"); if(header == null || header.equals("")){ return ""; } //得到用户的操作系统 if (header.indexOf("NT 6.0") > 0){ systenInfo = "Windows Vista/Server 2008"; } else if (header.indexOf("NT 5.2") > 0){ systenInfo = "Windows Server 2003"; } else if (header.indexOf("NT 5.1") > 0){ systenInfo = "Windows XP"; } else if (header.indexOf("NT 6.0") > 0){ systenInfo = "Windows Vista"; } else if (header.indexOf("NT 6.1") > 0){ systenInfo = "Windows 7"; } else if (header.indexOf("NT 6.2") > 0){ systenInfo = "Windows Slate"; } else if (header.indexOf("NT 6.3") > 0){ systenInfo = "Windows 9"; } else if (header.indexOf("NT 5") > 0){ systenInfo = "Windows 2000"; } else if (header.indexOf("NT 4") > 0){ systenInfo = "Windows NT4"; } else if (header.indexOf("Me") > 0){ systenInfo = "Windows Me"; } else if (header.indexOf("98") > 0){ systenInfo = "Windows 98"; } else if (header.indexOf("95") > 0){ systenInfo = "Windows 95"; } else if (header.indexOf("Mac") > 0){ systenInfo = "Mac"; } else if (header.indexOf("Unix") > 0){ systenInfo = "UNIX"; } else if (header.indexOf("Linux") > 0){ systenInfo = "Linux"; } else if (header.indexOf("SunOS") > 0){ systenInfo = "SunOS"; } return systenInfo; } /** * 获取来访者的主机名称 * @param ip * @return */ public static String getHostName(String ip){ InetAddress inet; try { inet = InetAddress.getByName(ip); return inet.getHostName(); } catch (UnknownHostException e) { e.printStackTrace(); } return ""; } /** * 命令获取mac地址 * @param cmd * @return */ private static String callCmd(String[] cmd) { String result = ""; String line = ""; try { Process proc = Runtime.getRuntime().exec(cmd); InputStreamReader is = new InputStreamReader(proc.getInputStream()); BufferedReader br = new BufferedReader (is); while ((line = br.readLine ()) != null) { result += line; } }catch(Exception e) { e.printStackTrace(); } return result; } /** * * * * @param cmd * 第一个命令 * * @param another * 第二个命令 * * @return 第二个命令的执行结果 * */ private static String callCmd(String[] cmd,String[] another) { String result = ""; String line = ""; try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); proc.waitFor(); // 已经执行完第一个命令,准备执行第二个命令 proc = rt.exec(another); InputStreamReader is = new InputStreamReader(proc.getInputStream()); BufferedReader br = new BufferedReader (is); while ((line = br.readLine ()) != null) { result += line; } }catch(Exception e) { e.printStackTrace(); } return result; } /** * * * * @param ip * 目标ip,一般在局域网内 * * @param sourceString * 命令处理的结果字符串 * * @param macSeparator * mac分隔符号 * * @return mac地址,用上面的分隔符号表示 * */ private static String filterMacAddress(final String ip, final String sourceString,final String macSeparator) { String result = ""; String regExp = "((([0-9,A-F,a-f]{1,2}" + macSeparator + "){1,5})[0-9,A-F,a-f]{1,2})"; Pattern pattern = Pattern.compile(regExp); Matcher matcher = pattern.matcher(sourceString); while(matcher.find()){ result = matcher.group(1); if(sourceString.indexOf(ip) <= sourceString.lastIndexOf(matcher.group(1))) { break; // 如果有多个IP,只匹配本IP对应的Mac. } } return result; } /** * @param ip * 目标ip * @return Mac Address * */ private static String getMacInWindows(final String ip){ String result = ""; String[] cmd = {"cmd","/c","ping " + ip}; String[] another = {"cmd","/c","arp -a"}; String cmdResult = callCmd(cmd,another); result = filterMacAddress(ip,cmdResult,"-"); return result; } /** * * @param ip * 目标ip * @return Mac Address * */ private static String getMacInLinux(final String ip){ String result = ""; String[] cmd = {"/bin/sh","-c","ping " + ip + " -c 2 && arp -a" }; String cmdResult = callCmd(cmd); result = filterMacAddress(ip,cmdResult,":"); return result; } /** * 获取MAC地址 * * @return 返回MAC地址 */ public static String getMacAddress(String ip){ String macAddress = ""; macAddress = getMacInWindows(ip).trim(); if(macAddress==null||"".equals(macAddress)){ macAddress = getMacInLinux(ip).trim(); } return macAddress; } }
这是我现在用的方法,可以获取到mac地址,但是速度回很慢。而且没办法,现在登录这一块需要这么一个mac地址,暂时还没想到可以用什么代替,所以只能先问一下了
不好意思,刚才看了一下正式服务器,mac地址这个方法获取也是不对的,
我这里给你一个可以快速获取ip的类,可以进行过滤代理
package com.ordermeal.Util; import javax.servlet.http.HttpServletRequest; public class IpProbe { public static String getRemoteAddr(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } private static final String[] HEADERS_TO_TRY = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR", "X-Real-IP" }; public static String getClientIpAddress(HttpServletRequest request) { for (String header : HEADERS_TO_TRY) { String ip = request.getHeader(header); if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { return ip; } } return request.getRemoteAddr(); } public static String getClientIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_FORWARDED"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_VIA"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("REMOTE_ADDR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-Real-IP"); if (null != ip && !"".equals(ip.trim()) && !"unknown".equalsIgnoreCase(ip)) { return ip; } ip = request.getHeader("X-Forwarded-For"); if (null != ip && !"".equals(ip.trim()) && !"unknown".equalsIgnoreCase(ip)) { // get first ip from proxy ip int index = ip.indexOf(','); if (index != -1) { return ip.substring(0, index); } else { return ip; } } return request.getRemoteAddr(); } }
我这边获取ip使用的另一个方法,速度也挺快的,也能获取出来,所以获取ip的暂时不需要,谢谢
@软件杨威: 那可以可以使用多线程,并设置获取时间
@DanBrown: 我是在登录的时候需要获取mac地址的,没有办法用多线程,谢谢了,现在暂时不需要了,需求已经改了