From a512e42d54c9859677c8b85d70a992d513c03241 Mon Sep 17 00:00:00 2001 From: kaede10 Date: Wed, 21 Feb 2024 11:23:40 +0800 Subject: [PATCH 1/2] add msg code and logutil --- pom.xml | 5 + .../easysoftware/aop/ManagementLogAOP.java | 36 +++++ .../application/GlobalExceptionHandler.java | 42 ++---- .../com/easysoftware/result/MessageCode.java | 52 ++++++++ .../java/com/easysoftware/result/Result.java | 123 ++++++++++++++++++ .../com/easysoftware/utils/ClientUtil.java | 67 ++++++++++ .../java/com/easysoftware/utils/LogUtil.java | 56 ++++++++ .../com/easysoftware/vo/ManagementLog.java | 24 ++++ .../java/com/easysoftware/vo/ResultMsgVo.java | 21 +++ .../java/com/easysoftware/vo/ResultVo.java | 17 +++ 10 files changed, 413 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/easysoftware/aop/ManagementLogAOP.java create mode 100644 src/main/java/com/easysoftware/result/MessageCode.java create mode 100644 src/main/java/com/easysoftware/result/Result.java create mode 100644 src/main/java/com/easysoftware/utils/ClientUtil.java create mode 100644 src/main/java/com/easysoftware/utils/LogUtil.java create mode 100644 src/main/java/com/easysoftware/vo/ManagementLog.java create mode 100644 src/main/java/com/easysoftware/vo/ResultMsgVo.java create mode 100644 src/main/java/com/easysoftware/vo/ResultVo.java diff --git a/pom.xml b/pom.xml index a5c7a2d..810abba 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,11 @@ spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-aop + + org.projectlombok lombok diff --git a/src/main/java/com/easysoftware/aop/ManagementLogAOP.java b/src/main/java/com/easysoftware/aop/ManagementLogAOP.java new file mode 100644 index 0000000..bdc3545 --- /dev/null +++ b/src/main/java/com/easysoftware/aop/ManagementLogAOP.java @@ -0,0 +1,36 @@ +package com.easysoftware.aop; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.easysoftware.utils.LogUtil; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Aspect +@Component +public class ManagementLogAOP { + + @Autowired + private HttpServletRequest request; + + @Autowired + private HttpServletResponse response; + + //定义切点 + @Pointcut("execution(* com.easysoftware.adapter.*.*(..))") + public void pointcut() { + } + + @AfterReturning(pointcut = "pointcut()", returning = "returnObject") + public void afterReturning(JoinPoint joinPoint, Object returnObject) { + LogUtil.managementOperate(joinPoint, request, response, returnObject); + } + +} + diff --git a/src/main/java/com/easysoftware/application/GlobalExceptionHandler.java b/src/main/java/com/easysoftware/application/GlobalExceptionHandler.java index 5e8f891..cc59104 100644 --- a/src/main/java/com/easysoftware/application/GlobalExceptionHandler.java +++ b/src/main/java/com/easysoftware/application/GlobalExceptionHandler.java @@ -1,46 +1,28 @@ package com.easysoftware.application; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.util.StringUtils; -import org.springframework.validation.BindException; -import org.springframework.validation.BindingResult; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.MissingServletRequestParameterException; -import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import com.easysoftware.domain.common.exception.ParamErrorException; -import com.easysoftware.domain.common.utils.HttpResult; - -import jakarta.validation.ConstraintViolationException; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; +import com.easysoftware.result.MessageCode; +import com.easysoftware.result.Result; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; -@Slf4j @RestControllerAdvice() public class GlobalExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); + @ExceptionHandler(MethodArgumentNotValidException.class) - public String handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { - BindingResult result = e.getBindingResult(); - if (!result.hasErrors()) { - return HttpResult.fail(HttpStatus.BAD_REQUEST.value(), "请求错误", null); - } - List errors = result.getAllErrors(); - // ViolationFieldError - for (ObjectError error : errors) { - log.error("未通过参数校验: {}", error.toString()); - } - return HttpResult.fail(HttpStatus.BAD_REQUEST.value(), "请求错误", null); + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity exception(MethodArgumentNotValidException e) { + logger.error(MessageCode.EC0001.getMsgEn(), e); + MessageCode messageCode = MessageCode.msgCodeMap.get(e.getMessage()); + return Result.fail(HttpStatus.BAD_REQUEST, messageCode); } - - } diff --git a/src/main/java/com/easysoftware/result/MessageCode.java b/src/main/java/com/easysoftware/result/MessageCode.java new file mode 100644 index 0000000..e8e54ef --- /dev/null +++ b/src/main/java/com/easysoftware/result/MessageCode.java @@ -0,0 +1,52 @@ +/* This project is licensed under the Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + PURPOSE. + See the Mulan PSL v2 for more details. + Create: 2024 +*/ + +package com.easysoftware.result; + +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + +public enum MessageCode { + // client exception + EC0001("EC0001", "Request Error", "请求异常"), + EC0005("EC0002", "Wrong parameter", "参数错误"), + EC0009("EC0003", "Unsupported community", "不支持该community"), + + // self service exception + ES0001("ES0001", "Internal Server Error", "服务异常"); + + + private final String code; + private final String msgEn; + private final String msgZh; + + MessageCode(String code, String msgEn, String msgZh) { + this.code = code; + this.msgEn = msgEn; + this.msgZh = msgZh; + } + + public String getCode() { + return code; + } + + public String getMsgEn() { + return msgEn; + } + + public String getMsgZh() { + return msgZh; + } + + public static final Map msgCodeMap = Arrays.stream(MessageCode.values()) + .collect(Collectors.toMap(MessageCode::getCode, e -> e)); +} diff --git a/src/main/java/com/easysoftware/result/Result.java b/src/main/java/com/easysoftware/result/Result.java new file mode 100644 index 0000000..da02e67 --- /dev/null +++ b/src/main/java/com/easysoftware/result/Result.java @@ -0,0 +1,123 @@ +/* This project is licensed under the Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + PURPOSE. + See the Mulan PSL v2 for more details. + Create: 2024 +*/ + +package com.easysoftware.result; + +import java.util.HashMap; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.easysoftware.vo.ResultMsgVo; +import com.easysoftware.vo.ResultVo; + + +public class Result { + public static ResponseEntity success(HttpStatus status) { + ResultVo res = new ResultVo() + .setCode(status.value()) + .setMsg(status.getReasonPhrase()); + return new ResponseEntity<>(res, status); + } + + public static ResponseEntity success(HttpStatus status, MessageCode msgCode) { + ResultVo res = new ResultVo() + .setCode(status.value()) + .setMsg(new ResultMsgVo() + .setCode(msgCode.getCode()) + .setMsgEn(msgCode.getMsgEn()) + .setMsgZh(msgCode.getMsgZh())); + return new ResponseEntity<>(res, status); + } + + public static ResponseEntity success(HttpStatus status, Object data) { + ResultVo res = new ResultVo() + .setCode(status.value()) + .setMsg(status.getReasonPhrase()) + .setData(data); + return new ResponseEntity<>(res, status); + } + + public static ResponseEntity fail(HttpStatus status, MessageCode msgCode) { + ResultVo res = new ResultVo() + .setCode(status.value()) + .setMsg(new ResultMsgVo() + .setCode(msgCode.getCode()) + .setMsgEn(msgCode.getMsgEn()) + .setMsgZh(msgCode.getMsgZh())); + return new ResponseEntity<>(res, status); + } + + public static ResponseEntity fail(HttpStatus status, MessageCode msgCode, String error) { + ResultVo res = new ResultVo() + .setCode(status.value()) + .setMsg(new ResultMsgVo() + .setCode(msgCode.getCode()) + .setMsgEn(msgCode.getMsgEn()) + .setMsgZh(msgCode.getMsgZh())) + .setError(error); + return new ResponseEntity<>(res, status); + } + + public static ResponseEntity setResult(HttpStatus status, MessageCode msgCode) { + HashMap res = new HashMap<>(); + if (status.value() == 200) { + res.put("code", status.value()); + res.put("msg", status.getReasonPhrase()); + return new ResponseEntity<>(res, status); + } + + if (msgCode != null) { + HashMap msgMap = new HashMap<>(); + msgMap.put("code", msgCode.getCode()); + msgMap.put("message_en", msgCode.getMsgEn()); + msgMap.put("message_zh", msgCode.getMsgZh()); + res.put("msg", msgMap); + } + return new ResponseEntity<>(res, status); + } + + public static ResponseEntity setResult(HttpStatus status, MessageCode msgCode, String error) { + HashMap res = new HashMap<>(); + if (status.value() == 200) { + res.put("code", status.value()); + res.put("msg", status.getReasonPhrase()); + res.put("error", error); + return new ResponseEntity<>(res, status); + } + + if (msgCode != null) { + HashMap msgMap = new HashMap<>(); + msgMap.put("code", msgCode.getCode()); + msgMap.put("message_en", msgCode.getMsgEn()); + msgMap.put("message_zh", msgCode.getMsgZh()); + res.put("msg", msgMap); + res.put("error", error); + } + return new ResponseEntity<>(res, status); + } + +/* public static ResponseEntity paramError(HttpStatus status, MessageCode msgCode, String parameter) { + ResultEntity res = new ResultEntity() + .setCode(status.value()) + .setMsg(new ResultMsgEntity() + .setCode(msgCode.getCode()) + .setMsgEn(msgCode.getMsgEn()) + .setMsgZh(msgCode.getMsgZh())) + .setError(); + return new ResponseEntity<>(res, status); + }*/ + + /*public static ResponseEntity paramError(String parameter) { + String error = MessageCode.EC0004.getMsgEn() + ": " + parameter; + return fail(HttpStatus.BAD_REQUEST, MessageCode.EC0004, error); + }*/ +} diff --git a/src/main/java/com/easysoftware/utils/ClientUtil.java b/src/main/java/com/easysoftware/utils/ClientUtil.java new file mode 100644 index 0000000..aaa33fe --- /dev/null +++ b/src/main/java/com/easysoftware/utils/ClientUtil.java @@ -0,0 +1,67 @@ +package com.easysoftware.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +public class ClientUtil { + private static final Logger logger = LoggerFactory.getLogger(ClientUtil.class); + + public static String getClientIpAddress(HttpServletRequest request) { + // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 + String headerName = "x-forwarded-for"; + String ip = request.getHeader(headerName); + if (null != ip && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { + // 多次反向代理后会有多个IP值,第一个IP才是真实IP,它们按照英文逗号','分割 + if (ip.indexOf(",") != -1) { + ip = ip.split(",")[0]; + } + } + if (checkIp(ip)) { + headerName = "Proxy-Client-IP"; + ip = request.getHeader(headerName); + } + if (checkIp(ip)) { + headerName = "WL-Proxy-Client-IP"; + ip = request.getHeader(headerName); + } + if (checkIp(ip)) { + headerName = "HTTP_CLIENT_IP"; + ip = request.getHeader(headerName); + } + if (checkIp(ip)) { + headerName = "HTTP_X_FORWARDED_FOR"; + ip = request.getHeader(headerName); + } + if (checkIp(ip)) { + headerName = "X-Real-IP"; + ip = request.getHeader(headerName); + } + if (checkIp(ip)) { + headerName = "remote addr"; + ip = request.getRemoteAddr(); + // 127.0.0.1 ipv4, 0:0:0:0:0:0:0:1 ipv6 + if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) { + // 根据网卡取本机配置的IP + InetAddress inet = null; + try { + inet = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + logger.error("get local host error: " + e.getMessage()); + } + ip = inet.getHostAddress(); + } + } + return ip; + } + + private static boolean checkIp(String ip) { + if (null == ip || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + return true; + } + return false; + } +} diff --git a/src/main/java/com/easysoftware/utils/LogUtil.java b/src/main/java/com/easysoftware/utils/LogUtil.java new file mode 100644 index 0000000..ad3464c --- /dev/null +++ b/src/main/java/com/easysoftware/utils/LogUtil.java @@ -0,0 +1,56 @@ +package com.easysoftware.utils; + +import com.easysoftware.vo.ManagementLog; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.aspectj.lang.JoinPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.SneakyThrows; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; + +public class LogUtil { + private static final Logger logger = LoggerFactory.getLogger(LogUtil.class); + private static ObjectMapper objectMapper = new ObjectMapper(); + + @SneakyThrows + public static void managementOperate(JoinPoint joinPoint, HttpServletRequest request, HttpServletResponse response, + Object returnObject) { + ManagementLog log = new ManagementLog(); + log.setType("OmOperate"); + + LocalDateTime dateTime = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + log.setTime(dateTime.format(formatter)); + + log.setFunc(String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName(), + joinPoint.getSignature().getName())); + + log.setRequestUrl(request.getRequestURI()); + log.setMethod(request.getMethod()); + + log.setAppIP(ClientUtil.getClientIpAddress(request)); + + if (returnObject instanceof ResponseEntity) { + ResponseEntity responseEntity = (ResponseEntity) returnObject; + log.setStatus(responseEntity.getStatusCodeValue()); + if (responseEntity.getBody() instanceof HashMap) { + HashMap body = (HashMap) responseEntity.getBody(); + Object msg = (body.get("msg") == null) ? body.get("message") : body.get("msg"); + log.setMessage((msg == null) ? "" : msg.toString()); + } + } + log.setOperator(""); + + String jsonLog = objectMapper.writeValueAsString(log); + logger.info("operationLog:{}", jsonLog); + } + +} \ No newline at end of file diff --git a/src/main/java/com/easysoftware/vo/ManagementLog.java b/src/main/java/com/easysoftware/vo/ManagementLog.java new file mode 100644 index 0000000..55a5543 --- /dev/null +++ b/src/main/java/com/easysoftware/vo/ManagementLog.java @@ -0,0 +1,24 @@ +package com.easysoftware.vo; + +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +@Getter +@Setter +public class ManagementLog implements Serializable { + private static final long serialVersionUID = 1L; + private String type; + private String time; + private String func; + private String eventDetails; + private String requestUrl; + private String method; + private String appIP; + private int status; + private String message; + private String ErrorLog; + private String operator; +} + diff --git a/src/main/java/com/easysoftware/vo/ResultMsgVo.java b/src/main/java/com/easysoftware/vo/ResultMsgVo.java new file mode 100644 index 0000000..b7ae5ea --- /dev/null +++ b/src/main/java/com/easysoftware/vo/ResultMsgVo.java @@ -0,0 +1,21 @@ +package com.easysoftware.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Data +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ResultMsgVo implements Serializable { + private String code; + + @JsonProperty("message_en") + private String msgEn; + + @JsonProperty("message_zh") + private String msgZh; +} diff --git a/src/main/java/com/easysoftware/vo/ResultVo.java b/src/main/java/com/easysoftware/vo/ResultVo.java new file mode 100644 index 0000000..e7e736e --- /dev/null +++ b/src/main/java/com/easysoftware/vo/ResultVo.java @@ -0,0 +1,17 @@ +package com.easysoftware.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Data +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ResultVo implements Serializable { + private int code; + private Object msg; + private Object data; + private String error; +} -- Gitee From 014ab14f183d82f33dcd48438b7e037dadfffd6e Mon Sep 17 00:00:00 2001 From: kaede10 Date: Wed, 21 Feb 2024 11:25:28 +0800 Subject: [PATCH 2/2] update pom.xml format --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 810abba..6e2715f 100644 --- a/pom.xml +++ b/pom.xml @@ -28,9 +28,9 @@ - org.springframework.boot - spring-boot-starter-aop - + org.springframework.boot + spring-boot-starter-aop + org.projectlombok -- Gitee