为了获取当前访问用户的ip,所以编写了一个小demo,供大家参考学习。
文章目录
简单阐述一下我们的demo要做的事,先搭建一个简单的网页,然后我们去访问这个网页的时候获取访问者的用户ip,然后保存在数据库中,点击查看ip的时候,显示在网页中。
接下来我们就直接开始操作吧!!!!!
一、创建数据库
既然是要把ip存在数据库中,那我们先简单的建个数据库,建个表。
/*
Navicat Premium Data Transfer
Source Server : root
Source Server Type : MySQL
Source Server Version : 50527
Source Host : localhost:3306
Source Schema : ip
Target Server Type : MySQL
Target Server Version : 50527
File Encoding : 65001
Date: 08/01/2022 12:16:59
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for ipadrr
-- ----------------------------
DROP TABLE IF EXISTS `ipadrr`;
CREATE TABLE `ipadrr` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish2_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_spanish2_ci ROW_FORMAT = Compact;
SET FOREIGN_KEY_CHECKS = 1;
二、新建个springboot的项目
1.pom.xml / application.yml
pom.xml 如图所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml 如图所示: 只需要将数据库配置改成自己的即可使用!!!
server:
port: 8088
spring:
thymeleaf:
cache: false
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ip?useUnicode=true&characterEncoding=utf-8
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
username: root
mvc:
view:
suffix: .html
prefix: classpath:/templates/
static-path-pattern: /static/**
mybatis:
type-aliases-package: com.example.demo.pojo
mapper-locations: classpath:mybatis/ipMapper.xml
2.实体类(pojo)
Ip.java如下所示:
package com.example.demo.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Ip implements Serializable {
private long id;
private String ip;
}
3.数据持久层
也就是dao层,它是介于业务逻辑层和数据库之间,进行数据的访问和操作。
ipDao.java如下所示:
package com.example.demo.dao;
import com.example.demo.pojo.Ip;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface IpDao {
//将获取到的ip存入数据库中
int insert(String ip);
//查询ip
List<Ip> queryIdList();
}
ORM框架用的是Mybatis,ipMapper文件如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.IpDao">
<insert id="insert">
insert into ipadrr (ip) values (#{ip});
</insert>
<select id="queryIdList" resultType="com.example.demo.pojo.Ip">
select * from ipadrr;
</select>
</mapper>
4.业务逻辑层
业务逻辑层接口及实现类代码如下所示:
接口类:
package com.example.demo.server;
import com.example.demo.pojo.Ip;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface IpServer {
int insert(String ip);
List<Ip> queryIdList();
}
实现类:
package com.example.demo.server.impl;
import com.example.demo.dao.IpDao;
import com.example.demo.pojo.Ip;
import com.example.demo.server.IpServer;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service("ipServer")
public class IpServerImpl implements IpServer {
@Resource
private IpDao ipDao;
@Override
public int insert(String ip) {
return ipDao.insert(ip);
}
@Override
public List<Ip> queryIdList() {
return ipDao.queryIdList();
}
}
5.获取当前网络ip工具类(最重要的)
package com.example.demo.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class CusAccessObjectUtil {
/**
* 获取当前网络ip
* @param request
* @return
*/
public String getIpAddr(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}
}
6.控制层
package com.example.demo.controller;
import com.example.demo.pojo.Ip;
import com.example.demo.server.IpServer;
import com.example.demo.utils.CusAccessObjectUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Controller
public class controller {
@Resource
private IpServer ipServer;
@RequestMapping("/ip")
public String hello(HttpServletRequest request,String url,String ip){
CusAccessObjectUtil cus = new CusAccessObjectUtil();
cus.getIpAddr(request);
url = request.getRequestURL().toString();//获得客户端发送请求的完整url
ip = request.getRemoteAddr();//返回发出请求的IP地址
System.out.println(url);
System.out.println(ip);
ipServer.insert(ip);
return "helloIp";
}
@RequestMapping("/lookIp")
public String lookIp(Model model){
List<Ip> ips = ipServer.queryIdList();
model.addAttribute("ip",ips);
return "ipList";
}
}
7.表现层html
需要的两个html文件,如下所示:
helloIp.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="app">
<a th:href="@{/lookIp}" style="color: red">哈喽,请点击查看ip</a>
</div>
</body>
</html>
ipList.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ip</title>
</head>
<body>
<table border="1" th:action="@{/queryIpList}">
<tr>
<td>id</td>
<td>ip</td>
</tr>
<tr th:each="user:${ip}">
<td th:text="${user.id}"></td>
<td th:text="${user.ip}"></td>
</tr>
</table>
<!--<div th:each="user:${ip}">-->
<!-- ip = <a th:href="${user.ip}"></a>-->
<!--</div>-->
</body>
</html>
一切准备就绪后直接启动项目,查看效果!!!!!!!!
我先来展示一波,整起!!!
首先我是win+R----->cmd----->ipconfig查询了自己的ip,然后访问:http://192.168.121.1:8088/ip,让我们来看按效果,往下看!
点击查看ip的按钮:
到这里就结束了,这个demo还是不太完整,按理来说当访问网址的时候获取ip,点击查看ip时,正常应该是只能查看当前获取到的网络ip,但是咱们的demo实现的是,查看的是整个ip的列表,也就是说,当你多访问几次或者使用不同的电脑去多访问几次的话,会查到一个ip列表,显然不是很合理。
既然不合理,我简单说一下思路,我们在存储获取到的ip的时候,可以先删除数据库中的ip列表,这样的话他就只能查看到当前网络的ip,这样相对来说是比较合理的,有兴趣的小伙伴可以完善一下。