httpclient工具类(支持泛型转换)

news2024/11/28 3:46:38

1、网上搜到的httpclient工具类的问题:

1.1、如下图我们都能够发现这种封装的问题:

  • 代码繁杂、充斥了很多重复性代码
  • 返回值单一,无法拿到对应的Java Bean对象及List对象集合
  • 实际场景中会对接大量第三方的OPEN API,下述方法的扩展性差

在这里插入图片描述

1.2、简洁调用方式演示

本文基于上述问题,通过设计模式、泛型、JSON工具类的方式进行了封装,得到了下述更方便、更简洁的http请求调用方式

Entity params = new Entity();
params.setUrl("/common/postJson");
 Map<String, Object> map = new HashMap<>();
map.put("userId", "13277887788");
map.put("companyId", "87037827534cf");
params.setParams(map);

// 返回对象集合
List<AppEntity> appEntity = thirdHttpProcessorFactory
	.doGetReturnList(ThirdSystemEnum.ION, params, AppEntity.class);
// 返回String类型
String result = thirdHttpProcessorFactory
	.doGetReturnBean(ThirdSystemEnum.ION, params, String.class);
// 返回指定的对象
AppEntity appEntity = thirdHttpProcessorFactory
	.doGetReturnBean(ThirdSystemEnum.ION, params, AppEntity.class);
        

1.3、 目录结构

在这里插入图片描述

2、引入的maven仓库

 <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
	 <version>2.14.2</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.16</version>
</dependency>
  • ThirdHttpProcessorFactory:存储不同三方平台的处理期
  • ThirdHttpProcessor:定义通用的接口
  • AbstractThirdHttpProcessor:定义公共的处理逻辑
  • IonHttpProcessor:定义各对接平台的差异性逻辑
  • AppEntity:返回值
  • Entity:入参
  • ThirdSystemEnum:定义三方平台的枚举

3、代码实现

3.1、获取不同第三方处理器的工厂ThirdHttpProcessorFactory

package com.ionrocking.platform.tripartite;


import com.ionrocking.common.core.exception.ServiceException;
import com.ionrocking.platform.tripartite.entity.Entity;
import com.ionrocking.platform.tripartite.enums.ThirdSystemEnum;
import lombok.experimental.Accessors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ke
 * Created by on  2023-10-27 15:23
 */
@Component
@Accessors(chain = true)
public class ThirdHttpProcessorFactory {

    @Autowired
    private List<ThirdHttpProcessor> thirdHttpProcessors;

    private Map<String, ThirdHttpProcessor> thirdHttpProcessorMap;

    @PostConstruct
    public void init() {
        if (CollectionUtils.isEmpty(thirdHttpProcessors)) {
            return;
        }
        thirdHttpProcessorMap = new HashMap<>(8);
        for (ThirdHttpProcessor processor : thirdHttpProcessors) {
            thirdHttpProcessorMap.put(processor.getType().getCode(), processor);
        }
    }

    private ThirdHttpProcessor getThirdHttpProcessor(String type) {
        ThirdSystemEnum thirdSystemEnum = ThirdSystemEnum.getByCode(type);
        if (null == thirdSystemEnum) {
            throw new ServiceException("三方OpenApi尚未配置,无法进行请求");
        }
        return thirdHttpProcessorMap.get(type);
    }


    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doGetReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass) throws Exception {
        return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnBean(entity, tClass);
    }

    /**
     * http post请求,入参支持application/x-www-form-urlencoded 请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doPostReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass) throws Exception {
        return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostReturnBean(entity, tClass);
    }

    /**
     * http post请求,入参支持application/json请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return T              返回数据对象
     * @throws Exception 业务执行异常
     */
    public <T> T doPostJsonReturnBean(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass) throws Exception {
        return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostJsonReturnBean(entity, tClass);
    }

    /**
     * http get请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doGetReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass) throws Exception {
        return getThirdHttpProcessor(thirdSystemEnum.getCode()).doGetReturnList(entity, tClass);
    }

    /**
     * http post请求,入参支持application/x-www-form-urlencoded 请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doPostReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass) throws Exception {
        return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostReturnList(entity, tClass);
    }

    /**
     * http post请求,入参支持application/json请求
     *
     * @param thirdSystemEnum 三方系统类型枚举
     * @param entity          参数
     * @param tClass          返回参数类型
     * @return List<T>        返回数据集合
     * @throws Exception 业务执行异常
     */
    public <T> List<T> doPostJsonReturnList(ThirdSystemEnum thirdSystemEnum, Entity entity, Class<T> tClass) throws Exception {
        return getThirdHttpProcessor(thirdSystemEnum.getCode()).doPostJsonReturnList(entity, tClass);
    }

}

