Browse Source

feat: 接口添加参数校验

weijianghai 2 years ago
parent
commit
5782a79c43

+ 4 - 0
sms_blk_api/pom.xml

@@ -26,6 +26,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-aop</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>

+ 8 - 0
sms_blk_api/src/main/java/com/nokia/common/http/R.java

@@ -45,6 +45,14 @@ public class R {
         return r;
     }
 
+    public static R error(String message) {
+        R r = new R();
+        r.setSuccess(false);
+        r.setCode(500);
+        r.setMessage(message);
+        return r;
+    }
+
     public R success(Boolean success) {
         this.setSuccess(success);
         return this;

+ 48 - 2
sms_blk_api/src/main/java/com/nokia/sms/config/ControllerExceptionHandler.java

@@ -4,9 +4,15 @@ import com.nokia.common.http.R;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.validation.BindException;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
+import javax.validation.ConstraintViolationException;
+
 /**
  * 请求异常处理
  */
@@ -14,9 +20,49 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
 @RestControllerAdvice
 public class ControllerExceptionHandler
 {
-    @SuppressWarnings("rawtypes")
+    @ExceptionHandler(HttpMessageNotReadableException.class)
+    public ResponseEntity<Object> httpMessageNotReadableExceptionValidatorHandler(HttpMessageNotReadableException e)
+    {
+        log.warn("╭( ′• o •′ )╭☞ 请求参数校验未通过: {}", e.getMessage());
+        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(R.error(e.getMessage()));
+    }
+
+    @ExceptionHandler(BindException.class)
+    public ResponseEntity<Object> bindExceptionValidatorHandler(BindException e)
+    {
+        FieldError fieldError = e.getBindingResult().getFieldError();
+        String message = "";
+        if (fieldError != null)
+        {
+            message = fieldError.getDefaultMessage();
+            log.warn("╭( ′• o •′ )╭☞ 请求参数校验未通过: {}", message);
+        }
+        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(R.error(message));
+    }
+
+    @ExceptionHandler(ConstraintViolationException.class)
+    public ResponseEntity<Object> constraintViolationExceptionValidatorHandler(ConstraintViolationException e)
+    {
+        String message = e.getConstraintViolations().iterator().next().getMessage();
+        log.warn("╭( ′• o •′ )╭☞ 请求参数校验未通过: {}", message);
+        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(R.error(message));
+    }
+
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public ResponseEntity<Object> methodArgumentNotValidExceptionValidatorHandler(MethodArgumentNotValidException e)
+    {
+        FieldError fieldError = e.getBindingResult().getFieldError();
+        String message = "";
+        if (fieldError != null)
+        {
+            message = fieldError.getDefaultMessage();
+            log.warn("╭( ′• o •′ )╭☞ 请求参数校验未通过: {}", message);
+        }
+        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(R.error(message));
+    }
+    
     @ExceptionHandler({Exception.class})
-    public ResponseEntity exceptionHandler(Exception e)
+    public ResponseEntity<R> exceptionHandler(Exception e)
     {
         log.error("╭( ′• o •′ )╭☞ 发生错误了 {}", e.getMessage(), e);
         return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(R.error());

+ 47 - 15
sms_blk_api/src/main/java/com/nokia/sms/config/LogAspectConfig.java

@@ -1,6 +1,6 @@
 package com.nokia.sms.config;
 
-import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson.JSON;
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -9,6 +9,7 @@ import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Before;
 import org.aspectj.lang.annotation.Pointcut;
 import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
 import org.springframework.util.StopWatch;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
@@ -17,22 +18,50 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
- * 日志切面
+ * 日志配置
+ *
+ * @author weijianghai
  */
 @Aspect
 @Component
 @Slf4j
 public class LogAspectConfig
 {
+    @Pointcut("execution(* com.nokia..ControllerExceptionHandler.*ValidatorHandler(..))")
+    public void validatorExceptionHandlerPointcut()
+    {
+        // Pointcut
+    }
+
     @Pointcut("execution(public * com.nokia..*Controller.*(..))")
     public void controllerPointcut()
     {
         // Pointcut
     }
 
-    @Before("controllerPointcut()")
+    @Pointcut("execution(* com.nokia..ControllerExceptionHandler.*(..))")
+    public void controllerExceptionHandlerPointcut()
+    {
+        // Pointcut
+    }
+
+    @Pointcut("controllerPointcut() || validatorExceptionHandlerPointcut()")
+    public void beforePointCut()
+    {
+        // Pointcut
+    }
+
+    @Pointcut("controllerPointcut() || controllerExceptionHandlerPointcut()")
+    public void afterPointCut()
+    {
+        // Pointcut
+    }
+
+    @Before("beforePointCut()")
     public void doBefore(JoinPoint joinPoint)
     {
         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
@@ -41,25 +70,28 @@ public class LogAspectConfig
             return;
         }
         HttpServletRequest request = attributes.getRequest();
+        // 打印请求信息
         log.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
+        // 打印请求参数
         Object[] args = joinPoint.getArgs();
-        Object[] arguments = new Object[args.length];
-        for (int i = 0; i < args.length; i++)
-        {
-            if (args[i] instanceof ServletRequest
-                    || args[i] instanceof ServletResponse
-                    || args[i] instanceof MultipartFile
-                    || args[i] instanceof Exception
-            )
-            {
+        List<Object> list = new ArrayList<>();
+        for (Object arg : args) {
+            if (arg instanceof ServletRequest
+                    || arg instanceof ServletResponse
+                    || arg instanceof MultipartFile
+                    || arg instanceof Exception
+            ) {
                 continue;
             }
-            arguments[i] = args[i];
+            list.add(arg);
+        }
+        if (CollectionUtils.isEmpty(list)) {
+            return;
         }
-        log.info("入参: {}", JSON.toJSONString(arguments));
+        log.info("请求参数: {}", JSON.toJSONString(list));
     }
 
-    @Around("controllerPointcut()")
+    @Around("afterPointCut()")
     public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
     {
         StopWatch stopWatch = new StopWatch();

+ 27 - 0
sms_blk_api/src/main/java/com/nokia/sms/config/ValidatorConfig.java

@@ -0,0 +1,27 @@
+package com.nokia.sms.config;
+
+import org.hibernate.validator.HibernateValidator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+/**
+ * 校验配置
+ *
+ * @author weijianghai
+ */
+@Configuration
+public class ValidatorConfig
+{
+    @Bean
+    public Validator validator()
+    {
+        try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
+                .failFast(true).buildValidatorFactory()) {
+            return validatorFactory.getValidator();
+        }
+    }
+}

+ 5 - 3
sms_blk_api/src/main/java/com/nokia/sms/controller/BlkController.java

@@ -4,6 +4,7 @@ import com.nokia.common.http.R;
 import com.nokia.sms.service.QueryService;
 import com.nokia.sms.service.SocketClientService;
 import com.nokia.sms.vo.DelBlkResp;
+import com.nokia.sms.vo.QueryDTO;
 import com.nokia.sms.vo.QueryResp;
 import com.nokia.sms.vo.RequestParams;
 import org.springframework.util.CollectionUtils;
@@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.validation.Valid;
 import java.util.Map;
 
 /**
@@ -32,7 +34,7 @@ public class BlkController {
      * 黑名单解除接口
      */
     @PostMapping("remove")
-    public R remove(@RequestBody RequestParams params) {
+    public R remove(@Valid @RequestBody RequestParams params) {
         DelBlkResp delBlkResp = new DelBlkResp();
         // 查询黑名单
         Map<String, Object> current = queryService.getBlackListInfo(params.getPhone());
@@ -45,7 +47,7 @@ public class BlkController {
         // 尝试解除黑名单
         // TODO 此处测试环境和正式环境不同,待测试环境下的server部署后,可以修改测试环境的配置文件,即可考虑测试环境和正式环境部署相同的jar包
         if (socketClientService.delBlk(params.getPhone())) {
-            // if (params.getPhone().equals("13231899751")) {
+//             if (params.getPhone().equals("13231899751")) {
             delBlkResp.setDelBlkSuccess(true);
             delBlkResp.setDelBlkMessage("成功解除黑名单");
         } else {
@@ -59,7 +61,7 @@ public class BlkController {
      * 黑名单查询接口
      */
     @PostMapping("query")
-    public R query(@RequestBody RequestParams params) {
+    public R query(@Valid @RequestBody QueryDTO params) {
         QueryResp resp = queryService.query(params);
         return R.ok().data(resp);
     }

+ 2 - 2
sms_blk_api/src/main/java/com/nokia/sms/service/QueryService.java

@@ -1,7 +1,7 @@
 package com.nokia.sms.service;
 
+import com.nokia.sms.vo.QueryDTO;
 import com.nokia.sms.vo.QueryResp;
-import com.nokia.sms.vo.RequestParams;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
@@ -18,7 +18,7 @@ public class QueryService {
         this.jdbcTemplate = jdbcTemplate;
     }
 
-    public QueryResp query(RequestParams params) {
+    public QueryResp query(QueryDTO params) {
         Map<String, Object> map = getBlackListInfo(params.getPhone());
         QueryResp r = new QueryResp();
         r.setQuerySuccess(false);

+ 13 - 0
sms_blk_api/src/main/java/com/nokia/sms/vo/QueryDTO.java

@@ -0,0 +1,13 @@
+package com.nokia.sms.vo;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class QueryDTO {
+    @NotBlank(message = "phone不能为空")
+    private String phone;
+    @NotBlank(message = "fromSystem不能为空")
+    private String fromSystem;
+}

+ 5 - 0
sms_blk_api/src/main/java/com/nokia/sms/vo/RequestParams.java

@@ -2,9 +2,14 @@ package com.nokia.sms.vo;
 
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+
 @Data
 public class RequestParams {
+    @NotBlank(message = "phone不能为空")
     private String phone;
+    @NotBlank(message = "fromSystem不能为空")
     private String fromSystem;
+    @NotBlank(message = "operator不能为空")
     private String operator;
 }

+ 0 - 1
sms_blk_api/src/main/resources/application.properties

@@ -4,4 +4,3 @@ logging.level.com.nokia=debug
 spring.datasource.url=jdbc:postgresql://192.168.10.54:5432/sqmmt
 spring.datasource.username=sms_blk
 spring.datasource.password=Sms@Richr00t
-spring.datasource.driverClassName=org.postgresql.Driver

+ 58 - 18
sms_blk_interface/src/test/java/com/nokia/sms/SyncTest.java

@@ -8,7 +8,6 @@ import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.util.CollectionUtils;
 
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
@@ -25,28 +24,60 @@ import java.util.stream.Stream;
 @Slf4j
 @SpringBootTest
 class SyncTest {
+    public static final String TEST_DIR = "test/";
     @Autowired
     private JdbcTemplate jdbcTemplate;
 
+    @Test
+    void testBlack() {
+        String p1 = TEST_DIR + "blacklist.csv";
+        String result = TEST_DIR + "black.csv";
+        try (CsvReader csvReader = CsvReader.builder().build(Paths.get(p1), StandardCharsets.UTF_8);
+             OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(Paths.get(result)),
+                     StandardCharsets.UTF_8);
+             CsvWriter csvWriter = CsvWriter.builder().build(osw);) {
+            for (CsvRow row : csvReader) {
+                if ("2".equals(row.getField(5))) {
+                    continue;
+                }
+
+                csvWriter.writeRow(row.getFields());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
     @Test
     void test() {
         Map<String, Map<String, String>> m1 = new HashMap<>();
         Map<String, Map<String, String>> m2 = new HashMap<>();
-        String p1 = "z:/blacklist_202208231737.csv";
-        String p2 = "z:/data1.csv";
-        String result = "z:/result2.csv";
+        String p1 = TEST_DIR + "data.csv";
+        String p2 = TEST_DIR + "black.csv";
+//        String p2 = TEST_DIR + "blacklist.csv";
+        String result = TEST_DIR + "result2.csv";
         try {
-            try (CsvReader csvReader = CsvReader.builder().build(Paths.get(p2), StandardCharsets.UTF_8)) {
+            try (CsvReader csvReader = CsvReader.builder().build(Paths.get(p1), StandardCharsets.UTF_8)) {
                 for (CsvRow row : csvReader) {
+                    if (row.getOriginalLineNumber() == 1) {
+                        continue;
+                    }
+
                     m1.put(row.getField(0), new HashMap<String, String>() {{
                         put("phone", row.getField(0));
                         put("reason", row.getField(1));
-                        put("suggestion", row.getField(2));
+                        put("start_time", row.getField(2));
+                        put("end_time", row.getField(3));
+                        put("suggestion", row.getField(4));
                     }});
                 }
             }
-            try (CsvReader csvReader = CsvReader.builder().build(Paths.get(p1), StandardCharsets.UTF_8)) {
+            try (CsvReader csvReader = CsvReader.builder().build(Paths.get(p2), StandardCharsets.UTF_8)) {
                 for (CsvRow row : csvReader) {
+                    if (row.getOriginalLineNumber() == 1) {
+                        continue;
+                    }
+
                     m2.put(row.getField(0), new HashMap<String, String>() {{
                         put("phone", row.getField(0));
                         put("reason", row.getField(1));
@@ -61,27 +92,36 @@ class SyncTest {
             try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(Paths.get(result)),
                     StandardCharsets.UTF_8);
                  CsvWriter csvWriter = CsvWriter.builder().build(osw);) {
-                csvWriter.writeRow("黑名单号码", "入黑名单原因", "解黑建议", "是否一致", "入黑名单原因", "解黑建议", "开始时间", "结束时间", "命中策略说明", "操作类型");
+                csvWriter.writeRow("黑名单号码", "入黑名单原因", "开始时间", "结束时间", "解黑建议", "是否一致", "入黑名单原因", "解黑建议", "开始时间", "结束时间", "命中策略说明", "操作类型");
                 for (Map<String, String> v2 : m2.values()) {
                     String phone = v2.get("phone");
                     Map<String, String> v1 = m1.getOrDefault(phone, new HashMap<>());
+//                    if (CollectionUtils.isEmpty(v1) && "2".equals(v2.get("operation_type"))) {
+//                        continue;
+//                    }
+
                     String flag = "是";
-                    if (!v2.get("reason").equals(v1.get("reason")) || !v2.get("suggestion").equals(v1.get("suggestion"))) {
+                    if (!v2.get("reason").equals(v1.get("reason"))
+                            || !v2.get("start_time").equals(v1.get("start_time"))
+                            || !v2.get("end_time").equals(v1.get("end_time"))
+                            || !v2.get("suggestion").equals(v1.get("suggestion"))
+                    ) {
                         flag = "否";
-                        if (CollectionUtils.isEmpty(v1) && v2.get("operation_type").equals("1")) {
-                            System.out.println(">>>>>>>>>>" + phone);
-                        }
                     }
-                    csvWriter.writeRow(phone, v1.get("reason"), v1.get("suggestion"), flag, v2.get("reason"), v2.get("suggestion"), v2.get("start_time"), v2.get("end_time"), v2.get("hit_desc"), v2.get("operation_type"));
+                    csvWriter.writeRow(phone, v1.get("reason"), v1.get("suggestion"), v1.get("start_time"), v1.get("end_time"), flag, v2.get("reason"), v2.get("suggestion"), v2.get("start_time"), v2.get("end_time"), v2.get("hit_desc"), v2.get("operation_type"));
                 }
 //                for (Map<String, String> v1 : m1.values()) {
 //                    String phone = v1.get("phone");
 //                    Map<String, String> v2 = m2.getOrDefault(phone, new HashMap<>());
 //                    String flag = "是";
-//                    if (!v1.get("reason").equals(v2.get("reason")) || !v1.get("suggestion").equals(v2.get("suggestion"))) {
+//                    if (!v1.get("reason").equals(v2.get("reason"))
+//                            || !v1.get("start_time").equals(v2.get("start_time"))
+//                            || !v1.get("end_time").equals(v2.get("end_time"))
+//                            || !v1.get("suggestion").equals(v2.get("suggestion"))
+//                    ) {
 //                        flag = "否";
 //                    }
-//                    csvWriter.writeRow(phone, v1.get("reason"), v1.get("suggestion"), flag, v2.get("reason"), v2.get("suggestion"), v2.get("start_time"), v2.get("end_time"), v2.get("hit_desc"), v2.get("operation_type"));
+//                    csvWriter.writeRow(phone, v1.get("reason"), v1.get("suggestion"), v1.get("start_time"), v1.get("end_time"), flag, v2.get("reason"), v2.get("suggestion"), v2.get("start_time"), v2.get("end_time"), v2.get("hit_desc"), v2.get("operation_type"));
 //                }
             }
         } catch (Exception e) {
@@ -94,7 +134,7 @@ class SyncTest {
      */
     @Test
     void testImport() {
-        String path = "z:/download";
+        String path = TEST_DIR + "download";
         // 读取目标文件夹下的文件
         try (Stream<Path> stream = Files.list(Paths.get(path))) {
             List<Path> pathList = stream.collect(Collectors.toList());
@@ -105,7 +145,7 @@ class SyncTest {
                 log.info("file: {}", t.getFileName().toString());
                 try (CsvReader csvReader = CsvReader.builder().build(t, StandardCharsets.UTF_8)) {
                     for (CsvRow row : csvReader) {
-                        Object[] o1 = new Object[] {
+                        Object[] o1 = new Object[]{
                                 row.getField(0),
                                 Integer.valueOf(row.getField(1)),
                                 row.getField(2),
@@ -115,7 +155,7 @@ class SyncTest {
                                 Integer.valueOf(row.getField(6)),
                         };
                         l1.add(o1);
-                        Object[] o2 = new Object[] {
+                        Object[] o2 = new Object[]{
                                 row.getField(0),
                                 Integer.valueOf(row.getField(1)),
                                 row.getField(2),