模块化拆分
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package cn.celess.visitor.controller;
|
||||
|
||||
import cn.celess.common.entity.Response;
|
||||
import cn.celess.common.service.CountService;
|
||||
import cn.celess.common.service.VisitorService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/02 23:09
|
||||
*/
|
||||
@RestController
|
||||
public class VisitorController {
|
||||
@Autowired
|
||||
VisitorService visitorService;
|
||||
@Autowired
|
||||
CountService countService;
|
||||
|
||||
@GetMapping("/visitor/count")
|
||||
public Response getVisitorCount() {
|
||||
return Response.success(countService.getVisitorCount());
|
||||
}
|
||||
|
||||
@GetMapping("/admin/visitor/page")
|
||||
public Response page(@RequestParam(value = "count", required = false, defaultValue = "10") int count,
|
||||
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
|
||||
@RequestParam(value = "showLocation", required = false, defaultValue = "true") boolean showLocation) {
|
||||
return Response.success(visitorService.visitorPage(page, count, showLocation));
|
||||
}
|
||||
|
||||
@PostMapping("/visit")
|
||||
public Response add(HttpServletRequest request) {
|
||||
return Response.success(visitorService.addVisitor(request));
|
||||
}
|
||||
|
||||
@GetMapping("/dayVisitCount")
|
||||
public Response dayVisitCount() {
|
||||
return Response.success(countService.getDayVisitCount());
|
||||
}
|
||||
|
||||
@GetMapping("/ip/{ip}")
|
||||
public Response ipLocation(@PathVariable("ip") String ip) {
|
||||
return Response.success(visitorService.location(ip));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地访问者的ip
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/ip")
|
||||
public Response getIp(HttpServletRequest request) {
|
||||
return Response.success(request.getRemoteAddr());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package cn.celess.visitor.serviceimpl;
|
||||
|
||||
import cn.celess.common.enmu.ResponseEnum;
|
||||
import cn.celess.common.entity.Visitor;
|
||||
import cn.celess.common.entity.vo.PageData;
|
||||
import cn.celess.common.entity.vo.VisitorModel;
|
||||
import cn.celess.common.exception.MyException;
|
||||
import cn.celess.common.mapper.VisitorMapper;
|
||||
import cn.celess.common.service.VisitorService;
|
||||
import cn.celess.common.util.DateFormatUtil;
|
||||
import cn.celess.common.util.RedisUtil;
|
||||
import cn.celess.visitor.util.AddressUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import eu.bitwalker.useragentutils.Browser;
|
||||
import eu.bitwalker.useragentutils.OperatingSystem;
|
||||
import eu.bitwalker.useragentutils.UserAgent;
|
||||
import eu.bitwalker.useragentutils.Version;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/02 23:04
|
||||
*/
|
||||
@Service
|
||||
public class VisitorServiceImpl implements VisitorService {
|
||||
@Autowired
|
||||
VisitorMapper visitorMapper;
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
public String location(String ip) {
|
||||
return getLocation(ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<VisitorModel> visitorPage(int page, int count, boolean showLocation) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<Visitor> visitorList = visitorMapper.findAll();
|
||||
return new PageData<>(new PageInfo<>(visitorList), list2List(visitorList, showLocation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisitorModel addVisitor(HttpServletRequest request) {
|
||||
//新session
|
||||
if (!request.getSession().isNew()) {
|
||||
return null;
|
||||
}
|
||||
if (isSpiderBot(request.getHeader("User-Agent"))) {
|
||||
return null;
|
||||
}
|
||||
Visitor visitor = new Visitor();
|
||||
visitor.setIp(request.getRemoteAddr());
|
||||
visitor.setDate(new Date());
|
||||
visitor.setUa(request.getHeader("User-Agent"));
|
||||
//记录当日的访问
|
||||
String dayVisitCount = redisUtil.get("dayVisitCount");
|
||||
|
||||
LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
||||
long secondsLeftToday = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
|
||||
if (dayVisitCount == null) {
|
||||
redisUtil.setEx("dayVisitCount", "1", secondsLeftToday, TimeUnit.SECONDS);
|
||||
} else {
|
||||
int count = Integer.parseInt(dayVisitCount) + 1;
|
||||
redisUtil.setEx("dayVisitCount", count + "", secondsLeftToday, TimeUnit.SECONDS);
|
||||
}
|
||||
if (visitorMapper.insert(visitor) == 0) {
|
||||
throw new MyException(ResponseEnum.FAILURE);
|
||||
}
|
||||
return trans(visitor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据修改
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<VisitorModel> list2List(List<Visitor> visitorList, boolean showLocation) {
|
||||
List<VisitorModel> visitorModelList = new ArrayList<>();
|
||||
for (Visitor v : visitorList) {
|
||||
VisitorModel trans = trans(v);
|
||||
if (showLocation) {
|
||||
trans.setLocation(getLocation(v.getIp()));
|
||||
}
|
||||
visitorModelList.add(trans);
|
||||
}
|
||||
return visitorModelList;
|
||||
}
|
||||
|
||||
/***
|
||||
* 转化为model
|
||||
*
|
||||
* @param v
|
||||
* @return
|
||||
*/
|
||||
private VisitorModel trans(Visitor v) {
|
||||
UserAgent userAgent = UserAgent.parseUserAgentString(v.getUa());
|
||||
VisitorModel visitor = new VisitorModel();
|
||||
visitor.setId(v.getId());
|
||||
visitor.setDate(DateFormatUtil.get(v.getDate()));
|
||||
visitor.setIp(v.getIp());
|
||||
Browser browser = userAgent.getBrowser();
|
||||
visitor.setBrowserName(browser == null ? "" : browser.getName());
|
||||
OperatingSystem operatingSystem = userAgent.getOperatingSystem();
|
||||
visitor.setOSName(operatingSystem == null ? "" : operatingSystem.getName());
|
||||
Version browserVersion = userAgent.getBrowserVersion();
|
||||
visitor.setBrowserVersion(browserVersion == null ? "" : browserVersion.getVersion());
|
||||
return visitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ua判断是不是爬虫
|
||||
*
|
||||
* @param ua ua
|
||||
* @return true:爬虫 false :不是爬虫
|
||||
*/
|
||||
private boolean isSpiderBot(String ua) {
|
||||
if (ua == null) {
|
||||
return false;
|
||||
}
|
||||
//服务器端的缓存抓取
|
||||
if (ua.contains("https://github.com/prerender/prerender")) {
|
||||
return true;
|
||||
}
|
||||
//搜索引擎得爬虫ua一般有链接
|
||||
if (ua.contains("http://")) {
|
||||
return true;
|
||||
}
|
||||
//防止没有匹配到http
|
||||
return ua.toLowerCase().contains("spider");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip的地址
|
||||
*
|
||||
* @param ip
|
||||
* @return
|
||||
*/
|
||||
private String getLocation(String ip) {
|
||||
return AddressUtil.getCityInfo(ip);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package cn.celess.visitor.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.lionsoul.ip2region.DataBlock;
|
||||
import org.lionsoul.ip2region.DbConfig;
|
||||
import org.lionsoul.ip2region.DbSearcher;
|
||||
import org.lionsoul.ip2region.Util;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/09/04 9:36
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class AddressUtil {
|
||||
|
||||
public static String getCityInfo(String ip) {
|
||||
File file;
|
||||
try {
|
||||
//db
|
||||
String dbPath = AddressUtil.class.getResource("/ip2region/ip2region.db").getPath();
|
||||
file = new File(dbPath);
|
||||
if (!file.exists()) {
|
||||
String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
|
||||
dbPath = tmpDir + "ip.db";
|
||||
file = new File(dbPath);
|
||||
FileCopyUtils.copy(Objects.requireNonNull(AddressUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.db")), new FileOutputStream(file));
|
||||
}
|
||||
//查询算法
|
||||
//B-tree
|
||||
int algorithm = DbSearcher.BTREE_ALGORITHM;
|
||||
try {
|
||||
DbConfig config = new DbConfig();
|
||||
DbSearcher searcher = new DbSearcher(config, dbPath);
|
||||
Method method = null;
|
||||
switch (algorithm) {
|
||||
case DbSearcher.BTREE_ALGORITHM:
|
||||
method = searcher.getClass().getMethod("btreeSearch", String.class);
|
||||
break;
|
||||
case DbSearcher.BINARY_ALGORITHM:
|
||||
method = searcher.getClass().getMethod("binarySearch", String.class);
|
||||
break;
|
||||
case DbSearcher.MEMORY_ALGORITYM:
|
||||
method = searcher.getClass().getMethod("memorySearch", String.class);
|
||||
break;
|
||||
}
|
||||
|
||||
DataBlock dataBlock;
|
||||
if (!Util.isIpAddress(ip)) {
|
||||
System.out.println("Error: Invalid ip address");
|
||||
}
|
||||
|
||||
dataBlock = (DataBlock) method.invoke(searcher, ip);
|
||||
|
||||
return dataBlock.getRegion();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user