3.2、http请求处理的接口ThirdHttpProcessor

/**
 * Dans.com Inc.
 * Copyright (c) 2011-2020 All Rights Reserved
 */
package com.ionrocking.platform.tripartite;


import com.ionrocking.platform.tripartite.entity.Entity;
import com.ionrocking.platform.tripartite.enums.ThirdSystemEnum;

import java.util.List;

/**
 * 追踪事件处理器
 *
 * @author ke
 * Created by on  2023-06-20 15:23
 */
public interface ThirdHttpProcessor {

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return T
     * @throws Exception 业务执行异常
     */
    <T> T doGetReturnBean(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> T doPostReturnBean(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> T doPostJsonReturnBean(Entity entity, Class<T> tClass) throws Exception;
    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return T
     * @throws Exception 业务执行异常
     */
    <T> List<T> doGetReturnList(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> List<T> doPostReturnList(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 业务执行
     *
     * @param entity
     * @param tClass
     * @return
     * @throws Exception 业务执行异常
     */
    <T> List<T> doPostJsonReturnList(Entity entity, Class<T> tClass) throws Exception;

    /**
     * 获取事件类型
     *
     * @return
     */
    ThirdSystemEnum getType();
}

3.3、通用逻辑处理的抽象类AbstractThirdHttpProcessor

  • 如在通过http client发起HTTP请求时,除了请求头requestHeader、请求入参requestBody不同,其他逻辑都是一样的,则可以进行公共代码的抽取
  • 如果存在特殊的逻辑处理,则可以在子类中重写父类的方法
package com.ionrocking.platform.tripartite;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ionrocking.common.core.exception.ServiceException;
import com.ionrocking.platform.config.SysNacosConfig;
import com.ionrocking.platform.tripartite.entity.Entity;
import com.ionrocking.platform.tripartite.entity.IonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Slf4j
@Component
public abstract class AbstractThirdHttpProcessor implements ThirdHttpProcessor {
    @Override
    public <T> List<T> doGetReturnList(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createGet(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toList(result, tClass);
    }

    @Override
    public <T> List<T> doPostReturnList(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toList(result, tClass);
    }

    @Override
    public <T> List<T> doPostJsonReturnList(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .body(JSONUtil.toJsonStr(requestBody))
                .execute()
                .body();
        return toList(result, tClass);
    }

    public <T> T toBean(String result, Class<T> tClass) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        IonResponse<Object> response = JSONUtil.toBean(result, IonResponse.class);
        if (CODE != response.getCode()) {
            throw new ServiceException(response.getMsg());
        }
        if (null == response.getData()) {
            return null;
        }
        return objectMapper.readValue(response.getData().toString(), tClass);
    }

    public <T> List<T> toList(String result, Class<T> tClass) throws JsonProcessingException {
        List<T> data = new ArrayList<>();
        IonResponse<List<Object>> response = JSONUtil.toBean(result, IonResponse.class);
        if (CODE != response.getCode()) {
            throw new ServiceException(response.getMsg());
        }
        if (CollUtil.isEmpty(response.getData())) {
            return null;
        }
        for (Object o : response.getData()) {
            ObjectMapper objectMapper = new ObjectMapper();
            data.add(objectMapper.readValue(o.toString(), tClass));
        }
        return data;
    }

    @Resource
    protected SysNacosConfig sysNacosConfig;

    protected static final int CODE = 200;

    @Override
    public <T> T doGetReturnBean(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createGet(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toBean(result, tClass);
    }

    /**
     * 执行
     *
     * @return
     */
    @Override
    public <T> T doPostReturnBean(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .form(requestBody)
                .execute()
                .body();
        return toBean(result, tClass);
    }

    @Override
    public <T> T doPostJsonReturnBean(Entity entity, Class<T> tClass) throws Exception {
        // 构造请求头
        Map<String, String> requestHead = constructRequestHead(entity);
        // 构造请求数据
        Map<String, Object> requestBody = constructRequestBody(entity);
        String result = HttpUtil.createPost(sysNacosConfig.getIonRequestUrl() + entity.getUrl())
                .addHeaders(requestHead)
                .body(JSONUtil.toJsonStr(requestBody))
                .execute()
                .body();
        return toBean(result, tClass);
    }


    /**
     * 构造请求头
     *
     * @param entity
     * @return
     */
    public abstract Map<String, String> constructRequestHead(Entity entity);

    /**
     * 构造请求体
     *
     * @param entity
     * @return
     */
    public Map<String, Object> constructRequestBody(Entity entity) {
        if (CharSequenceUtil.isBlank(entity.getUrl())) {
            throw new ServiceException("请求路径不能为空");
        }
        if (null == entity) {
            return null;
        }
        return entity.getParams();
    }

}

3.4、第三方非通用逻辑处理类IonHttpProcessor

  • 比如此处对接的xx公司需要进行access_token获取及验证,然后将access_token放在请求头中
package com.ionrocking.platform.tripartite.impl;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.ionrocking.platform.tripartite.AbstractThirdHttpProcessor;
import com.ionrocking.platform.tripartite.entity.Entity;
import com.ionrocking.platform.tripartite.entity.IonResponse;
import com.ionrocking.platform.tripartite.enums.ThirdSystemEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Slf4j
@Component
public class IonHttpProcessor extends AbstractThirdHttpProcessor {

    private String accessTokenUrl = "/token/getAccessToken";


    private static final String ACCESS_TOKEN_KEY = "access_token";

    @Override
    public Map<String, String> constructRequestHead(Entity entity) {
        Map<String, String> header = new HashMap<>(2);
        Map<String, Object> params = new HashMap<>(4);
        params.put("appId", sysNacosConfig.getIonRequestAppId());
        params.put("appSecret", sysNacosConfig.getIonRequestAppSecret());

        String result = HttpUtil.get(sysNacosConfig.getIonRequestUrl() + accessTokenUrl, params);
        if (CharSequenceUtil.isEmpty(result)) {
            return null;
        }
        TypeReference<IonResponse<Map<String, Object>>> typeRef = new TypeReference<IonResponse<Map<String, Object>>>() {
        };
        IonResponse<Map<String, Object>> response = JSONUtil.toBean(result, typeRef, false);
        if (CODE == response.getCode() && null != response.getData()) {
            if (response.getData().containsKey(ACCESS_TOKEN_KEY)) {
                header.put(ACCESS_TOKEN_KEY, response.getData().get(ACCESS_TOKEN_KEY).toString());
            }
        }
        return header;
    }

    @Override
    public ThirdSystemEnum getType() {
        return ThirdSystemEnum.ION;
    }
}

3.5、枚举类ThirdSystemEnum

  • 区分不同的平台,根据枚举获取不同的实现类
package com.ionrocking.platform.tripartite.enums;

import org.apache.commons.lang3.StringUtils;

/**
 * @author ke
 * @Date 2023/10/27
 */
public enum ThirdSystemEnum {
    /**
     * XX科技公司
     */
    ION("ion", "xx科技");

    private final String code;

    private final String name;

    public String getName() {
        return this.name;
    }


    public String getCode() {
        return this.code;
    }

    ThirdSystemEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ThirdSystemEnum getByCode(String code) {
        if (StringUtils.isEmpty(code)) {
            return null;
        }
        for (ThirdSystemEnum codeEnum : values()) {
            if (code.equals(codeEnum.getCode())) {
                return codeEnum;
            }
        }
        return null;
    }
}

3.6、第三方返回格式对象IonResponse

package com.ionrocking.platform.tripartite.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IonResponse<T> implements Serializable {

    private static final long serialVersionUID = -8741972144218822267L;
    private int code;
    /**
     * 消息
     */
    private String msg;
    /**
     * 数据
     */
    private T data;
    /**
     * 总记录数
     */
    private long total;
}

3.7、处理器入参对象Entity

  • 此处定义请求的URL和请求的参数
package com.ionrocking.platform.tripartite.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Map;

/**
 * @author ke
 * @Date 2023/10/27
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Entity implements Serializable {

    private static final long serialVersionUID = -6083780287057302816L;

    private String url;

    /**
     * 参数
     */
    private Map<String, Object> params;
}

3.8、第三方接口返回值对象AppEntity

package com.ionrocking.platform.tripartite.entity;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotBlank;

/**
 * @author ke
 * @Date 2023/10/26
 */

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class AppEntity {
    private long id;

    private String appId;

    @NotBlank(message = "应用名称不能为空")
    private String appName;

    private String appSecret;

    private String accessToken;

    private Integer isFlag;
}

3.9、Nacos配置

  • Nacos中一般存放一些第三方的请求域名、鉴权的appId、appSecret等
tripartite-platform:
  ion:
    request:
      url: http://localhost:8080/api/
      appId: YodeqWwp
      appSecret: 87037827534cf848a570fae3c93a2469fa0262935af531dddfe7a52ae7f98f41
package com.ionrocking.platform.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * nacos配置信息
 * @author ke
 * @Date 2023/9/20
 */
@Component
public class SysNacosConfig {


    @Value("${upload.path}")
    private String uploadPath;

    @Value("${tripartite-platform.ion.request.url}")
    private String ionRequestUrl;

    @Value("${tripartite-platform.ion.request.appId}")
    private String ionRequestAppId;

    @Value("${tripartite-platform.ion.request.appSecret}")
    private String ionRequestAppSecret;

    public String getUploadPath() {
        return uploadPath;
    }

    public String getIonRequestUrl() {
        return ionRequestUrl;
    }

    public String getIonRequestAppId() {
        return ionRequestAppId;
    }

    public String getIonRequestAppSecret() {
        return ionRequestAppSecret;
    }
}

测试

@RestController
@RequestMapping("/test")
public class Test {
    
    @Resource
    private SysNacosConfig sysNacosConfig;
    
    @Resource
    private ThirdHttpProcessorFactory thirdHttpProcessorFactory;
    
    @ResponseBody
    @RequestMapping(value = "/get")
    public AjaxResult get() throws Exception extends BaseController  {
        Entity params = new Entity();
        params.setUrl("/common/get");
        String result = thirdHttpProcessorFactory.doGetReturnBean(ThirdSystemEnum.ION, params, String.class);
        return AjaxResult.success(result);
    }


    @ResponseBody
    @RequestMapping(value = "/list")
    public AjaxResult list() throws Exception {
        Entity params = new Entity();
        params.setUrl("/common/list");
        List<AppEntity> appEntity = thirdHttpProcessorFactory.doGetReturnList(ThirdSystemEnum.ION, params, AppEntity.class);
        return AjaxResult.success(appEntity);
    }

    @ResponseBody
    @RequestMapping(value = "/postJson")
    public AjaxResult postJson() throws Exception {
        Entity params = new Entity();
        params.setUrl("/common/postJson");
        Map<String, Object> map = new HashMap<>();
        map.put("appId", "YodeqWwp");
        map.put("appSecret", "87037827534cf848a570fae3c93a2469fa0262935af531dddfe7a52ae7f98f41");
        params.setParams(map);
        List<AppEntity> list = thirdHttpProcessorFactory.doPostJsonReturnList(ThirdSystemEnum.ION, params, AppEntity.class);
		return AjaxResult.success(list);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1168842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最亮那颗星的中年危机 —— 程序员的职场困境与破局

如果说最近的这十年国内市场什么工作是最受瞩目的&#xff0c;那么程序员绝对算得上是夜空中最闪亮的那颗星。 伴随科技的迅猛发展&#xff0c;计算机走进千家万户&#xff0c;智能终端深深融入每个人的生活&#xff0c;程序员这一职业群体也逐渐成为了现代社会中不可或缺的一…

分享一个抖音视频解析神器~

怎么样下载抖音视频&#xff1f;相信很多人都有过这样的困惑。作为一个资深短视频剪辑工作者&#xff0c;常常需要用到各种视频素材&#xff0c;其中不乏需要从抖音上下载的&#xff0c;因此我也尝试过许多下载工具&#xff0c;但是效果都不大满意&#xff0c;直到有一次朋友给…

最近面试者对接口测试的理解真把我给笑拥了~

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

建议收藏《2023华为海思实习笔试-数字芯片真题+解析》(附下载)

华为海思一直以来是从业者想要进入的热门公司。但是岗位就那么多&#xff0c;在面试的时候&#xff0c;很多同学因为准备不充分&#xff0c;与岗位失之交臂&#xff0c;无缘进入该公司。今天为大家带来《2023华为海思实习笔试-数字芯片真题解析》题目来源于众多网友对笔试的记录…

CSS基础知识点速览

1 基础认识 1.1 css的介绍 CSS:层叠样式表(Cascading style sheets) CSS作用&#xff1a; 给页面中的html标签设置样式 css写在style标签里&#xff0c;style标签一般在head标签里&#xff0c;位于head标签下。 <style>p{color: red;background-color: green;font-size…

路由器基础(五): OSPF原理与配置

开放式最短路径优先 (Open Shortest Path First,OSPF) 是一个内部网关协议 (Interior Gateway Protocol,IGP),用于在单一自治系统(Autonomous System,AS) 内决策路由。OSPF 适合小型、中型、较大规模网络。OSPF 采用Dijkstra的最短路径优先算法 (Shortest Pat…

Go Gin中间件

Gin是一个用Go语言编写的Web框架&#xff0c;它提供了一种简单的方式来创建HTTP路由和处理HTTP请求。中间件是Gin框架中的一个重要概念&#xff0c;它可以用来处理HTTP请求和响应&#xff0c;或者在处理请求之前和之后执行一些操作。 以下是关于Gin中间件开发的一些基本信息&am…

【计算机网络 - 自顶向下方法】第一章习题答案

P2 Question&#xff1a;   式 (1-1) 给出了经传输速率为 R 的 N 段链路发送长度为 L 的一个分组的端到端时延。 对于经过 N 段链路一个接一个地发送 P 个这样的分组&#xff0c;一般化地表示出这个公式。 Answer&#xff1a;    N ∗ L R \frac{N*L}{R} RN∗L​ 时&…

【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取(北斗、GPS和GNSS)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取&#xff08;北斗、GPS和GNSS&#xff09; 测试视频&#xff08;其中的恶性BUG会在下一篇文章阐述&#xff09;&#xff1a; 【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG&#xff08;目前没有完全的…

Python语言:容器操作知识点总结清单

容器通用操作表格&#xff1a; 列表知识点清单&#xff1a; 元组知识点清单&#xff1a; 字典知识点清单&#xff1a; 集合知识点清单&#xff1a; 字符串知识点清单&#xff1a; 说明&#xff1a;本次知识点总结可能会有遗漏&#xff0c;没有做到面面俱到。

联通智网科技正式入选国家级专精特新“小巨人”企业

近日&#xff0c;北京市经济和信息化局发布《第五批专精特新“小巨人”企业公告名单》&#xff0c;根据工业和信息化部发布的《工业和信息化部关于公布第五批专精特新“小巨人”企业和通过复核的第二批专精特新“小巨人”企业名单的通告》&#xff0c;联通智网科技股份有限公司…

Java自学第3课:Java语言流程控制和字符串

1 复合语句 复合语句是以区块为单位的语句&#xff0c;也就是{}内的内容。 2 条件语句 if (布尔表达式){语句序列}else{语句序列} 有个好玩的是&#xff0c;对年龄段的分段&#xff0c;其实以前的思维是有点冗余的&#xff0c;比如a<100 & a>90&#xff0c;在复合…

蛋白质N端测序服务

表达纯化后的蛋白产物&#xff0c;特别是蛋白品的分析过程中&#xff0c;需要对蛋白的末端进行验证&#xff0c;以保证表达纯化产物的N端和C端序列准确。Edman降解法是蛋白的N端序列分析中非常成熟的方法之一&#xff0c;有着广泛的应用。卡梅德生物采用岛津公司Edman测序系统&…

C++定义一个 Student 类,在该类定义中包括:一个数据成员 score(分数)及两个静态数据 成员 total(总分)和学生人数 count

完整代码&#xff1a; /*声明一个Student类&#xff0c;在该类中包括一个数据成员score&#xff08;分数&#xff09;、两个静态数据成员total_score&#xff08;总分&#xff09;和count&#xff08;学生人数&#xff09;&#xff1b;还包括一个成员函数account&#xff08;&…

Redis缓存穿透、击穿、雪崩问题原理和解决方案

目录 一、Redis缓存穿透1.1、缓存穿透原理1.2、缓存穿透代码演示1.3、缓存穿透解决方案解决方案一&#xff08;数据库中查询不到数据也将key进行缓存&#xff09;解决方案二&#xff08;使用布隆过滤器&#xff09; 二、Redis缓存击穿&#xff08;缓存失效&#xff09;三、Redi…

KV STUDIO对plc的读取与电焊机的配料设置

今天又开始了明天的工作总结&#xff0c;希望对于看小编博客的粉丝有所帮助&#xff0c;前程似锦&#xff01;&#xff01;&#xff01; KV STUDIO对plc的读取 一&#xff0c;先将电脑与设备相连接&#xff0c;有许多种发生&#xff0c;小编这使用的是以太网方式 二&#xff0…

倒计时丨距离RestCloud新品发布仅有6天!

6天倒计时&#xff0c;RestCloud零代码集成自动化平台重磅发布 ⏰11月9日14:00&#xff0c;期待您的参与&#xff01; 点击报名&#xff1a;http://c.nxw.so/dfaJ9

【LeetCode刷题-链表】--146.LRU缓存

146.LRU缓存 方法一&#xff1a;哈希表双向链表 使用一个哈希表和一个双向链表维护所有在缓存中的键值对 双向链表按照被使用的顺序存储了这些键值对&#xff0c;靠近头部的键值对是最近使用的&#xff0c;而靠近尾部的键值对是最久使用的哈希表即为普通的哈希映射&#xff0…

Java基础之类型(内涵面试题)

目录 一、自动类型转换&#xff1a; 二、强制类型转换&#xff1a; 1.强制类型转换可能造成数据丢失&#xff08;溢出&#xff09;。 2.浮点型强转成整型&#xff0c;直接丢掉小数部分&#xff0c;保留整数部分返回。 三、自增、自减&#xff08;、--&#xff09;有关面试题…