Sunday 3 months ago
commit
eac3f30ba6

+ 33 - 0
day01/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 108 - 0
day01/pom.xml

@@ -0,0 +1,108 @@
+<?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>
+    <groupId>com.zhentao</groupId>
+    <artifactId>day01</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>day01</name>
+    <description>day01</description>
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <spring-boot.version>2.6.13</spring-boot.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- Spring Boot 验证启动器,用于参数验证 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <version>3.2.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.16</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>2.0.31</version>
+        </dependency>
+    </dependencies>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <configuration>
+                    <mainClass>com.zhentao.Day01Application</mainClass>
+                    <skip>false</skip>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 97 - 0
day01/src/main/java/com/zhentao/Day01Application.java

@@ -0,0 +1,97 @@
+package com.zhentao;
+
+import com.zhentao.service.TestService;
+import com.zhentao.service.impl.TestServiceImpl;
+import com.zhentao.util.HttpUtils;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@SpringBootApplication
+public class Day01Application {
+    static TestService signService = new TestServiceImpl();
+    public static void main(String[] args) {
+        SpringApplication.run(Day01Application.class, args);
+
+
+
+
+
+
+        // 接口一的请求参数   post请求
+        Map<String, Object> requestParams1 = new HashMap<>();
+        requestParams1.put("appId", "123");
+        requestParams1.put("goodsId", "456");
+        requestParams1.put("reqTime", 1111L);
+        requestParams1.put("amount", 1);
+        requestParams1.put("price", 10.00);
+        requestParams1.put("mobile", "13800138000");
+        requestParams1.put("reqId", "789");
+
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Date nowDate = sdf.parse("2020-02-03");
+            requestParams1.put("nowDate", nowDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        // 生成签名
+        String sign1 = signService.generateSign(requestParams1);
+        requestParams1.put("sign", sign1);
+
+        // 调用接口一
+        String url1 = "http://localhost:8080/test/postApi";
+        String reqId = "789";
+        HttpUtils.callInterface(url1, requestParams1, reqId);
+        System.err.println("post请求");
+
+
+
+
+
+
+
+
+
+
+
+
+//get请求
+        // 接口二的请求参数
+        Map<String, Object> requestParams2 = new HashMap<>();
+        requestParams2.put("appId", "123");
+        requestParams2.put("goodsId", "456");
+        requestParams2.put("reqTime", 1111L);
+        requestParams2.put("amount", 1);
+        requestParams2.put("price", 10.00);
+        requestParams2.put("mobile", "13800138000");
+        requestParams2.put("reqId", "789");
+
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Date nowDate = sdf.parse("2020-02-03");
+            // 由于实体类中 nowDate 为 String 类型,这里将 Date 转为 String
+            requestParams2.put("nowDate", sdf.format(nowDate));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        // 生成签名
+        String sign2 = signService.generateSign(requestParams2);
+        requestParams2.put("sign", sign2);
+
+        // 调用接口二
+        String url2 = "http://localhost:8080/test/getApi";
+        String reqId2 = "789";
+        HttpUtils.callGetInterface(url2, requestParams2, reqId2);
+        System.err.println("get请求");
+    }
+
+
+}

+ 66 - 0
day01/src/main/java/com/zhentao/controller/TestController.java

@@ -0,0 +1,66 @@
+package com.zhentao.controller;
+
+import com.zhentao.pojo.Test;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("test")
+@Validated
+public class TestController {
+
+    // 定义一个 POST 请求的接口
+    @PostMapping("/postApi")
+    public ResponseEntity<Map<String, Object>> postApi(
+            // 从请求头中获取 reqId
+            @RequestHeader("reqId") String reqId,
+            // 验证请求体中的参数,并将其封装到 RequestParams 对象中
+            @Valid @RequestBody Test params,
+            // 用于存储验证结果
+            BindingResult bindingResult) {
+        // 用于存储响应数据
+        Map<String, Object> response = new HashMap<>();
+        // 检查是否有验证错误
+        if (bindingResult.hasErrors()) {
+            response.put("status", "error");
+            // 获取第一个验证错误的消息
+            response.put("message", bindingResult.getAllErrors().get(0).getDefaultMessage());
+            return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
+        }
+        response.put("status", "success");
+        response.put("data", params);
+        return new ResponseEntity<>(response, HttpStatus.OK);
+    }
+
+    // 定义一个 GET 请求的接口
+    @GetMapping("/getApi")
+    public ResponseEntity<Map<String, Object>> getApi(
+            // 从请求头中获取 reqId
+            @RequestHeader("reqId") String reqId,
+            // 验证请求参数,并将其封装到 RequestParams 对象中
+            @Valid Test params,
+            // 用于存储验证结果
+            BindingResult bindingResult) {
+        // 用于存储响应数据
+        Map<String, Object> response = new HashMap<>();
+        // 检查是否有验证错误
+        if (bindingResult.hasErrors()) {
+            response.put("status", "error");
+            // 获取第一个验证错误的消息
+            response.put("message", bindingResult.getAllErrors().get(0).getDefaultMessage());
+            return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
+        }
+        response.put("status", "success");
+        response.put("data", params);
+        return new ResponseEntity<>(response, HttpStatus.OK);
+    }
+
+
+}

+ 45 - 0
day01/src/main/java/com/zhentao/pojo/Test.java

@@ -0,0 +1,45 @@
+package com.zhentao.pojo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.*;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Test {
+    // 验证 appId 不能为空
+    @NotBlank(message = "appId 不能为空")
+    private String appId;
+    // 验证 reqTime 不能为空
+    @NotNull(message = "reqTime 不能为空")
+    private Long reqTime;
+    // 验证 goodsId 不能为空
+    @NotBlank(message = "goodsId 不能为空")
+    private String goodsId;
+    // 验证 amount 不能为空且不能小于 0
+    @NotNull(message = "amount 不能为空")
+    @Min(value = 0, message = "amount 不能小于 0")
+    private Integer amount;
+    // 验证 price 不能为空,且范围在 0 到 9999 之间
+    @NotNull(message = "price 不能为空")
+    @Min(value = 0, message = "price 不能小于 0")
+    @Max(value = 9999, message = "price 不能大于 9999")
+    private Double price;
+    // 验证 mobile 不能为空,且必须符合手机号格式
+    @NotBlank(message = "mobile 不能为空")
+    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
+    private String mobile;
+    // 验证 nowDate 不能为空
+    @NotNull(message = "nowDate 不能为空")
+//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8",shape = JsonFormat.Shape.STRING)
+//    private Date nowDate;//post
+//    @NotNull(message = "nowDate 不能为空")
+    private String nowDate;//get
+}

+ 20 - 0
day01/src/main/java/com/zhentao/service/TestService.java

@@ -0,0 +1,20 @@
+package com.zhentao.service;
+
+import java.util.Map;
+// 签名服务接口,定义签名相关的操作
+public interface TestService {
+    /**
+     * 生成签名
+     * @param params 请求参数
+     * @return 签名
+     */
+    String generateSign(Map<String, Object> params);
+
+    /**
+     * 验证签名
+     * @param params 请求参数
+     * @param sign 传入的签名
+     * @return 签名是否有效
+     */
+    boolean verifySign(Map<String, Object> params, String sign);
+}

+ 32 - 0
day01/src/main/java/com/zhentao/service/impl/TestServiceImpl.java

@@ -0,0 +1,32 @@
+package com.zhentao.service.impl;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import com.zhentao.service.TestService;
+
+import java.util.Map;
+// 签名服务接口的实现类,实现具体的签名生成和验证逻辑
+public class TestServiceImpl implements TestService {
+    // 假设的 appKey
+    private static final String APP_KEY = "789";
+
+    @Override
+    public String generateSign(Map<String, Object> params) {
+        String appId = String.valueOf(params.get("appId"));
+        String goodsId = String.valueOf(params.get("goodsId"));
+        String reqId = String.valueOf(params.get("reqId"));
+        String reqTime = String.valueOf(params.get("reqTime"));
+        String amount = String.valueOf(params.get("amount"));
+        String price = String.valueOf(params.get("price"));
+        String mobile = String.valueOf(params.get("mobile"));
+        String nowDate = String.valueOf(params.get("nowDate"));
+
+        String signStr = appId + goodsId + reqId + reqTime + amount + price + mobile + nowDate + APP_KEY;
+        return DigestUtil.md5Hex(signStr);
+    }
+
+    @Override
+    public boolean verifySign(Map<String, Object> params, String sign) {
+        String generatedSign = generateSign(params);
+        return generatedSign.equals(sign);
+    }
+}

+ 66 - 0
day01/src/main/java/com/zhentao/util/HttpUtils.java

@@ -0,0 +1,66 @@
+package com.zhentao.util;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSONObject;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+// HTTP 客户端工具类,负责发送 HTTP 请求
+public class HttpUtils {
+    /**
+     * 调用接口
+     *
+     * @param url    接口地址
+     * @param params 请求参数
+     * @param reqId
+     */
+    public static void callInterface(String url, Map<String, Object> params, String reqId) {
+        try {
+            String jsonParams = JSONObject.toJSONString(params);
+            HttpResponse response = HttpRequest.post(url)
+                    .header("reqId", reqId) // 设置请求头
+                    .body(jsonParams)
+                    .execute();
+
+            if (response.isOk()) {
+                System.out.println("接口调用成功,响应结果:" + response.body());
+            } else {
+                System.err.println("接口调用失败,状态码:" + response.getStatus());
+            }
+        } catch (Exception e) {
+            System.err.println("接口调用过程中出现异常:" + e.getMessage());
+        }
+    }
+
+
+
+    /**
+     * 调用 GET 接口
+     *
+     * @param url    接口地址
+     * @param params 请求参数
+     * @param reqId
+     */
+    public static void callGetInterface(String url, Map<String, Object> params, String reqId) {
+        try {
+            // 将请求参数拼接到 URL 后面
+            String queryString = params.entrySet().stream()
+                    .map(entry -> entry.getKey() + "=" + entry.getValue())
+                    .collect(Collectors.joining("&"));
+            String fullUrl = url + "?" + queryString;
+
+            HttpResponse response = HttpRequest.get(fullUrl)
+                    .header("reqId", reqId) // 设置请求头
+                    .execute();
+
+            if (response.isOk()) {
+                System.out.println("接口调用成功,响应结果:" + response.body());
+            } else {
+                System.err.println("接口调用失败,状态码:" + response.getStatus());
+            }
+        } catch (Exception e) {
+            System.err.println("接口调用过程中出现异常:" + e.getMessage());
+        }
+    }
+}

+ 2 - 0
day01/src/main/resources/application.yml

@@ -0,0 +1,2 @@
+server:
+  port: 8080

+ 91 - 0
day01/src/test/java/com/zhentao/Day01ApplicationTests.java

@@ -0,0 +1,91 @@
+package com.zhentao;
+
+
+import com.zhentao.service.TestService;
+import com.zhentao.service.impl.TestServiceImpl;
+import com.zhentao.util.HttpUtils;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@SpringBootTest
+class Day01ApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+    public static void main(String[] args) {
+        TestService signService = new TestServiceImpl();
+
+        // 接口一的请求参数   post请求
+//        Map<String, Object> requestParams1 = new HashMap<>();
+//        requestParams1.put("appId", "123");
+//        requestParams1.put("goodsId", "456");
+//        requestParams1.put("reqTime", 1111L);
+//        requestParams1.put("amount", 1);
+//        requestParams1.put("price", 10.00);
+//        requestParams1.put("mobile", "13800138000");
+//        requestParams1.put("reqId", "789");
+//
+//        try {
+//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+//            Date nowDate = sdf.parse("2020-02-03");
+//            requestParams1.put("nowDate", nowDate);
+//        } catch (ParseException e) {
+//            e.printStackTrace();
+//        }
+//
+//        // 生成签名
+//        String sign1 = signService.generateSign(requestParams1);
+//        requestParams1.put("sign", sign1);
+//
+//        // 调用接口一
+//        String url1 = "http://localhost:8080/test/postApi";
+//        String reqId = "789";
+//        HttpUtils.callInterface(url1, requestParams1, reqId);
+//    }
+
+
+
+
+
+
+        //get请求
+
+        // 接口二的请求参数
+        Map<String, Object> requestParams2 = new HashMap<>();
+        requestParams2.put("appId", "123");
+        requestParams2.put("goodsId", "456");
+        requestParams2.put("reqTime", 1111L);
+        requestParams2.put("amount", 1);
+        requestParams2.put("price", 10.00);
+        requestParams2.put("mobile", "13800138000");
+        requestParams2.put("reqId", "789");
+
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Date nowDate = sdf.parse("2020-02-03");
+            // 由于实体类中 nowDate 为 String 类型,这里将 Date 转为 String
+            requestParams2.put("nowDate", sdf.format(nowDate));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        // 生成签名
+        String sign2 = signService.generateSign(requestParams2);
+        requestParams2.put("sign", sign2);
+
+        // 调用接口二
+        String url2 = "http://localhost:8080/test/getApi";
+        String reqId = "789";
+        HttpUtils.callGetInterface(url2, requestParams2, reqId);
+
+
+    }
+}