HTTP+XML形式完成请求交互

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());
        }
    }

}
相关推荐
7澄132 分钟前
Java Socket 网络编程实战:从基础通信到线程池优化
java·服务器·网络·网络编程·socket·多线程·客户端
2201_7578308732 分钟前
反射的概念
java·开发语言
Pocker_Spades_A33 分钟前
DeepCore:大模型统一网关,Claude 免费体验与跨模型技术洞察
java·服务器·数据库
Arva .37 分钟前
Spring Boot自动配置原理
java·spring boot·后端
寻星探路39 分钟前
Java EE初阶启程记15---文件操作和IO
java·java-ee
阿巳helloWorld39 分钟前
SpringMVC底层流程解析
java·开发语言
heartbeat..40 分钟前
介绍java中常用于处理 Excel 文件的Apache POI
java·apache·excel·poi
路边草随风41 分钟前
java 实现 flink 读 kafka 写 iceberg
java·flink·kafka
路边草随风42 分钟前
java 实现 flink cdc 读 mysql binlog 按表写入kafka不同topic
java·大数据·mysql·flink