USPS新API创建面单返回非标准格式,如何实现反序列化?
USPS新API返回数据格式解析与反序列化方案
一、数据格式说明
你收到的是Multipart/form-data格式的响应,这是HTTP协议中用于在单个请求/响应中传输多种不同类型数据的标准格式,常用来同时传递结构化数据和二进制文件。
它的核心结构规则:
- 由随机生成的边界字符串(示例中的
--z-zSV9BXZtRNip-8GHCvJoED)分隔不同数据段 - 每个数据段包含头部信息(如
Content-Type、Content-Disposition),用于标注数据类型和唯一标识 - 头部下方是对应的数据内容(JSON字符串、base64编码的PDF数据等)
- 最终以
--边界字符串--标记整个响应结束
二、反序列化实现
无需手动拆分解析,主流编程语言都有成熟库可直接处理该格式,以下是常见语言的实现方案:
Python 实现
使用requests结合requests-toolbelt的多部分解析工具:
import requests import json import base64 from requests_toolbelt.multipart import decoder # 发起请求获取响应(示例,需替换为实际请求参数) response = requests.post("USPS_API接口地址", data=你的请求参数) # 解析Multipart响应 multipart_data = decoder.MultipartDecoder.from_response(response) # 遍历处理每个数据段 for part in multipart_data.parts: # 提取Content-Disposition中的name字段,区分数据类型 disp_header = part.headers.get(b'Content-Disposition').decode('utf-8') data_name = disp_header.split('name="')[1].split('"')[0] if data_name == "labelMetadata": # 解析JSON为字典对象 metadata = json.loads(part.content.decode('utf-8')) print("追踪单号:", metadata["trackingNumber"]) elif data_name == "labelImage": # 解码base64并保存为PDF文件 pdf_bytes = base64.b64decode(part.content) with open("面单文件.pdf", "wb") as f: f.write(pdf_bytes)
Java 实现
使用Apache HttpClient配合Mime4j解析工具:
import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.apache.james.mime4j.parser.MimeStreamParser; import org.apache.james.mime4j.stream.Field; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Base64; public class USPSLabelParser { public static void main(String[] args) throws IOException { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost post = new HttpPost("USPS_API接口地址"); // 设置请求参数(需补充实际请求体) HttpResponse response = client.execute(post); HttpEntity entity = response.getEntity(); byte[] responseBytes = EntityUtils.toByteArray(entity); MimeStreamParser parser = new MimeStreamParser(); parser.setContentHandler(new org.apache.james.mime4j.stream.ContentHandler() { private String currentDataName; @Override public void startField(Field field) { if (field.getName().equalsIgnoreCase("Content-Disposition")) { String headerValue = field.getBody(); currentDataName = headerValue.split("name=\"")[1].split("\"")[0]; } } @Override public void body(org.apache.james.mime4j.stream.BodyDescriptor bd, ByteArrayInputStream is) throws IOException { if ("labelMetadata".equals(currentDataName)) { // 解析JSON为实体类(需提前定义LabelMetadata类,使用Jackson/Gson等库) String jsonStr = new String(is.readAllBytes()); // ObjectMapper mapper = new ObjectMapper(); // LabelMetadata metadata = mapper.readValue(jsonStr, LabelMetadata.class); System.out.println("追踪单号: " + jsonStr); } else if ("labelImage".equals(currentDataName)) { // 解码base64并保存PDF byte[] base64Bytes = is.readAllBytes(); byte[] pdfBytes = Base64.getDecoder().decode(base64Bytes); // Files.write(Paths.get("面单文件.pdf"), pdfBytes); } } }); parser.parse(new ByteArrayInputStream(responseBytes)); } } }
核心思路
- 依赖成熟的HTTP/MIME解析库自动拆分数据段,避免手动处理边界字符串和头部的复杂逻辑
- 通过每个数据段的
name标识区分元数据和面单文件 - JSON段直接用对应语言的JSON序列化工具转成对象
- PDF段解码base64后可直接保存为文件或用于后续业务逻辑
内容的提问来源于stack exchange,提问作者zfixeun
相关产品推荐
相关产品推荐

