如何序列化请求?服务报错时需序列化请求存入数据库待重发
解决方案:序列化失败请求并存储到数据库
我来给你梳理下具体的实现思路和代码,帮你把失败的请求完整保存到数据库,方便后续重发:
1. 定义失败请求的持久化实体
首先要创建一个能存储请求关键信息的实体类,这样才能把请求的各个部分持久化到数据库里:
import jakarta.persistence.*; import java.time.LocalDateTime; import java.util.Map; @Entity @Table(name = "failed_requests") public class FailedRequest { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String uri; @Column(nullable = false) private String httpMethod; @ElementCollection private Map<String, String> headers; @Column(columnDefinition = "TEXT") private String requestBody; @Column(nullable = false) private LocalDateTime createdAt; // 构造方法、getter和setter public FailedRequest(String uri, String httpMethod, Map<String, String> headers, String requestBody) { this.uri = uri; this.httpMethod = httpMethod; this.headers = headers; this.requestBody = requestBody; this.createdAt = LocalDateTime.now(); } }
2. 实现请求信息的提取与存储逻辑
接下来需要一个数据库操作的Repository(这里假设你用Spring Data JPA):
import org.springframework.data.jpa.repository.JpaRepository; public interface FailedRequestRepository extends JpaRepository<FailedRequest, Long> { }
然后修改你原来的业务代码,在请求失败时提取并保存请求信息:
import jakarta.ws.rs.core.*; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.List; import java.util.Map; // 依赖注入Repository和Jackson的序列化工具 @Autowired private FailedRequestRepository failedRequestRepo; @Autowired private ObjectMapper objectMapper; // 原有请求逻辑 URI uri = fromUri(config.getUri()).path("/myservice").build(); Client client = ClientProducer.get(); Response response = client .target(uri) .request() .headers(obterCabecalhos()) .accept(MediaType.APPLICATION_JSON) .post(Entity.json(myEntity)); if (response.getStatus() != Response.Status.OK.getStatusCode()) { try { // 1. 把多值请求头转换成单值Map(方便存储) MultivaluedMap<String, String> rawHeaders = obterCabecalhos(); Map<String, String> headersMap = new HashMap<>(); for (Map.Entry<String, List<String>> entry : rawHeaders.entrySet()) { headersMap.put(entry.getKey(), String.join(",", entry.getValue())); } // 2. 序列化请求体为字符串 String requestBody = objectMapper.writeValueAsString(myEntity); // 3. 封装实体并保存到数据库 FailedRequest failedRequest = new FailedRequest( uri.toString(), "POST", headersMap, requestBody ); failedRequestRepo.save(failedRequest); } catch (Exception e) { // 处理序列化或保存异常,建议记录日志 e.printStackTrace(); } throw new TSEIntegracaoException(); }
3. 后续重发的小提示
- 重发时可以从数据库取出
FailedRequest,用保存的URI、头信息和请求体重新构建请求发送 - 可以给实体加个
status字段(比如PENDING/RETRYING/SUCCESS),跟踪重发状态,避免重复处理 - 建议添加
retryCount字段,限制最大重试次数,防止无限循环
内容的提问来源于stack exchange,提问作者Luciano Borges
相关产品推荐
相关产品推荐

