HTTP+XML形式完成请求交互
公司让对接精友,需要通过HTTP+XML形式完成数据交互,记录一下吧
XML格式
请求:
xml
<?xml version="1.0" encoding="GBK"?>
<PACKET>
<HEAD>
<UserCode>x</UserCode>
<Password>x</Password>
<RequestSourceCode>请求来源代码 保险公司名称缩写</RequestSourceCode>
<RequestSourceName>请求来源名称 保险公司名称</RequestSourceName>
<RequestSource>推送数据来源 0:PC推送;1:移动推送</RequestSource>
<RequestType>请求类型 001</RequestType>
<OperatingTime>2025-01-05 20:18:01</OperatingTime>
</HEAD>
<BODY>
<ReqInfo>
<IfNewLossFlag>是否包含保单、报案信息 0:否 1:是</IfNewLossFlag>
<AuditLossFlag>核损标记 0:正常定损 1:核损退回进定损 2:追加定损</AuditLossFlag>
<ReturnURL>返回URL http://x.x.x.x/xxxx</ReturnURL>
<RefreshURL>返回刷新URL http://x.x.x.x/yyyy</RefreshURL>
</ReqInfo>
《。。。。。。。。。》
<LossReporting>
<Id>4439A1C2FE603576E050A8C0785033EB</Id>
<ReportCode>201715</ReportCode>
<AccidentCauseCode>出险原因代码</AccidentCauseCode>
<AccidentCauseName>出险原因名称</AccidentCauseName>
<AccidentArea>北京</AccidentArea>
<AccidentWeather>大晴天</AccidentWeather>
</LossReporting>
</BODY>
</PACKET>
响应:
xml
<PACKET>
<HEAD>
<ResponseCode>000</ResponseCode>
<ErrorMessage>成功</ErrorMessage>
</HEAD>
<BODY>
<URL>xxxxxxx</URL>
</BODY>
</PACKET>
pom依赖
xml
<!-- 精友所需依赖 开始-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.14</version>
</dependency>
<!-- 精友所需依赖 结束-->
构建pojo
请求:
java
@XmlRootElement(name = "PACKET")
@XmlAccessorType(XmlAccessType.FIELD)
@Data
public class Packet {
@XmlElement(name = "HEAD")
private Head head;
@XmlElement(name = "BODY")
private Body body;
}
@Data
@XmlAccessorType(XmlAccessType.FIELD)
class Head {
@XmlElement(name = "UserCode")
private String userCode;
@XmlElement(name = "Password")
private String password;
@XmlElement(name = "RequestSourceCode")
private String requestSourceCode;
@XmlElement(name = "RequestSourceName")
private String requestSourceName;
@XmlElement(name = "RequestSource")
private String requestSource;
@XmlElement(name = "RequestType")
private String requestType;
@XmlElement(name = "OperatingTime")
private String operatingTime;
}
@Data
@XmlAccessorType(XmlAccessType.FIELD)
class Body {
@XmlElement(name = "ReqInfo")
private ReqInfo reqInfo;
@XmlElement(name = "EvalLossInfo")
private EvalLossInfo evalLossInfo;
@XmlElement(name = "EvalInsureTerm")
private EvalInsureTerm evalInsureTerm;
@XmlElement(name = "ExtraBusinessInfo")
private ExtraBusinessInfo extraBusinessInfo;
@XmlElement(name = "LossPolicy")
private LossPolicy lossPolicy;
@XmlElement(name = "LossCoverVehicle")
private LossCoverVehicle lossCoverVehicle;
@XmlElement(name = "LossInsured")
private LossInsured lossInsured;
@XmlElement(name = "LossReporting")
private LossReporting lossReporting;
}
//........
响应:(忘记用@Data替换getter/setter了)
java
@XmlRootElement(name = "PACKET")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssessmentResponse {
@XmlElement(name = "HEAD")
private ResponseHead head;
@XmlElement(name = "BODY")
private ResponseBody body;
// getters and setters
public ResponseHead getHead() { return head; }
public void setHead(ResponseHead head) { this.head = head; }
public ResponseBody getBody() { return body; }
public void setBody(ResponseBody body) { this.body = body; }
// 构建成功响应的方法
public static AssessmentResponse success(String url) {
AssessmentResponse response = new AssessmentResponse();
ResponseHead head = new ResponseHead();
head.setResponseCode("000");
head.setErrorMessage("成功");
ResponseBody body = new ResponseBody();
body.setUrl(url);
response.setHead(head);
response.setBody(body);
return response;
}
// 构建失败响应的方法
public static AssessmentResponse error(String errorCode, String errorMessage) {
AssessmentResponse response = new AssessmentResponse();
ResponseHead head = new ResponseHead();
head.setResponseCode(errorCode);
head.setErrorMessage(errorMessage);
ResponseBody body = new ResponseBody();
body.setUrl(""); // 失败时URL为空
response.setHead(head);
response.setBody(body);
return response;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class ResponseHead {
@XmlElement(name = "ResponseCode")
private String responseCode;
@XmlElement(name = "ErrorMessage")
private String errorMessage;
// getters and setters
public String getResponseCode() { return responseCode; }
public void setResponseCode(String responseCode) { this.responseCode = responseCode; }
public String getErrorMessage() { return errorMessage; }
public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
}
@XmlAccessorType(XmlAccessType.FIELD)
class ResponseBody {
@XmlElement(name = "URL")
private String url;
// getters and setters
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
}
工具类
java
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
public class XmlParserUtil {
/**
* 将XML字符串解析为Packet对象(请求)
*/
public static Packet parseXmlToPacket(String xmlContent) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Packet.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader reader = new StringReader(xmlContent);
return (Packet) unmarshaller.unmarshal(reader);
}
/**
* 将AssessmentResponse对象转换为XML字符串(响应)
*/
public static String convertResponseToXml(AssessmentResponse response) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(AssessmentResponse.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
StringWriter writer = new StringWriter();
marshaller.marshal(response, writer);
return writer.toString();
}
/**
* 将Packet对象转换为XML字符串
*/
public static String convertPacketToXml(Packet packet) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Packet.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
StringWriter writer = new StringWriter();
marshaller.marshal(packet, writer);
return writer.toString();
}
}
java
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
public class XmlBuilderUtil {
/**
* 构建请求XML字符串
*/
public static String buildRequestXml(Packet packet) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Packet.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); // 不格式化,减少空格
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); // 不生成XML声明
StringWriter writer = new StringWriter();
// 手动添加XML声明
writer.write("<?xml version=\"1.0\" encoding=\"GBK\"?>");
marshaller.marshal(packet, writer);
return writer.toString();
}
/**
* 构建响应XML字符串
*/
public static String buildResponseXml(AssessmentResponse response) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(AssessmentResponse.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer = new StringWriter();
writer.write("<?xml version=\"1.0\" encoding=\"GBK\"?>");
marshaller.marshal(response, writer);
return writer.toString();
}
/**
* 解析响应XML
*/
public static AssessmentResponse parseResponseXml(String xmlContent) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(AssessmentResponse.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader reader = new StringReader(xmlContent);
return (AssessmentResponse) unmarshaller.unmarshal(reader);
}
}
java
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.claimApp.dto.*;
import com.claimApp.dto.mapper.*;
import com.claimApp.util.UserContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Slf4j
@Component
@Data
public class PacketBuilder {
@Autowired
private CheckcarMapper checkcarMapper;
private Checkcar checkcar;
@Autowired
private ItemkindMapper itemkindMapper;
private List<Itemkind> itemkinds;
@Autowired
private PolicyMapper policyMapper;
private List<Policy> policys;
@Autowired
private RegistMapper registMapper;
private Regist regist;
@Autowired
private TaskMapper taskMapper;
@Autowired
private CheckinfoMapper checkinfoMapper;
@Autowired
private CheckpropMapper checkpropMapper;
@Autowired
private CheckpersonMapper checkpersonMapper;
private Task task;
private Task task() {
if (task == null) {
List<Task> tasks = taskMapper.selectList(new QueryWrapper<Task>().eq("registNo", registNo).eq("TaskId", taskId));
if (tasks != null && tasks.size() > 0 && tasks.get(0) != null) {
task = tasks.get(0);
} else {
throw new RuntimeException("该Task不存在");
}
}
return task;
}
private Checkcar checkcar() {
if (checkcar == null) {
if (task().getLossItemId() != null) {
List<Checkcar> lossItemIds = checkcarMapper.selectList(new QueryWrapper<Checkcar>()
.eq("LossItemId", task().getLossItemId())
// .eq("registNo", registNo)
);
if (lossItemIds != null && lossItemIds.size() > 0 && lossItemIds.get(0) != null) {
checkcar = lossItemIds.get(0);
}/* else {
throw new RuntimeException("找不到checkcar信息");
}*/
} /*else {
throw new RuntimeException("找不到LossItemId");
}*/
}
return checkcar;
}
private List<Itemkind> itemkinds() {
if (itemkinds == null) {
itemkinds = itemkindMapper.selectList(new QueryWrapper<Itemkind>().eq("registNo", registNo));
}
return itemkinds;
}
private List<Policy> policys() {
if (policys == null) {
policys = policyMapper.selectList(new QueryWrapper<Policy>().eq("registNo", registNo));
}
return policys;
}
private Regist regist() {
if (regist == null) {
regist = registMapper.selectOne(new QueryWrapper<Regist>().eq("registNo", registNo));
}
return regist;
}
private String registNo;
private String taskId;
private String lossApprovalId;
/**
* 构建完整的Packet对象
*/
public static Packet buildClaimPacket(PacketBuilder packetBuilder, String registNo, String taskId, String lossApprovalId) {
Packet packet = new Packet();
packetBuilder.setRegistNo(registNo);
packetBuilder.setTaskId(taskId);
packetBuilder.setLossApprovalId(lossApprovalId);
packet.setHead(packetBuilder.buildHead());//请求类型代码数据字典 001 定损请求(理赔------>精友)
packet.setBody(packetBuilder.buildBody());
return packet;
}
/**
* 请求头
*/
private Head buildHead() {
Head head = new Head();
head.setUserCode(""); //
head.setPassword("");//
head.setRequestSourceCode("");//固定为保险公司名称缩写
head.setRequestSourceName("");//固定为保险公司名称
head.setRequestType("001");//请求类型代码数据字典 比如: 001 定损请求(理赔------>精友)
head.setOperatingTime(getDateTime(LocalDateTime.now()));
return head;
}
/**
* 请求体
*/
private Body buildBody() {
Body body = new Body();
body.setReqInfo(buildReqInfo());
body.setEvalLossInfo(buildEvalLossInfo());
// body.setEvalInsureTerm(buildEvalInsureTerm());
// body.setExtraBusinessInfo(buildExtraBusinessInfo());
body.setLossPolicy(buildLossPolicy());
body.setLossCoverVehicle(buildLossCoverVehicle());
body.setLossInsured(buildLossInsured());
body.setLossReporting(buildLossReporting());
return body;
}
private ReqInfo buildReqInfo() {
ReqInfo reqInfo = new ReqInfo();
reqInfo.setIfNewLossFlag("1");//是否包含保单、报案信息 0:否 1:是
reqInfo.setAuditLossFlag("0");//0:正常定损 1:核损退回进定损 2:追加定损
reqInfo.setReturnURL("xxxx");//返回URL
reqInfo.setRefreshURL("xxxx");//返回刷新URL
reqInfo.setSourceType("1");//
return reqInfo;
}
//...
private String getDateTime(LocalDateTime localDateTime) {
if (null == localDateTime) return "";
return localDateTime.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
private String getDate(Date date) {
if (null == date) return "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
}
Service⭐
java
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
@Slf4j
@Service
public class ClaimHttpClientService {
private static final int CONNECTION_TIMEOUT = 30000; // 30秒
private static final int SOCKET_TIMEOUT = 30000; // 30秒
/**
* 发送定损请求到目标系统
* @param packet 请求数据
* @return 响应结果
*/
public AssessmentResponse sendClaimRequest(Packet packet, String url) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
try {
// 构建XML请求体
String xmlContent = XmlBuilderUtil.buildRequestXml(packet);
log.info("XML请求体 : {}", xmlContent);
// 创建HTTP客户端
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECTION_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.build();
httpClient = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.build();
// 创建POST请求
httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/xml; charset=GBK");
httpPost.setHeader("User-Agent", "ClaimSystem/1.0");
// 设置请求体
StringEntity entity = new StringEntity(xmlContent, "GBK");
httpPost.setEntity(entity);
// 执行请求
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
HttpEntity responseEntity = response.getEntity();
String responseXml = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
EntityUtils.consume(responseEntity);
// 解析响应XML
return XmlBuilderUtil.parseResponseXml(responseXml);
} else {
throw new RuntimeException("HTTP请求失败,状态码: " + statusCode);
}
} catch (Exception e) {
throw new RuntimeException("发送定损请求失败: " + e.getMessage(), e);
} finally {
// 清理资源
try {
if (httpPost != null) {
httpPost.releaseConnection();
}
if (httpClient != null) {
httpClient.close();
}
} catch (Exception e) {
// 忽略关闭异常
}
}
}
}
Controller
java
import com.claimApp.common.Result;
import com.claimApp.dictionary.service.PrplinterfaceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/jyclaim")
public class ClaimAssessmentController {
private static final Logger logger = LoggerFactory.getLogger(ClaimAssessmentController.class);
@Autowired
private ClaimHttpClientService claimHttpClientService;
@Resource(name = "prplinterfaceServiceImpl")
private PrplinterfaceService prplinterfaceService;
@Autowired
private PacketBuilder packetBuilder;
/**
* 发送定损请求
*/
@GetMapping("/send")
public Result<String> sendQuickClaimRequest(@RequestParam String registNo, @RequestParam String taskId, @RequestParam String lossApprovalId) {
logger.info("registNo:{},lossApprovalId:{},taskId:{}", registNo, lossApprovalId,taskId);
try {
// 构建报文
Packet packet = PacketBuilder.buildClaimPacket(packetBuilder, registNo, taskId , lossApprovalId);
String url = prplinterfaceService.getUrlByCode("jyclaimLossSend");
// 发送请求到精友
AssessmentResponse response = claimHttpClientService.sendClaimRequest(packet, url);
// 处理响应
if ("000".equals(response.getHead().getResponseCode())) {
logger.info("精友定损请求发送成功,定损URL: {}", response.getBody().getUrl());
return Result.build(response.getBody().getUrl(), HttpStatus.OK.value(), "执行成功");
} else {
return Result.build(null, HttpStatus.BAD_REQUEST.value(), response.getHead().getErrorMessage());
}
} catch (Exception e) {
logger.error("精友定损请求发送异常: {}", e.getMessage(), e);
return Result.build(null, HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
}
}