dengsixing 3 年之前
当前提交
770ed88810

+ 38 - 0
.gitignore

@@ -0,0 +1,38 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+/**/target/
+out
+gen
+
+/4dkankan-pom/src/test/java/TestAutoGenerate.java
+

+ 95 - 0
pom.xml

@@ -0,0 +1,95 @@
+<?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.fdkankan</groupId>
+    <artifactId>4dkankan-mvp</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <repositories>
+        <repository>
+            <id>releases</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+        </repository>
+        <repository>
+            <id>nexus-aliyun</id>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+        </repository>
+        <repository>
+            <id>snapshots</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+        </repository>
+    </repositories>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <fastjson-version>1.2.83</fastjson-version>
+        <hutool-version>5.7.17</hutool-version>
+        <spring.cloud-version>Hoxton.SR8</spring.cloud-version>
+        <servlet-api-version>2.4</servlet-api-version>
+        <shiro.version>1.7.1</shiro.version>
+        <spring.plugin.metadata-version>1.2.0.RELEASE</spring.plugin.metadata-version>
+        <lombok-version>1.18.20</lombok-version>
+        <forest-version>1.5.19</forest-version>
+        <fastjson-version>1.2.83</fastjson-version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.dtflys.forest</groupId>
+            <artifactId>forest-core</artifactId>
+            <version>1.5.26</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson-version}</version>
+        </dependency>
+
+    </dependencies>
+
+
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.8.1</version>
+                    <configuration>
+                        <source>8</source>
+                        <target>8</target>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <distributionManagement>
+        <repository>
+            <!-- 这里的ID要和setting的id一致 -->
+            <id>releases</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+        </repository>
+        <!--这是打成快照版本的配置 -->
+        <snapshotRepository>
+            <id>snapshots</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+</project>

+ 25 - 0
src/main/java/com/fdkankan/mvp/bean/ResultData.java

@@ -0,0 +1,25 @@
+package com.fdkankan.mvp.bean;
+
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResultData<T> implements Serializable {
+    /**
+     * 状态码
+     */
+    private int code;
+    /**
+     * 响应信息
+     */
+    private String msg;
+    /**
+     * 后端返回结果
+     */
+    private T data;
+
+}

+ 36 - 0
src/main/java/com/fdkankan/mvp/bean/WvpServerInfo.java

@@ -0,0 +1,36 @@
+package com.fdkankan.mvp.bean;
+
+import com.fdkankan.mvp.device.DeviceUtil;
+import com.fdkankan.mvp.factory.InstanceFactory;
+import com.fdkankan.mvp.streamProxy.StreamProxyUtil;
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/8/31
+ **/
+@Data
+public class WvpServerInfo {
+
+    private String scheme;
+
+    private String ip;
+
+    private String port;
+
+    private String address;
+
+
+    public static void main(String[] args) {
+        WvpServerInfo info = InstanceFactory.initMvpServer("192.168.0.211", "18080");
+//        ResultData sip = SipServerUtil.getSipServerConfig();
+        ResultData resultData = DeviceUtil.listChannel("34020000001000000001",null, 1, 10);
+        System.out.println(123);
+    }
+
+
+}

+ 35 - 0
src/main/java/com/fdkankan/mvp/constant/ApiConstant.java

@@ -0,0 +1,35 @@
+package com.fdkankan.mvp.constant;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/8/31
+ **/
+public class ApiConstant {
+
+    public static String SERVER_CONFIG = "/api/server/config";
+
+    public static String GET_PLAY_ADDRESS_BY_CHANNEL = "/api/play/start/%s/%s";
+
+    public static String GET_PLAY_ADDRESS_BY_APP = "/api/media/stream_info_by_app_and_stream";
+
+    public static String SAVE_STREAM_PROXY = "/api/proxy/save";
+
+    public static String STOP_STREAM_PROXY = "/api/proxy/stop";
+
+    public static String START_STREAM_PROXY = "/api/proxy/start";
+
+    public static String DEL_STREAM_PROXY = "/api/proxy/del";
+
+    public static String LIST_STREAM_PROXY = "/api/proxy/list";
+
+    public static String LIST_DEVICE = "/api/device/query/devices";
+
+    public static String DEL_DEVICE = "/api/device/query/devices/%s/delete";
+
+    public static String LIST_CHANNELS = "/api/device/query/devices/%s/channels";
+
+}

