springboot 获取访问者的ip地址、访问设备信息、城市地址信息
1.获取访问者的ip地址:
不多说直接上代码,详解见注释
package com.xr.util;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;
/**
* @Description: 获取IP方法
* @BelongsProject: Jmccms
* @BelongsPackage: com.jmccms.util
* @Author: ChenYongJia
* @CreateTime: 2019-05-14 22:29
* @Email aaa@qq.com
*/
@Slf4j
public class IpUtil {
private static final String LOCAL_IP = "127.0.0.1";
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
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("X-Forwarded-For");
}
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("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? LOCAL_IP : ip;
}
public static boolean internalIp(String ip) {
boolean res = false;
byte[] addr = textToNumericFormatV4(ip);
if (addr != null && ip != null) {
res = internalIp(addr) || LOCAL_IP.equals(ip);
}
return res;
}
private static boolean internalIp(byte[] addr) {
final byte b0 = addr[0];
final byte b1 = addr[1];
// 10.x.x.x/8
final byte SECTION_1 = 0x0A;
// 172.16.x.x/12
final byte SECTION_2 = (byte) 0xAC;
final byte SECTION_3 = (byte) 0x10;
final byte SECTION_4 = (byte) 0x1F;
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
boolean flag = false;
switch (b0) {
case SECTION_1:
flag = true;
break;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
flag = true;
}
break;
case SECTION_5:
if (b1 == SECTION_6) {
flag = true;
}
break;
default:
break;
}
return flag;
}
/**
* 将IPv4地址转换成字节
*IPv4地址
* @param text
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text) {
if (text.length() == 0) {
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try {
long l;
int i;
switch (elements.length) {
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L))
return null;
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L))
return null;
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L))
return null;
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
return null;
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L))
return null;
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
return null;
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
} catch (NumberFormatException e) {
log.error("数字格式化异常",e);
return null;
}
return bytes;
}
public static String getLocalIP() {
String ip = "";
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
InetAddress addr;
try {
addr = InetAddress.getLocalHost();
ip = addr.getHostAddress();
} catch (UnknownHostException e) {
log.error("获取失败",e);
}
return ip;
} else {
try {
Enumeration<?> e1 = (Enumeration<?>) NetworkInterface
.getNetworkInterfaces();
while (e1.hasMoreElements()) {
NetworkInterface ni = (NetworkInterface) e1.nextElement();
if (!ni.getName().equals("eth0")) {
continue;
} else {
Enumeration<?> e2 = ni.getInetAddresses();
while (e2.hasMoreElements()) {
InetAddress ia = (InetAddress) e2.nextElement();
if (ia instanceof Inet6Address)
continue;
ip = ia.getHostAddress();
return ip;
}
break;
}
}
} catch (SocketException e) {
log.error("获取失败",e);
}
}
return "";
}
}
在控制类里使用:
@RequestMapping("login")
public ResponseResult login( HttpServletRequest request){
ResponseResult result=new ResponseResult();
String ipAddress = IpUtil.getIpAddr(request);
System.out.println(ipAddress);
result.getData().put("message",ipAddress);
return result;
}
2.获取访问设备信息:
Spring Mobile是一个框架,该框架提供的功能可以检测向您的Spring网站发出请求的设备的类型,并基于该设备提供其他视图。像所有Spring项目一样,Spring Mobile的真正强大之处在于它的扩展容易程度。
特征
-
设备解析器抽象,用于移动和平板设备的服务器端检测
-
网站首选项管理,允许用户指示他或她是否喜欢“正常”,“移动”或“平板电脑”体验
-
站点切换器,能够根据用户的设备和显示的站点首选项,将用户切换到最适合的网站,无论是手机,平板电脑还是普通网站
-
设备感知视图管理,用于组织和管理特定设备的不同视图
SpringBoot配置:
1.要使用Spring Mobile,需要在项目的pom.xml里添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mobile</artifactId>
<version>1.5.9.RELEASE</version>
</dependency>
2.添加以下基于Java的配置以在Spring Web应用程序中启用设备检测:
package com.xr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver;
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
import org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor;
import org.springframework.mobile.device.site.SitePreferenceHandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class MobileConfig implements WebMvcConfigurer {
@Bean
public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() {
return new DeviceResolverHandlerInterceptor();
}
@Bean
public DeviceHandlerMethodArgumentResolver
deviceHandlerMethodArgumentResolver() {
return new DeviceHandlerMethodArgumentResolver();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new DeviceResolverHandlerInterceptor());
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new DeviceHandlerMethodArgumentResolver());
}
}
2.将Device注入你的控制器:
@RequestMapping("about")
public void about(Device device){
if (device.isMobile()) {
System.out.println("========请求来源设备是手机!========");
} else if (device.isTablet()) {
System.out.println("========请求来源设备是平板!========");
} else if(device.isNormal()){
System.out.println("========请求来源设备是PC!========");
}else {
System.out.println("========请求来源设备是其它!========");
}
}
3.获取访问ip城市地址信息:
1、去腾讯位置服务进行开发者注册
2、通过访问控制台中key管理,申请key
3、在key设置里设置白名单,否则有key也不能成功调用接口。
包括域名白名单和授权ip,一般是自己本机和服务器的ip
4、创建查找位置的工具类
package com.xr.util;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
public class IpToAddressUtil {
//使用腾讯的接口通过ip拿到城市信息
private static final String KEY = "自己的key";
public static String getCityInfo(String ip) {
String s = sendGet(ip, KEY);
Map map = JSONObject.parseObject(s, Map.class);
String message = (String) map.get("message");
if("query ok".equals(message)){
Map result = (Map) map.get("result");
Map addressInfo = (Map) result.get("ad_info");
String nation = (String) addressInfo.get("nation");
String province = (String) addressInfo.get("province");
// String district = (String) addressInfo.get("district");
String city = (String) addressInfo.get("city");
String address = nation + "-" + province + "-" + city;
return address;
}else{
System.out.println(message);
return null;
}
}
//根据在腾讯位置服务上申请的key进行请求操作
public static String sendGet(String ip, String key) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = "https://apis.map.qq.com/ws/location/v1/ip?ip="+ip+"&key="+key;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
// for (Map.Entry entry : map.entrySet()) {
// System.out.println(key + "--->" + entry);
// }
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
}
5、在控制类里直接调用就OK
上一篇: PHP打开.dbf类型文件_
下一篇: 怎么做到检测文件是否存在,然后返回一段话
推荐阅读
-
springboot 获取访问者的ip地址、访问设备信息、城市地址信息
-
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法
-
php 获取客户端IP地址、地理信息、浏览器信息、本地真实IP的代码
-
如何在SqlServer中获取前端连接的IP地址,计算机名等信息
-
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法,所有信息经纬度_PHP教程
-
超简单的php获取ip地址信息的接口范例
-
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法
-
Android获得设备状态信息、Mac地址、IP地址的方法
-
springboot 获取访问接口的请求的IP地址的实现
-
php获取在线访客Ip地址信息的方法