实体类
@EqualsAndHashCode(callSuper = true)
@Data
@SuppressWarnings("serial")
@ApiModel("OperationLog")
public class OperationLog extends Model<OperationLog> implements Serializable {
private static final long serialVersionUID = -53946117294772715L;
@ApiModelProperty("id主键")
@TableId(type = IdType.AUTO)
private Integer id;
@ApiModelProperty("功能模块")
private String operModel;
@ApiModelProperty("操作类型")
private String operType;
@ApiModelProperty("请求参数")
private Object operParam;
@ApiModelProperty("操作人id")
private Integer operUserId;
@ApiModelProperty("操作方法")
private String operMethod;
@ApiModelProperty("操作url")
private String operUrl;
@ApiModelProperty("操作ip")
private String operIp;
@ApiModelProperty("操作描述")
private String operDes;
@ApiModelProperty("操作时间")
private Date operTime;
@ApiModelProperty("返回结果")
private Object operResult;
@ApiModelProperty("操作地址")
private Object operAddress;
}
自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperateLog {
String operateModule() default "";
String operateType() default "";
String operateDes() default "";
}
切面
@Aspect
@Component
public class OperationLogAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(OperationLogAspect.class);
@Resource
private OperationLogService operationLogService;
@Pointcut("@annotation(com.xxx.xxx.xxx.OperateLog)")
public void operationLogPointCut() {
}
@AfterReturning(value = "operationLogPointCut()",returning = "jsonResult")
public void saveOperationLog(JoinPoint joinPoint,Object jsonResult) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
assert requestAttributes != null;
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
OperationLog operationLog = new OperationLog();
try {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
OperateLog opLog = method.getAnnotation(OperateLog.class);
if (opLog != null) {
String opModule = opLog.operateModule();
String opType = opLog.operateType();
String opDesc = opLog.operateDes();
operationLog.setOperModel(opModule);
operationLog.setOperType(opType);
operationLog.setOperDes(opDesc);
}
String className = joinPoint.getTarget().getClass().getName();
String methodName = method.getName();
methodName = className + "." + methodName;
operationLog.setOperMethod(methodName);
assert request != null;
operationLog.setOperParam(JSON.toJSONString(getParameter(method,joinPoint.getArgs())));
operationLog.setOperUserId(Objects.requireNonNull(UserInfoUtils.getUserInfo()).getUserId());
operationLog.setOperIp(IpUtils.getIpAddr(request));
operationLog.setOperUrl(request.getRequestURI());
operationLog.setOperTime(new Date());
operationLog.setOperResult(JSON.toJSONString(jsonResult));
operationLog.setOperAddress(AddressUtils.getRealAddressByIp(IpUtils.getIpAddr(request)));
operationLogService.save(operationLog);
} catch (Exception e) {
LOGGER.info("添加操作日志失败:{}", operationLog);
}
}
private Object getParameter(Method method, Object[] args) {
List<Object> argList = new ArrayList<>();
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
if (requestBody != null) {
argList.add(args[i]);
}
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
if (requestParam != null) {
Map<String, Object> map = new HashMap<>(args.length);
String key = parameters[i].getName();
if (!StringUtils.isEmpty(requestParam.value())) {
key = requestParam.value();
}
map.put(key, args[i]);
argList.add(map);
}
}
if (argList.size() == 0) {
return null;
} else if (argList.size() == 1) {
return argList.get(0);
} else {
return argList;
}
}
工具类
ipUtils
public class IpUtils {
private static final String UNKNOWN_IP_ADDR = "unknown";
public static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return UNKNOWN_IP_ADDR;
}
String ip = request.getHeader("x-forwarded-for");
if (StringUtils.isBlank(ip) || UNKNOWN_IP_ADDR.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || UNKNOWN_IP_ADDR.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (StringUtils.isBlank(ip) || UNKNOWN_IP_ADDR.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || UNKNOWN_IP_ADDR.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (StringUtils.isBlank(ip) || UNKNOWN_IP_ADDR.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
public static boolean internalIp(String ip) {
byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip);
}
private static boolean internalIp(byte[] addr) {
if (addr == null || addr.length < ConstantValue.TWO) {
return true;
}
final byte b0 = addr[0];
final byte b1 = addr[1];
final byte section1 = 0x0A;
final byte section2 = (byte) 0xAC;
final byte section3 = (byte) 0x10;
final byte section4 = (byte) 0x1F;
final byte section5 = (byte) 0xC0;
final byte section6 = (byte) 0xA8;
switch (b0) {
case section1:
return true;
case section2:
if (b1 >= section3 && b1 <= section4) {
return true;
}
case section5:
return b1 == section6;
default:
return false;
}
}
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 > ConstantValue.LENGTH)) {
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 > ConstantValue.LENGTH_1)) {
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > ConstantValue.LENGTH_2)) {
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 < ConstantValue.TWO; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > ConstantValue.LENGTH_1)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > ConstantValue.LENGTH_3)) {
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < ConstantValue.FOUR; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l >ConstantValue.LENGTH_1)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
} catch (NumberFormatException e) {
return null;
}
return bytes;
}
}
httpUtils
@Slf4j
public class HttpUtils {
public static String sendGet(String url, String param, String contentType)
{
StringBuilder result = new StringBuilder();
BufferedReader in = null;
try
{
String urlNameString = url + "?" + param;
log.info("sendGet - {}", urlNameString);
URL realUrl = new URL(urlNameString);
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();
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
String line;
while ((line = in.readLine()) != null)
{
result.append(line);
}
log.info("recv - {}", result);
}
catch (ConnectException e)
{
log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
}
catch (SocketTimeoutException e)
{
log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
}
catch (IOException e)
{
log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
}
catch (Exception e)
{
log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
}
finally
{
try
{
if (in != null)
{
in.close();
}
}
catch (Exception ex)
{
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
}
}
return result.toString();
}
}
AddressUtills
public class AddressUtils {
private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
public static final String UNKNOWN = "XX XX";
public static String getRealAddressByIp(String ip) {
if (IpUtils.internalIp(ip)) {
return "内网IP";
}
try {
String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", ConstantValue.GBK);
if (StringUtils.isEmpty(rspStr)) {
log.error("获取地理位置异常 {}", ip);
return UNKNOWN;
}
JSONObject obj = JSONObject.parseObject(rspStr);
String region = obj.getString("pro");
String city = obj.getString("city");
return String.format("%s %s", region, city);
} catch (Exception e) {
log.error("获取地理位置异常 {}", ip);
}
return UNKNOWN;
}
}