+ 27 - 0
src/main/java/com/fdkankan/mvp/constant/ServerCode.java

@@ -0,0 +1,27 @@
+package com.fdkankan.mvp.constant;
+
+public enum ServerCode {
+
+	SUCCESS(0, "操作成功"),
+	SYSTEM_ERROR(-1, "服务器异常");
+
+	private Integer code;
+	private String message;
+
+	private ServerCode(Integer code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+
+	public Integer code() {
+		return code;
+	}
+
+	public String message() {
+		return message;
+	}
+
+	public String formatMessage(Object... args) {
+		return String.format(message, args);
+	}
+}

+ 36 - 0
src/main/java/com/fdkankan/mvp/constant/StreamType.java

@@ -0,0 +1,36 @@
+package com.fdkankan.mvp.constant;
+
+public enum StreamType {
+
+    PUSH("push", "国标推流"),
+    PULL("pull", "拉流代理");
+
+    private String code;
+    private String message;
+
+    private StreamType(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+    public static StreamType get(String code){
+        StreamType[] values = StreamType.values();
+        String enumValue = null;
+        for(StreamType eachValue : values){
+            enumValue = eachValue.code();
+            if(enumValue.equals(code)){
+                return eachValue;
+            }
+        }
+        return null;
+    }
+
+}

+ 77 - 0
src/main/java/com/fdkankan/mvp/device/DeviceUtil.java

@@ -0,0 +1,77 @@
+package com.fdkankan.mvp.device;
+
+import com.fdkankan.mvp.bean.ResultData;
+import com.fdkankan.mvp.bean.WvpServerInfo;
+import com.fdkankan.mvp.constant.ApiConstant;
+import com.fdkankan.mvp.factory.InstanceFactory;
+import com.fdkankan.mvp.util.forest.HttpClient;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * 设备和通道相关
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/9/1
+ **/
+public class DeviceUtil {
+
+    private static HttpClient httpClient = InstanceFactory.httpClient;
+    private static WvpServerInfo wvpServerInfo = InstanceFactory.wvpServerInfo;
+
+    /**
+     * <p>
+            分页查询国标设备
+     * </p>      
+     * @author dengsixing
+     * @param page
+     * @param count 
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData listDevice(int page, int count){
+        String url = wvpServerInfo.getAddress() + ApiConstant.LIST_DEVICE;
+        Map<String, Object> params = new HashMap<>();
+        params.put("page",page);
+        params.put("count",count);
+        ResultData resultData = httpClient.get(url, params);
+        return resultData;
+    }
+
+    /**
+     * <p>
+        根据设备id移除设备
+     * </p>
+     * @author dengsixing
+     * @param deviceId
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData deleteDevice(String deviceId){
+        String url = wvpServerInfo.getAddress() + String.format(ApiConstant.DEL_DEVICE, deviceId);
+        ResultData resultData = httpClient.get(url);
+        return resultData;
+    }
+
+    /**
+     * <p>
+            分页查询某设备下的通道
+     * </p>
+     * @author dengsixing
+     * @param deviceId
+     * @param online 是否在线(0-否,1-是) 默认全部
+     * @param page
+     * @param count
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData listChannel(String deviceId, Integer online, int page, int count){
+        String url = wvpServerInfo.getAddress() + String.format(ApiConstant.LIST_CHANNELS, deviceId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("online", online);
+        params.put("page", page);
+        params.put("count", count);
+        ResultData resultData = httpClient.get(url, params);
+        return resultData;
+    }
+
+}

+ 63 - 0
src/main/java/com/fdkankan/mvp/factory/InstanceFactory.java

@@ -0,0 +1,63 @@
+package com.fdkankan.mvp.factory;
+
+import com.dtflys.forest.Forest;
+import com.fdkankan.mvp.bean.WvpServerInfo;
+import com.fdkankan.mvp.util.forest.HttpClient;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 初始化相关
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/8/31
+ **/
+public class InstanceFactory {
+
+    public volatile static HttpClient httpClient = initHttpClient();
+
+    public volatile static WvpServerInfo wvpServerInfo;
+
+    public static HttpClient initHttpClient(){
+        if(Objects.isNull(httpClient)){
+            synchronized (InstanceFactory.class){
+                httpClient = Forest.client(HttpClient.class);
+            }
+        }
+        return httpClient;
+    }
+
+    /**
+     * <p>
+     初始化信令服务器信息,默认使用http协议
+     * </p>
+     * @author dengsixing
+     * @param ip ip
+     * @param port 端口
+     * @return com.fdkankan.mvp.server.MvpServerInfo
+     **/
+    public static WvpServerInfo initMvpServer(String ip, String port){
+        return initMvpServer("http", ip, port);
+    }
+
+    /**
+     * <p>
+     初始化信令服务器信息
+     * </p>
+     * @author dengsixing
+     * @param scheme 协议
+     * @param ip ip
+     * @param port 端口
+     * @return com.fdkankan.mvp.server.MvpServerInfo
+     **/
+    public static WvpServerInfo initMvpServer(String scheme, String ip, String port){
+        WvpServerInfo wvpServer = new WvpServerInfo();
+        wvpServer.setScheme(scheme);
+        wvpServer.setIp(ip);
+        wvpServer.setPort(port);
+        wvpServer.setAddress(scheme + "://" + ip + ":" + port);
+        wvpServerInfo = wvpServer;
+        return wvpServerInfo;
+    }
+}

+ 85 - 0
src/main/java/com/fdkankan/mvp/play/VideoPlayUtil.java

@@ -0,0 +1,85 @@
+package com.fdkankan.mvp.play;
+
+import cn.hutool.core.util.StrUtil;
+import com.fdkankan.mvp.bean.ResultData;
+import com.fdkankan.mvp.bean.WvpServerInfo;
+import com.fdkankan.mvp.constant.ApiConstant;
+import com.fdkankan.mvp.constant.StreamType;
+import com.fdkankan.mvp.factory.InstanceFactory;
+import com.fdkankan.mvp.util.forest.HttpClient;
+import java.util.HashMap;
+import java.util.Map;
+import javax.print.DocFlavor.STRING;
+
+/**
+ * <p>
+ * 播放相关
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/8/31
+ **/
+public class VideoPlayUtil {
+
+    private static HttpClient httpClient = InstanceFactory.httpClient;
+    private static WvpServerInfo wvpServerInfo = InstanceFactory.wvpServerInfo;
+
+    /**
+     * <p>
+            根据设备id和通道id获取播放地址
+     * </p>
+     * @author dengsixing
+     * @param deviceId 设备国标编码
+     * @param channelId 通道国标编码
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData getPlayAddressByChannel(String deviceId, String channelId){
+        return getPlayAddress(StreamType.PUSH.code(), deviceId,channelId,null,null,null);
+    }
+
+    /**
+     * <p>
+        根据app和流id获取播放地址
+     * </p>
+     * @author dengsixing
+     * @param app   应用名
+     * @param streamId  流id
+     * @param mediaServerId 流媒体服务id
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData getPlayAddressByApp(String app, Integer streamId, String mediaServerId){
+        return getPlayAddress(StreamType.PULL.code(), null,null, app, streamId, mediaServerId);
+    }
+
+    /**
+     * <p>
+            获取播放地址
+     * </p>
+     * @author dengsixing
+     * @param type  推拉流方式 push:国标推流,pull:拉流代理
+     * @param deviceId
+     * @param channelId
+     * @param app
+     * @param streamId
+     * @param mediaServerId
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData getPlayAddress(String type, String deviceId, String channelId, String app, Integer streamId, String mediaServerId){
+        String url;
+        if(StreamType.PUSH.code().equals(type)){
+            url = wvpServerInfo.getAddress() + String.format(ApiConstant.GET_PLAY_ADDRESS_BY_CHANNEL, deviceId, channelId);
+            return httpClient.get(url);
+        }else if(StreamType.PULL.code().equals(type)){
+            url = wvpServerInfo.getAddress() +  ApiConstant.GET_PLAY_ADDRESS_BY_APP;
+            Map<String, Object> params = new HashMap<>();
+            params.put("app", app);
+            params.put("stream", streamId);
+            if(StrUtil.isNotEmpty(mediaServerId)){
+                params.put("mediaServerId", mediaServerId);
+            }
+            return httpClient.get(url,params);
+        }
+        return null;
+    }
+
+}

+ 33 - 0
src/main/java/com/fdkankan/mvp/server/SipServerUtil.java

@@ -0,0 +1,33 @@
+package com.fdkankan.mvp.server;
+
+import com.fdkankan.mvp.bean.ResultData;
+import com.fdkankan.mvp.factory.InstanceFactory;
+import com.fdkankan.mvp.constant.ApiConstant;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * sip服务器相关
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/8/31
+ **/
+public class SipServerUtil {
+
+    /**
+     * <p>
+     获取配置信息
+     * </p>
+     * @author dengsixing
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData getSipServerConfig(){
+        String url = InstanceFactory.wvpServerInfo.getAddress() + ApiConstant.SERVER_CONFIG;
+        Map<String, Object> params = new HashMap<>();
+        params.put("type", "sip");
+        ResultData resultData = InstanceFactory.initHttpClient().get(url, params);
+        return resultData;
+    }
+}

+ 144 - 0
src/main/java/com/fdkankan/mvp/streamProxy/StreamProxyUtil.java

@@ -0,0 +1,144 @@
+package com.fdkankan.mvp.streamProxy;
+
+import com.fdkankan.mvp.bean.ResultData;
+import com.fdkankan.mvp.bean.WvpServerInfo;
+import com.fdkankan.mvp.constant.ApiConstant;
+import com.fdkankan.mvp.factory.InstanceFactory;
+import com.fdkankan.mvp.util.forest.HttpClient;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 拉流代理相关
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/8/31
+ **/
+public class StreamProxyUtil {
+
+    private static HttpClient httpClient = InstanceFactory.httpClient;
+    private static WvpServerInfo wvpServerInfo = InstanceFactory.wvpServerInfo;
+
+    /**
+     * <p>
+            保存拉流代理
+     * </p>
+     * @author dengsixing
+     * @param name  拉流代理名称
+     * @param app   app名称
+     * @param streamId  流id
+     * @param streamUrl 拉流地址
+     * @param mediaServerId  流媒体服务节点id
+     * @param rtpType   拉流方式 0-tcp,1-udp
+     * @param enable    是否启用
+     * @param enableHls 是否转hls
+     * @param enableMp4 是否开启mp4录制
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData saveStreamProxy(
+        String name, String app, String streamId,
+        String streamUrl, String mediaServerId, String rtpType,
+        boolean enable, boolean enableHls, boolean enableMp4){
+
+        String url = wvpServerInfo.getAddress() + ApiConstant.SAVE_STREAM_PROXY;
+        Map<String, Object> params = new HashMap<>();
+        params.put("app", app);
+        params.put("enable", enable);
+        params.put("enable_hls", enableHls);
+        params.put("enable_mp4", enableMp4);
+        params.put("enable_remove_none_reader", false);
+        params.put("ffmpeg_cmd_key", "ffmpeg_cmd");
+        params.put("mediaServerId", mediaServerId);
+        params.put("name", name);
+        params.put("rtp_type", rtpType);
+        params.put("stream", streamId);
+        params.put("type", "default");
+        params.put("url", streamUrl);
+        ResultData resultData = httpClient.postJson(url, params);
+        return resultData;
+    }
+
+    /**
+     * <p>
+            停用拉流代理
+     * </p>
+     * @author dengsixing
+     * @param app
+     * @param streamId
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData stopStreamProxy(String app, String streamId){
+        String url = wvpServerInfo.getAddress() + ApiConstant.STOP_STREAM_PROXY;
+        Map<String, Object> params = new HashMap<>();
+        params.put("app", app);
+        params.put("stream", streamId);
+        ResultData resultData = httpClient.get(url, params);
+        return resultData;
+    }
+
+    /**
+     * <p>
+            启用拉流代理
+     * </p>
+     * @author dengsixing
+     * @param app
+     * @param streamId
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData startStreamProxy(String app, String streamId){
+        String url = wvpServerInfo.getAddress() + ApiConstant.START_STREAM_PROXY;
+        Map<String, Object> params = new HashMap<>();
+        params.put("app", app);
+        params.put("stream", streamId);
+        ResultData resultData = httpClient.get(url, params);
+        return resultData;
+    }
+
+    /**
+     * <p>
+            移除拉流代理
+     * </p>
+     * @author dengsixing
+     * @param app
+     * @param streamId
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData delStreamProxy(String app, String streamId){
+        String url = wvpServerInfo.getAddress() + ApiConstant.DEL_STREAM_PROXY;
+        Map<String, Object> params = new HashMap<>();
+        params.put("app", app);
+        params.put("stream", streamId);
+        ResultData resultData = httpClient.deleteForm(url, params);
+        return resultData;
+    }
+
+    /**
+     * <p>
+            分页查询拉流代理
+     * </p>
+     * @author dengsixing
+     * @param page   页码
+     * @param count  每页条数
+     * @param online 是否启用(0-否,1是) 默认全部
+     * @return com.fdkankan.mvp.bean.ResultData
+     **/
+    public static ResultData listStreamProxy(int page, int count, Boolean online){
+        String url = wvpServerInfo.getAddress() + ApiConstant.DEL_STREAM_PROXY;
+        Map<String, Object> params = new HashMap<>();
+        params.put("page", page);
+        params.put("count", count);
+        if(Objects.nonNull(online)){
+            params.put("online", online);
+        }
+        ResultData resultData = httpClient.get(url, params);
+        return resultData;
+    }
+
+
+
+
+
+}

+ 0 - 0
src/main/java/com/fdkankan/mvp/util/111.txt


+ 40 - 0
src/main/java/com/fdkankan/mvp/util/forest/ErrorCallback.java

@@ -0,0 +1,40 @@
+package com.fdkankan.mvp.util.forest;
+
+import cn.hutool.http.HttpStatus;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.dtflys.forest.callback.OnError;
+import com.dtflys.forest.exceptions.ForestRuntimeException;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.http.ForestResponse;
+import com.fdkankan.mvp.bean.ResultData;
+import com.fdkankan.mvp.constant.ServerCode;
+import java.util.Objects;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+@Slf4j
+public class ErrorCallback implements OnError {
+
+    @Override
+    public void onError(ForestRuntimeException e, ForestRequest forestRequest,
+        ForestResponse forestResponse) {
+        JSONObject jsonObject = JSONUtil.parseObj(forestResponse.getContent());
+        Integer status = jsonObject.getInt("status");
+        if(Objects.isNull(status) && status != HttpStatus.HTTP_OK){
+            log.error("请求失败,url:{}", forestRequest.getUrl());
+            throw new RuntimeException(ServerCode.SYSTEM_ERROR.message());
+        }
+        ResultData result = JSONUtil.toBean(forestResponse.getContent(), ResultData.class);
+        if(result.getCode() != ServerCode.SUCCESS.code()){
+            throw new RuntimeException(ServerCode.SYSTEM_ERROR.message());
+        }
+    }
+}

+ 45 - 0
src/main/java/com/fdkankan/mvp/util/forest/HttpClient.java

@@ -0,0 +1,45 @@
+package com.fdkankan.mvp.util.forest;
+
+import cn.hutool.json.JSONObject;
+import com.dtflys.forest.annotation.Body;
+import com.dtflys.forest.annotation.Delete;
+import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.JSONBody;
+import com.dtflys.forest.annotation.Post;
+import com.dtflys.forest.annotation.Query;
+import com.dtflys.forest.annotation.Success;
+import com.dtflys.forest.annotation.Var;
+import com.fdkankan.mvp.bean.ResultData;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/24
+ **/
+@Success(condition = SuccessCondition.class)
+public interface HttpClient {
+
+    @Get("{url}")
+    ResultData get(@Var("url") String url);
+
+    @Get("{url}")
+    ResultData get(@Var("url") String url, @Query Object params);
+
+    @Post("{url}")
+    ResultData postForm(@Var("url") String url, @Body Object params);
+
+    @Post("{url}")
+    ResultData postJson(@Var("url") String url, @JSONBody Object params);
+
+    @Delete("{url}")
+    ResultData deleteForm(@Var("url") String url, @Body Object params);
+
+
+
+
+}

+ 25 - 0
src/main/java/com/fdkankan/mvp/util/forest/SuccessCallback.java

@@ -0,0 +1,25 @@
+package com.fdkankan.mvp.util.forest;
+
+import com.dtflys.forest.callback.OnSuccess;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.http.ForestResponse;
+import com.fdkankan.mvp.bean.ResultData;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+@Slf4j
+public class SuccessCallback implements OnSuccess<ResultData> {
+
+    @Override
+    public void onSuccess(ResultData result, ForestRequest forestRequest,
+        ForestResponse forestResponse) {
+        log.info("请求成功,url:{},result:{}", forestRequest.getUrl(), forestResponse.getContent());
+    }
+}

+ 50 - 0
src/main/java/com/fdkankan/mvp/util/forest/SuccessCondition.java

@@ -0,0 +1,50 @@
+package com.fdkankan.mvp.util.forest;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.dtflys.forest.callback.SuccessWhen;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.http.ForestResponse;
+import com.fdkankan.mvp.bean.ResultData;
+import com.fdkankan.mvp.constant.ServerCode;
+
+/**
+ * <p>
+ *  自定义成功/失败条件实现类
+ *  需要实现 SuccessWhen 接口
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+
+public class SuccessCondition implements SuccessWhen {
+
+    /**
+     * 请求成功条件
+     * @param req Forest请求对象
+     * @param res Forest响应对象
+     * @return 是否成功,true: 请求成功,false: 请求失败
+     */
+    @Override
+    public boolean successWhen(ForestRequest req, ForestResponse res) {
+        boolean reqStatus = res.noException() &&   // 请求过程没有异常
+            res.statusOk() &&     // 并且状态码在 100 ~ 399 范围内
+            res.statusIsNot(203);
+        if(!reqStatus){
+            return reqStatus;
+        }
+
+        String content = res.getContent();
+        if(StrUtil.isEmpty(content)){
+            reqStatus = false;
+            return reqStatus;
+        }
+        ResultData result = JSONUtil.toBean(content, ResultData.class);
+        if(result.getCode() != ServerCode.SUCCESS.code()){
+            reqStatus = false;
+            return reqStatus;
+        }
+        return true;
+    }
+}