From 625199757b698a2074e78f66deb410298546bb65 Mon Sep 17 00:00:00 2001 From: YOUR_USERNAME <1822377117@qq.com> Date: Tue, 17 Dec 2024 23:46:40 +0800 Subject: [PATCH] zhaoyuyan_common --- .../com/sky/constant/PasswordConstant.java | 16 ++ .../sky/exception/AccountLockedException.java | 28 +++ .../DeletionNotAllowedException.java | 22 ++ .../sky/exception/PasswordErrorException.java | 30 +++ .../com/sky/json/JacksonObjectMapper.java | 77 +++++++ .../com/sky/properties/WeChatProperties.java | 74 +++++++ .../java/com/sky/utils/HttpClientUtil.java | 205 ++++++++++++++++++ 7 files changed, 452 insertions(+) create mode 100644 sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java create mode 100644 sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java create mode 100644 sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java create mode 100644 sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java create mode 100644 sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java create mode 100644 sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java create mode 100644 sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java diff --git a/sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java b/sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java new file mode 100644 index 0000000..4a71eb6 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java @@ -0,0 +1,16 @@ +package com.sky.constant; + +/** + * 密码常量类,用于定义项目中与密码相关的常量值。 + * 此类中的常量可以在整个项目的多个地方被引用,方便统一管理和维护密码相关的固定值。 + */ +public class PasswordConstant { + + /** + * 默认密码常量,定义了系统默认使用的密码字符串值为 "123456"。 + * 在一些场景下,例如新用户首次创建账号时,如果没有指定密码,可能会默认赋予该密码。 + * 或者在进行密码重置等操作,当需要一个初始的默认密码时可使用此常量所代表的值。 + */ + public static final String DEFAULT_PASSWORD = "123456"; + +} diff --git a/sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java b/sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java new file mode 100644 index 0000000..d0388eb --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java @@ -0,0 +1,28 @@ +package com.sky.exception; + +/** + * 账号被锁定异常类,用于表示在系统中账号处于被锁定状态时抛出的异常情况。 + * 当检测到账号由于某些原因(比如多次输入错误密码等)被锁定后,会通过抛出该异常来通知相关的业务逻辑进行相应处理, + * 该异常类继承自BaseException,便于统一纳入项目的异常处理体系中。 + */ +public class AccountLockedException extends BaseException { + + /** + * 默认构造函数,无参构造。 + * 当不需要传递额外的异常信息,仅想表示账号被锁定这一异常情况时可使用此构造函数创建异常实例。 + */ + public AccountLockedException() { + } + + /** + * 带参构造函数,用于创建带有特定异常消息的账号被锁定异常实例。 + * 通过传入具体的消息字符串(msg),可以在异常抛出时提供更详细的关于账号被锁定原因等方面的信息, + * 方便在进行异常处理和日志记录等操作时更清晰地了解具体情况,该构造函数调用了父类(BaseException)的带参构造函数来传递消息。 + * + * @param msg 异常相关的具体消息内容,描述账号被锁定的详细原因等信息。 + */ + public AccountLockedException(String msg) { + super(msg); + } + +} diff --git a/sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java b/sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java new file mode 100644 index 0000000..e3de70a --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java @@ -0,0 +1,22 @@ +package com.sky.exception; +/** + * 禁止删除异常类,用于在系统中当某些对象或数据不允许被删除的情况下抛出异常。 + * 例如,可能存在业务规则限制某些关键数据、处于特定状态的数据不能被删除, + * 当违反这些规则尝试进行删除操作时,就可以通过抛出该异常来告知调用方操作不被允许, + * 它继承自BaseException,以便能更好地融入项目整体的异常处理框架中。 + */ +public class DeletionNotAllowedException extends BaseException { + + /** + * 带参构造函数,用于创建带有具体异常消息的禁止删除异常实例。 + * 通过传入一个消息字符串(msg),能够详细地说明为什么当前的删除操作不被允许, + * 比如是因为数据关联了其他重要模块、处于特定业务流程中不能删除等具体原因, + * 该构造函数调用了父类(BaseException)的带参构造函数来传递此消息,方便后续处理异常时获取相关信息。 + * + * @param msg 具体描述禁止删除原因的消息内容。 + */ + public DeletionNotAllowedException(String msg) { + super(msg); + } + +} \ No newline at end of file diff --git a/sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java b/sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java new file mode 100644 index 0000000..a0e2b4e --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java @@ -0,0 +1,30 @@ +package com.sky.exception; + +/** + * 密码错误异常类,用于表示在进行密码验证相关操作时,输入的密码不符合要求、与正确密码不一致的异常情况。 + * 例如用户登录、修改密码时验证原密码等场景下,若输入的密码不正确,就会通过抛出该异常来通知相应的业务逻辑进行处理, + * 该异常类继承自BaseException,便于在整个项目的异常管理体系中统一进行处理和追踪。 + */ +public class PasswordErrorException extends BaseException { + + /** + * 无参构造函数,用于创建一个默认的密码错误异常实例。 + * 当不需要传递额外详细的异常消息,仅想表明密码出现错误这一基本情况时,可以使用这个构造函数来创建异常对象, + * 后续可以根据异常类型在统一的异常处理机制中进行相应的通用处理操作。 + */ + public PasswordErrorException() { + } + + /** + * 带参构造函数,用于创建带有特定消息的密码错误异常实例。 + * 通过传入具体的消息字符串(msg),可以详细说明密码错误的具体原因,比如是长度不符合要求、格式不对, + * 或者与存储的正确密码不匹配等具体情况,此构造函数调用了父类(BaseException)的带参构造函数来传递该消息, + * 方便在异常处理以及日志记录等环节能够准确获取密码错误的详细缘由并进行针对性的处理。 + * + * @param msg 描述密码错误具体原因的消息内容。 + */ + public PasswordErrorException(String msg) { + super(msg); + } + +} diff --git a/sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java b/sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java new file mode 100644 index 0000000..5279524 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java @@ -0,0 +1,77 @@ +package com.sky.json; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; + +/** + * JacksonObjectMapper类,继承自ObjectMapper,主要用于在Java对象与JSON数据之间进行相互转换,是基于Jackson框架实现的对象映射器。 + * 在数据交互过程中,将JSON解析为Java对象的操作被称为 [从JSON反序列化Java对象],而把Java对象转换生成JSON的操作则被称为 [序列化Java对象到JSON]。 + * 此类通过配置一系列的序列化和反序列化相关特性及自定义模块,来满足项目中对于JSON和Java对象转换时的特定需求,例如时间格式处理以及对未知属性的兼容处理等。 + */ +public class JacksonObjectMapper extends ObjectMapper { + + /** + * 默认的日期格式字符串,用于定义在序列化和反序列化LocalDate类型时采用的日期格式,格式为 "yyyy-MM-dd", + * 符合常见的日期表示规范,方便在JSON数据与Java的LocalDate对象转换时统一日期的呈现和解析方式,确保数据的一致性和准确性。 + */ + public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; + + /** + * 默认的日期时间格式字符串,原本定义为 "yyyy-MM-dd HH:mm:ss",后修改为 "yyyy-MM-dd HH:mm",用于指定在处理LocalDateTime类型时的日期时间格式, + * 这种格式适用于项目中对于日期时间的具体展示和解析需求,例如在记录操作时间、事件发生时间等场景下,按照此格式进行转换,便于前后端数据交互以及数据存储和展示的统一。 + */ + public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm"; + + /** + * 默认的时间格式字符串,用于规范LocalTime类型在序列化和反序列化过程中的时间格式,格式为 "HH:mm:ss", + * 主要用于表示一天内的具体时间点,在涉及只关注时间部分(如营业时间、任务执行时间等)的业务场景中,以此格式来准确转换JSON与Java对象中的时间数据。 + */ + public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; + + /** + * 构造函数,在创建JacksonObjectMapper对象时进行一系列的初始化配置操作。 + */ + public JacksonObjectMapper() { + super(); + + // 配置在接收到未知属性时不报异常的特性。 + // 在JSON数据转换为Java对象时,如果JSON中包含了Java对象对应类中不存在的属性,默认情况下Jackson会抛出异常, + // 通过设置此项为false,使得在遇到这种情况时能够进行兼容处理,避免因未知属性导致转换失败,提高了对不同格式JSON数据的兼容性。 + this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); + + // 进一步设置反序列化时属性不存在的兼容处理。 + // 确保在反序列化过程中,即使遇到JSON中的属性在Java对象对应类里不存在的情况,也能平稳进行处理,不会因这种差异而中断转换流程, + // 这是对反序列化兼容性的再次强化,和上面的配置一起保障了在接收不同结构JSON数据时的稳健性。 + this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + SimpleModule simpleModule = new SimpleModule() + // 为LocalDateTime类型添加反序列化器,使用指定的日期时间格式(由DEFAULT_DATE_TIME_FORMAT定义)来解析JSON中的日期时间字符串,将其转换为Java的LocalDateTime对象。 + .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) + // 为LocalDate类型添加反序列化器,按照默认的日期格式(DEFAULT_DATE_FORMAT)把JSON中的日期字符串反序列化为Java的LocalDate对象。 + .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) + // 为LocalTime类型添加反序列化器,依据默认的时间格式(DEFAULT_TIME_FORMAT)将JSON中的时间字符串转换为Java的LocalTime对象。 + .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) + // 为LocalDateTime类型添加序列化器,将Java的LocalDateTime对象按照指定的日期时间格式(DEFAULT_DATE_TIME_FORMAT)转换为JSON中的日期时间字符串进行输出。 + .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) + // 为LocalDate类型添加序列化器,把Java的LocalDate对象依照默认的日期格式(DEFAULT_DATE_FORMAT)序列化为JSON中的日期字符串。 + .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) + // 为LocalTime类型添加序列化器,使用默认的时间格式(DEFAULT_TIME_FORMAT)将Java的LocalTime对象转换为JSON中的时间字符串,方便在JSON数据中呈现。 + .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); + + // 注册功能模块,通过注册这个自定义的SimpleModule,使得添加的针对时间类型的序列化器和反序列化器生效, + // 同时也可以在后续根据需要添加更多自定义的序列化器和反序列化器,扩展该对象映射器的功能,以满足不同业务场景下对JSON与Java对象转换的特殊要求。 + this.registerModule(simpleModule); + } +} \ No newline at end of file diff --git a/sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java b/sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java new file mode 100644 index 0000000..ba33547 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java @@ -0,0 +1,74 @@ +package com.sky.properties; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * WeChatProperties类,主要用于配置与微信相关的各种属性信息,方便在项目中集中管理和获取微信小程序、支付等相关功能所需要的关键参数。 + * 通过使用Spring框架提供的相关注解,能够将配置文件(通常是application.properties或application.yml等)中以特定前缀开头的配置项自动绑定到此类的对应属性上,实现配置的便捷注入和使用。 + */ +@Component +@ConfigurationProperties(prefix = "sky.wechat") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class WeChatProperties { + + /** + * 小程序的appid,是小程序在微信平台上的唯一标识,用于区分不同的小程序应用, + * 在与微信小程序进行交互时,如调用微信登录、获取用户信息等接口操作,都需要提供这个appid来进行身份验证和授权,确保操作是针对特定的小程序进行的。 + */ + private String appid; + + /** + * 小程序的秘钥,是用于保障小程序与微信服务器之间通信安全的重要密钥, + * 例如在获取小程序的访问令牌(access token)等涉及安全验证的操作中,会结合这个秘钥来生成签名等信息,确保请求的合法性和数据的保密性,防止非法访问和数据篡改。 + */ + private String secret; + + /** + * 商户号,是在微信支付体系中用于标识商家身份的唯一编号, + * 当进行微信支付相关的业务操作,如发起支付、处理退款等流程时,微信支付平台会通过这个商户号来识别是哪个商家在进行操作,关联对应的账户信息、交易记录等内容。 + */ + private String mchid; + + /** + * 商户API证书的证书序列号,用于唯一标识商户的API证书, + * 在使用微信支付的一些高级接口或者涉及到证书验证的操作场景中,微信支付平台会通过这个序列号来验证商户所提供证书的合法性和有效性,确保通信双方的身份可靠。 + */ + private String mchSerialNo; + + /** + * 商户私钥文件,指向存储商户私钥的文件路径,商户私钥是进行加密、签名等安全操作的关键元素, + * 在与微信支付平台进行数据交互时,使用私钥来生成数字签名等,以证明请求是由合法的商户发起的,保障支付交易过程中的安全性和不可抵赖性。 + */ + private String privateKeyFilePath; + + /** + * 证书解密的密钥,用于对微信支付相关证书进行解密操作, + * 在获取和使用微信支付平台提供的一些加密数据、验证证书内容等场景下,需要使用这个密钥来解密相关信息,确保能够正确读取和使用证书中的关键数据。 + */ + private String apiV3Key; + + /** + * 平台证书,指向微信支付平台证书文件的路径,平台证书是微信支付平台用于向商户证明其自身身份合法性的重要凭证, + * 商户在与微信支付进行交互时,通过验证平台证书来确认是与合法的微信支付平台进行通信,保障支付交易的安全性和可靠性。 + */ + private String weChatPayCertFilePath; + + /** + * 支付成功的回调地址,是微信支付平台在支付操作成功后,向商户系统发送支付结果通知的目标URL地址, + * 商户系统需要提供这个有效的回调地址,以便及时获取支付成功的信息,进而进行后续的业务处理,比如更新订单状态、通知用户支付成功等操作。 + */ + private String notifyUrl; + + /** + * 退款成功的回调地址,类似于支付成功的回调地址,不过它是专门用于在微信支付平台完成退款操作成功后,向商户系统发送退款结果通知的目标URL地址, + * 商户系统依据这个回调地址接收到退款成功的通知后,可以进行相应的业务处理,例如更新退款相关的记录、通知用户退款已到账等操作。 + */ + private String refundNotifyUrl; + +} \ No newline at end of file diff --git a/sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java b/sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java new file mode 100644 index 0000000..6e0c261 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java @@ -0,0 +1,205 @@ +package com.sky.utils; + +import com.alibaba.fastjson.JSONObject; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * HttpClientUtil类,是一个Http工具类,主要用于在Java程序中方便地发送HTTP请求(支持GET、POST等常见方式),并获取相应的响应结果, + * 简化了与HTTP协议交互的操作,使得在项目中进行网络请求相关的业务逻辑开发更加便捷高效,避免了重复编写复杂的底层HTTP请求代码。 + */ +public class HttpClientUtil { + + /** + * 定义请求超时时间,单位为毫秒,此处设置为5秒(5 * 1000毫秒),用于控制HTTP请求在连接建立、等待连接可用以及数据传输等阶段的最长等待时间, + * 避免因网络问题等原因导致请求长时间阻塞,影响程序的性能和稳定性,在创建请求配置时会应用这个超时时间。 + */ + static final int TIMEOUT_MSEC = 5 * 1000; + + /** + * 发送GET方式请求的方法,用于向指定的URL发送GET请求,并可携带请求参数,最后返回服务器响应的结果字符串。 + * + * @param url 请求的url,即要访问的目标服务器资源的网络地址,完整地指定了请求的目标位置,例如某个API接口地址等。 + * @param paramMap 请求参数,以Map形式存储,其中键为参数名,值为对应的参数值,可用于向服务器传递一些查询条件、筛选条件等信息,方便服务器根据这些参数返回相应的数据,参数可为空,表示无参数请求。 + * @return 返回响应结果,是服务器接收到请求后返回的内容,通常为JSON字符串、HTML页面内容或者其他符合约定的数据格式,若请求出现异常等情况可能返回空字符串。 + */ + public static String doGet(String url, Map paramMap) { + // 创建Httpclient对象,通过HttpClients.createDefault()方法获取默认配置的可关闭的HttpClient实例,用于后续发起HTTP请求,它是整个请求操作的基础客户端对象。 + CloseableHttpClient httpClient = HttpClients.createDefault(); + + String result = ""; + CloseableHttpResponse response = null; + + try { + // 创建URIBuilder对象,用于构建完整的URI(统一资源标识符),可以方便地在给定基础URL的基础上添加各种参数,构造出符合要求的请求地址。 + URIBuilder builder = new URIBuilder(url); + if (paramMap!= null) { + // 遍历请求参数Map,将每个参数添加到URIBuilder中,使其构建的URI包含相应的查询参数,按照参数名和参数值的对应关系进行添加,形成完整的带参请求地址。 + for (String key : paramMap.keySet()) { + builder.addParameter(key, paramMap.get(key)); + } + } + // 根据构建好的URIBuilder生成最终的URI对象,该对象完整地描述了请求的目标资源位置及相关参数信息。 + URI uri = builder.build(); + + // 创建GET请求对象,使用生成的URI来初始化HttpGet实例,明确此次请求的方式为GET以及请求的具体目标地址。 + HttpGet httpGet = new HttpGet(uri); + + // 发送请求,通过之前创建的HttpClient实例执行HttpGet请求,获取服务器返回的响应对象CloseableHttpResponse,此对象包含了响应的状态码、响应头以及响应体等重要信息。 + response = httpClient.execute(httpGet); + + // 判断响应状态,获取响应的状态码,若状态码为200,表示请求成功,此时将响应体内容(通过EntityUtils.toString方法,指定编码为"UTF-8")读取出来赋值给result变量,作为最终的响应结果返回;若状态码不是200,则返回空字符串。 + if (response.getStatusLine().getStatusCode() == 200) { + result = EntityUtils.toString(response.getEntity(), "UTF-8"); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + // 关闭响应对象,释放相关资源,避免资源泄漏,无论请求是否成功都需要执行此操作。 + response.close(); + // 关闭HttpClient对象,释放其占用的网络连接等资源,确保程序的资源管理良好。 + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return result; + } + + /** + * 发送POST方式请求的方法(用于发送表单形式数据的POST请求),向指定URL发送POST请求,携带以表单形式组织的参数,返回服务器响应的结果字符串,若请求过程中出现IO异常则向上抛出。 + * + * @param url 目标请求的URL地址,指定了请求要发送到的服务器资源位置,同GET请求方法中的url参数作用类似。 + * @param paramMap 请求参数,以Map形式存储,其中键是表单字段名,值为对应字段的值,用于向服务器传递需要处理的数据,比如提交用户注册信息、登录信息等以表单形式组织的数据,参数可为空表示无参数POST请求。 + * @return 返回响应结果,即服务器接收到POST请求后返回的内容,格式根据服务器端的响应设定而定,通常可能是操作结果提示信息、新生成的数据等内容,以字符串形式返回,若请求出现异常等情况则按照异常处理逻辑进行处理。 + * @throws IOException 当在请求执行过程中(如创建请求实体、执行请求、关闭响应等操作涉及到的输入输出操作)出现I/O相关异常时,会将该异常向上抛出,由调用者进行进一步的处理。 + */ + public static String doPost(String url, Map paramMap) throws IOException { + // 创建Httpclient对象,获取默认配置的可关闭的HttpClient实例,用于后续发起HTTP的POST请求操作,作为请求的客户端基础对象。 + CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = null; + String resultString = ""; + + try { + // 创建Http Post请求对象,使用给定的URL初始化HttpPost实例,明确此次请求的方式为POST以及请求的目标地址,后续将在此基础上添加请求参数等内容。 + HttpPost httpPost = new HttpPost(url); + + // 创建参数列表,若传入的请求参数Map不为空,则遍历该Map,将每个参数转换为NameValuePair对象并添加到List中,NameValuePair用于表示键值对形式的参数,方便后续构建表单形式的请求实体。 + if (paramMap!= null) { + List paramList = new ArrayList<>(); + for (Map.Entry param : paramMap.entrySet()) { + paramList.add(new BasicNameValuePair(param.getKey(), param.getValue())); + } + // 模拟表单,通过将参数列表转换为UrlEncodedFormEntity对象来构建表单形式的请求实体,它会对参数进行适当的编码处理(例如对中文等特殊字符进行URL编码),符合HTTP表单提交的规范,然后将该请求实体设置到HttpPost请求对象中,使得请求携带相应的参数信息。 + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList); + httpPost.setEntity(entity); + + } + + // 设置请求配置,通过调用builderRequestConfig方法构建请求配置对象,并设置到HttpPost请求中,该配置包含了连接超时时间、请求获取连接的超时时间以及套接字超时时间等设置,确保请求在合理的时间范围内进行,避免长时间等待。 + httpPost.setConfig(builderRequestConfig()); + + // 执行http请求,使用HttpClient实例执行HttpPost请求,获取服务器返回的响应对象CloseableHttpResponse,其中包含了响应的各种关键信息,如状态码、响应头和响应体等。 + response = httpClient.execute(httpPost); + // 将响应体内容(通过EntityUtils.toString方法,指定编码为"UTF-8")读取出来赋值给resultString变量,作为最终的响应结果返回,若响应体为空或者读取出现异常等情况会按照相应逻辑处理。 + resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); + } catch (Exception e) { + throw e; + } finally { + try { + // 关闭响应对象,释放相关资源,确保资源正确回收,避免资源泄漏,无论请求是否成功都需要执行此操作。 + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return resultString; + } + + /** + * 发送POST方式请求的方法(用于发送JSON格式数据的POST请求),向指定URL发送POST请求,携带以JSON格式组织的参数,返回服务器响应的结果字符串,若请求过程中出现IO异常则向上抛出。 + * + * @param url 目标请求的URL地址,指定了请求要发送到的服务器资源位置,作用与前面的POST方法中的url参数相同。 + * @param paramMap 请求参数,以Map形式存储,用于构建JSON格式的数据,其中键将作为JSON对象中的属性名,值作为对应的属性值,方便向服务器传递复杂的数据结构,参数可为空表示无参数的JSON格式POST请求。 + * @return 返回响应结果,即服务器接收到JSON格式POST请求后返回的内容,格式根据服务器端的响应设定而定,一般可能是处理后的JSON数据、操作提示信息等,以字符串形式返回,若请求出现异常等情况则按照相应的异常处理逻辑进行处理。 + * @throws IOException 当在请求执行过程中(如构造JSON数据、创建请求实体、执行请求、关闭响应等操作涉及到的输入输出操作)出现I/O相关异常时,会将该异常向上抛出,由调用者进行进一步的处理。 + */ + public static String doPost4Json(String url, Map paramMap) throws IOException { + // 创建Httpclient对象,获取默认配置的可关闭的HttpClient实例,作为发起HTTP的JSON格式POST请求的客户端基础对象。 + CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = null; + String resultString = ""; + + try { + // 创建Http Post请求对象,使用给定的URL初始化HttpPost实例,明确此次请求的方式为POST以及请求的目标地址,后续在此基础上构建JSON格式的请求数据。 + HttpPost httpPost = new HttpPost(url); + + if (paramMap!= null) { + // 构造json格式数据,通过遍历请求参数Map,将每个参数添加到JSONObject中,形成一个JSON格式的对象,其中参数名作为JSON对象的属性名,参数值作为对应属性的值,方便以JSON格式向服务器传递数据,符合现在很多基于RESTful API等交互中常用的JSON数据传输规范。 + JSONObject jsonObject = new JSONObject(); + for (Map.Entry param : paramMap.entrySet()) { + jsonObject.put(param.getKey(), param.getValue()); + } + // 创建StringEntity对象,将JSON对象转换为字符串形式,并指定编码为"utf-8",然后设置其内容编码和数据类型(设置为"application/json",表明这是一个JSON格式的数据),最后将该请求实体设置到HttpPost请求对象中,使得请求携带JSON格式的参数信息。 + StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8"); + // 设置请求编码,明确请求实体的编码方式为"utf-8",确保数据在传输过程中的编码一致性,便于服务器正确解析接收到的数据。 + entity.setContentEncoding("utf-8"); + // 设置数据类型,将请求实体的数据类型设置为"application/json",告知服务器此次请求发送的数据是JSON格式的,方便服务器按照相应的解析方式处理接收到的数据。 + entity.setContentType("application/json"); + httpPost.setEntity(entity); + } + + // 设置请求配置,调用builderRequestConfig方法构建请求配置对象,并设置到HttpPost请求中,该配置包含了连接超时时间、请求获取连接的超时时间以及套接字超时时间等设置,保证请求能在合理的时间范围内完成,避免因网络等问题导致请求长时间无响应。 + httpPost.setConfig(builderRequestConfig()); + + // 执行http请求,使用HttpClient实例执行HttpPost请求,获取服务器返回的响应对象CloseableHttpResponse,该对象包含了响应的状态码、响应头以及响应体等重要信息,用于后续获取响应结果。 + response = httpClient.execute(httpPost); + + // 将响应体内容(通过EntityUtils.toString方法,指定编码为"UTF-8")读取出来赋值给resultString变量,作为最终的响应结果返回,若响应体为空或者读取出现异常等情况会按照相应逻辑处理。 + resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); + } catch (Exception e) { + throw e; + } finally { + try { + // 关闭响应对象,释放相关资源,避免资源泄漏,无论请求是否成功都需要执行此操作。 + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return resultString; + } + + /** + * 构建请求配置的私有方法,用于创建一个RequestConfig对象,设置了连接超时时间、请求获取连接的超时时间以及套接字超时时间,均使用类中定义的TIMEOUT_MSEC常量值(5秒), + * 该配置对象用于在发送HTTP请求(如HttpGet、HttpPost等请求)时设置相关的超时限制,确保请求在合理的时间范围内进行,避免因网络问题等导致请求长时间阻塞,影响程序性能和用户体验。 + * + * @return 返回构建好的RequestConfig对象,包含了设置好的各种超时时间配置,供其他发送请求的方法使用来设置请求的超时相关属性。 + */ + private static RequestConfig builderRequestConfig() { + return RequestConfig.custom() + .setConnectTimeout(TIMEOUT_MSEC) + .setConnectionRequestTimeout(TIMEOUT_MSEC) + .setSocketTimeout(TIMEOUT_MSEC).build(); + } + +} \ No newline at end of file