Compare commits
5 Commits
main
...
shan-soutA
| Author | SHA1 | Date | |
|---|---|---|---|
| 948a4a085f | |||
| 8e2215bc2f | |||
| 5c0bb3f3ba | |||
| 0717201c58 | |||
| 95870fbc2b |
@ -108,6 +108,17 @@
|
|||||||
<artifactId>dom4j</artifactId>
|
<artifactId>dom4j</artifactId>
|
||||||
<version>1.6.1</version>
|
<version>1.6.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
420
adxp-adapter/src/main/java/com/qaup/adxp/adapter/dto/AllXml.java
Normal file
420
adxp-adapter/src/main/java/com/qaup/adxp/adapter/dto/AllXml.java
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
package com.qaup.adxp.adapter.dto;
|
||||||
|
|
||||||
|
public class AllXml {
|
||||||
|
// 将原始的 XML 字符串存储为常量
|
||||||
|
public static final String XML_ARR = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
" <Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_ARR</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber>be58e345-7bcf-4cbb-915f-28c16f0e09a4</Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>20171208140658867</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20171208140658867</Svc_SendTimeStamp>\n" +
|
||||||
|
" </Head>\n" +
|
||||||
|
" <Body>\n" +
|
||||||
|
" <DynFlight>\n" +
|
||||||
|
" <FlightId>4155920</FlightId>\n" +
|
||||||
|
" <BizKey>CZ3158-A-20170906230500</BizKey>\n" +
|
||||||
|
" <AirportIATA>TAO</AirportIATA>\n" +
|
||||||
|
" <FLIGHTSTATUS>ARR</FLIGHTSTATUS>\n" +
|
||||||
|
" <RealLanding>20170906230500</RealLanding>\n" +
|
||||||
|
" </DynFlight>\n" +
|
||||||
|
" </Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
public static final String XML_CRAFTSEAT = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
" <Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_CRAFTSEAT</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber>9a6b67e0-f061-4d0d-9a6a-f31328283d54</Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>20171208140658867</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20171208140658867</Svc_SendTimeStamp>\n" +
|
||||||
|
" </Head>\n" +
|
||||||
|
" <Body>\n" +
|
||||||
|
" <DynFlight>\n" +
|
||||||
|
" <FlightId>4155920</FlightId>\n" +
|
||||||
|
" <BizKey>CZ3158-D-20170906230500</BizKey>\n" +
|
||||||
|
" <CraftseatList>\n" +
|
||||||
|
" <Craftseat>\n" +
|
||||||
|
" <Code>32</Code>\n" +
|
||||||
|
" <PlanStart>20170920173500</PlanStart>\n" +
|
||||||
|
" <PlanEnd>20170920171500</PlanEnd>\n" +
|
||||||
|
" <RealStart>20170920173500</RealStart>\n" +
|
||||||
|
" <RealEnd>20170920173500</RealEnd>\n" +
|
||||||
|
" </Craftseat>\n" +
|
||||||
|
" </CraftseatList>\n" +
|
||||||
|
" </DynFlight>\n" +
|
||||||
|
" </Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
// 存储 XML 字符串作为常量
|
||||||
|
public static final String XML_DFIE = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
" <Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_DFIE</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber>97b79684-f755-41a1-82ab-f7e34352c6af</Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>20171208140658867</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20171208140658867</Svc_SendTimeStamp>\n" +
|
||||||
|
" </Head>\n" +
|
||||||
|
" <Body>\n" +
|
||||||
|
" <DynFlightList>\n" +
|
||||||
|
" <DynFlight>\n" +
|
||||||
|
" <FlightId>4155920</FlightId>\n" +
|
||||||
|
" <BizKey>CZ3158-A-20170906230500</BizKey>\n" +
|
||||||
|
" <ConnectId>4155935</ConnectId>\n" +
|
||||||
|
" <ConnectIdBizKey> CZ3158-D-20170906230500</ConnectIdBizKey>\n" +
|
||||||
|
" <PlanDate>20170906</PlanDate>\n" +
|
||||||
|
" <ExecDate>20170906</ExecDate>\n" +
|
||||||
|
" <PlanTime>20170906230500</PlanTime>\n" +
|
||||||
|
" <Airline>SC</Airline>\n" +
|
||||||
|
" <FlightNo>4753</FlightNo>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <InOut>A</InOut>\n" +
|
||||||
|
" <CraftModel>CRJ200</CraftModel>\n" +
|
||||||
|
" <CraftNo>B738L</CraftNo>\n" +
|
||||||
|
" <Task>W/Z</Task>\n" +
|
||||||
|
" <FlightProxy>1</FlightProxy>\n" +
|
||||||
|
" <Terminal>T1</Terminal>\n" +
|
||||||
|
" <RunwayNum>1</RunwayNum>\n" +
|
||||||
|
" <DispatchLevel>一级特勤保障</DispatchLevel>\n" +
|
||||||
|
" <Hasvip>1</Hasvip>\n" +
|
||||||
|
" <AirportList>\n" +
|
||||||
|
" <Airport>\n" +
|
||||||
|
" <AirportIATA>TAO</AirportIATA>\n" +
|
||||||
|
" <AirportStatus>ALT</AirportStatus>\n" +
|
||||||
|
" <PlanTakeoff>20170906232200</PlanTakeoff>\n" +
|
||||||
|
" <AlterTakeoff>20170906232500</AlterTakeoff>\n" +
|
||||||
|
" <RealTakeoff/>\n" +
|
||||||
|
" <PlanLanding/>\n" +
|
||||||
|
" <AlterLanding/>\n" +
|
||||||
|
" <RealLanding/>\n" +
|
||||||
|
" <RouteOrder>1</RouteOrder>\n" +
|
||||||
|
" </Airport>\n" +
|
||||||
|
" <Airport>\n" +
|
||||||
|
" <AirportIATA>HHA</AirportIATA>\n" +
|
||||||
|
" <AirportStatus/>\n" +
|
||||||
|
" <PlanTakeoff/>\n" +
|
||||||
|
" <AlterTakeoff/>\n" +
|
||||||
|
" <RealTakeoff/>\n" +
|
||||||
|
" <PlanLanding>20170906232200</PlanLanding>\n" +
|
||||||
|
" <AlterLanding/>\n" +
|
||||||
|
" <RealLanding/>\n" +
|
||||||
|
" <RouteOrder>1</RouteOrder>\n" +
|
||||||
|
" </Airport>\n" +
|
||||||
|
" </AirportList>\n" +
|
||||||
|
" <ShareFlightList>\n" +
|
||||||
|
" <ShareFlight>\n" +
|
||||||
|
" <Airline>SC</Airline>\n" +
|
||||||
|
" <FlightNo>1234</FlightNo>\n" +
|
||||||
|
" <AirFlightNo>SC1234</AirFlightNo>\n" +
|
||||||
|
" </ShareFlight>\n" +
|
||||||
|
" <ShareFlight>\n" +
|
||||||
|
" <Airline>MU</Airline>\n" +
|
||||||
|
" <FlightNo>2345</FlightNo>\n" +
|
||||||
|
" <AirFlightNo>MU2345</AirFlightNo>\n" +
|
||||||
|
" </ShareFlight>\n" +
|
||||||
|
" </ShareFlightList>\n" +
|
||||||
|
" <VirtualFlightList>\n" +
|
||||||
|
" <VirtualFlight>\n" +
|
||||||
|
" <Airline>SC</Airline>\n" +
|
||||||
|
" <FlightNO>1234</FlightNO>\n" +
|
||||||
|
" <AirFlightNo>SC1234</AirFlightNo>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <DeptAirport>TAO</DeptAirport>\n" +
|
||||||
|
" <ViaAirport>HGH</ViaAirport>\n" +
|
||||||
|
" <DestAirport>SZX</DestAirport>\n" +
|
||||||
|
" </VirtualFlight>\n" +
|
||||||
|
" </VirtualFlightList>\n" +
|
||||||
|
" </DynFlight>\n" +
|
||||||
|
" </DynFlightList>\n" +
|
||||||
|
" </Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
public static final String XML_DFDL ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
"<Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_DFDL</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org>ADXP</Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver>FIDS</Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber></Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>20171208140658867</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20171208140658867</Svc_SendTimeStamp>\n" +
|
||||||
|
"</Head>\n" +
|
||||||
|
"<Body>\n" +
|
||||||
|
"<SerialNum>5-3</SerialNum>\n" +
|
||||||
|
" <DynFlightList>\n" +
|
||||||
|
" <DynFlight>\n" +
|
||||||
|
" <FlightId>4155920</FlightId>\n" +
|
||||||
|
" <BizKey>CZ3158-A-20170906230500</BizKey>\n" +
|
||||||
|
" <ConnectId>4155935</ConnectId>\n" +
|
||||||
|
" <ConnectIdBizKey> CZ3158-D-20170906230500</ConnectIdBizKey>\n" +
|
||||||
|
" <PlanDate>20170906</PlanDate>\n" +
|
||||||
|
" <ExecDate>20170906</ExecDate>\n" +
|
||||||
|
" <PlanTime>20170906230500</PlanTime>\n" +
|
||||||
|
" <Airline>SC</Airline>\n" +
|
||||||
|
" <FlightNo>4753</FlightNo>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <InOut>A</InOut>\n" +
|
||||||
|
" <CraftModel>CRJ200</CraftModel>\n" +
|
||||||
|
" <CraftNo>B738L</CraftNo>\n" +
|
||||||
|
" <Task>W/Z</Task>\n" +
|
||||||
|
" <FlightProxy>1</FlightProxy>\n" +
|
||||||
|
" <Terminal>T1</Terminal>\n" +
|
||||||
|
" <RunwayNum>1</RunwayNum>\n" +
|
||||||
|
" <DispatchLevel>一级特勤保障</DispatchLevel>\n" +
|
||||||
|
" <Hasvip>1</Hasvip>\n" +
|
||||||
|
" <FlightStatus>BOR</FlightStatus>\n" +
|
||||||
|
" <InterFlightStatus>BOR</InterFlightStatus>\n" +
|
||||||
|
" <AirportList>\n" +
|
||||||
|
" <Airport>\n" +
|
||||||
|
" <AirportIATA>TAO</AirportIATA>\n" +
|
||||||
|
" <AirportStatus>ALT</AirportStatus>\n" +
|
||||||
|
" <PlanTakeoff>20170906232200</PlanTakeoff>\n" +
|
||||||
|
" <AlterTakeoff>20170906232500</AlterTakeoff>\n" +
|
||||||
|
" <RealTakeoff></RealTakeoff>\n" +
|
||||||
|
" <PlanLanding></PlanLanding>\n" +
|
||||||
|
" <AlterLanding></AlterLanding>\n" +
|
||||||
|
" <RealLanding></RealLanding>\n" +
|
||||||
|
" <RouteOrder>1</RouteOrder>\n" +
|
||||||
|
" </Airport>\n" +
|
||||||
|
" <Airport>\n" +
|
||||||
|
" <AirportIATA>HHA</AirportIATA>\n" +
|
||||||
|
" <AirportStatus></AirportStatus>\n" +
|
||||||
|
" <PlanTakeoff></PlanTakeoff>\n" +
|
||||||
|
" <AlterTakeoff></AlterTakeoff>\n" +
|
||||||
|
" <RealTakeoff></RealTakeoff>\n" +
|
||||||
|
" <PlanLanding>20170906232200</PlanLanding>\n" +
|
||||||
|
" <AlterLanding></AlterLanding>\n" +
|
||||||
|
" <RealLanding></RealLanding>\n" +
|
||||||
|
" <RouteOrder>1</RouteOrder>\n" +
|
||||||
|
" </Airport>\n" +
|
||||||
|
" </AirportList>\n" +
|
||||||
|
" <ShareFlightList>\n" +
|
||||||
|
" <ShareFlight>\n" +
|
||||||
|
" <Airline>SC</Airline>\n" +
|
||||||
|
" <FlightNo>1234</FlightNo>\n" +
|
||||||
|
" <AirFlightNo>SC1234</AirFlightNo>\n" +
|
||||||
|
" </ShareFlight>\n" +
|
||||||
|
" <ShareFlight>\n" +
|
||||||
|
" <Airline>MU</Airline>\n" +
|
||||||
|
" <FlightNo>2345</FlightNo>\n" +
|
||||||
|
" <AirFlightNo>MU2345</AirFlightNo>\n" +
|
||||||
|
" </ShareFlight>\n" +
|
||||||
|
" </ShareFlightList>\n" +
|
||||||
|
" <VirtualFlightList>\n" +
|
||||||
|
" <VirtualFlight>\n" +
|
||||||
|
" <Airline>SC</Airline>\n" +
|
||||||
|
" <FlightNO>1234</FlightNO>\n" +
|
||||||
|
" <AirFlightNo>SC1234</AirFlightNo>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <DeptAirport>TAO</DeptAirport>\n" +
|
||||||
|
" <ViaAirport>HGH</ViaAirport>\n" +
|
||||||
|
" <DestAirport>SZX</DestAirport>\n" +
|
||||||
|
" </VirtualFlight>\n" +
|
||||||
|
" </VirtualFlightList>\n" +
|
||||||
|
" <AbnStatusList>\n" +
|
||||||
|
" <AbnStatus>\n" +
|
||||||
|
" <AirportIATA>TAO</AirportIATA>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <AbnStatusCode>CAN</AbnStatusCode>\n" +
|
||||||
|
" <AbnStatusDesc>取消</AbnStatusDesc>\n" +
|
||||||
|
" <AbnReasonCode>1001</AbnReasonCode>\n" +
|
||||||
|
" <PublishTime>20170906234200</PublishTime>\n" +
|
||||||
|
" </AbnStatus>\n" +
|
||||||
|
" </AbnStatusList>\n" +
|
||||||
|
" <BorTimeList>\n" +
|
||||||
|
" <BorTime>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <OpenTime>20170920173100</OpenTime>\n" +
|
||||||
|
" <BeginTime>20170920173500</BeginTime>\n" +
|
||||||
|
" <TbrTime>20170920171500</TbrTime>\n" +
|
||||||
|
" <LbdTime>20170920173500</LbdTime>\n" +
|
||||||
|
" <BorEndTime>20170920175500</BorEndTime>\n" +
|
||||||
|
" <CloseTime>20170920175800</CloseTime>\n" +
|
||||||
|
" </BorTime>\n" +
|
||||||
|
" </BorTimeList>\n" +
|
||||||
|
" <CkicList>\n" +
|
||||||
|
" <Ckic>\n" +
|
||||||
|
" <Code>E35</Code>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <PlanStart>20170920173500</PlanStart>\n" +
|
||||||
|
" <PlanEnd>20170920171500</PlanEnd>\n" +
|
||||||
|
" <RealStart>20170920173500</RealStart>\n" +
|
||||||
|
" <RealEnd>20170920173500</RealEnd>\n" +
|
||||||
|
" <Airline>CZ</Airline>\n" +
|
||||||
|
" <Class>0701</Class>\n" +
|
||||||
|
" <OpenType>N</OpenType>\n" +
|
||||||
|
" </Ckic>\n" +
|
||||||
|
" </CkicList>\n" +
|
||||||
|
" <GateList>\n" +
|
||||||
|
" <Gate>\n" +
|
||||||
|
" <Code>32</Code>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <PlanStart>20170920173500</PlanStart>\n" +
|
||||||
|
" <PlanEnd>20170920171500</PlanEnd>\n" +
|
||||||
|
" <RealStart>20170920173500</RealStart>\n" +
|
||||||
|
" <RealEnd>20170920173500</RealEnd>\n" +
|
||||||
|
" </Gate>\n" +
|
||||||
|
" </GateList>\n" +
|
||||||
|
" <AcrslList>\n" +
|
||||||
|
" <Acrsl>\n" +
|
||||||
|
" <Code>32</Code>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <PlanStart>20170920173500</PlanStart>\n" +
|
||||||
|
" <PlanEnd>20170920171500</PlanEnd>\n" +
|
||||||
|
" <RealStart>20170920173500</RealStart>\n" +
|
||||||
|
" <RealEnd>20170920173500</RealEnd>\n" +
|
||||||
|
" </Acrsl>\n" +
|
||||||
|
" </AcrslList>\n" +
|
||||||
|
" <DcrslPosList>\n" +
|
||||||
|
" <DcrslPos>\n" +
|
||||||
|
" <Code>32</Code>\n" +
|
||||||
|
"<DcrslCode>12</DcrslCode>\n" +
|
||||||
|
" <Region>D</Region>\n" +
|
||||||
|
" <PlanStart>20170920173500</PlanStart>\n" +
|
||||||
|
" <PlanEnd>20170920171500</PlanEnd>\n" +
|
||||||
|
" <RealStart>20170920173500</RealStart>\n" +
|
||||||
|
" <RealEnd>20170920173500</RealEnd>\n" +
|
||||||
|
" </DcrslPos>\n" +
|
||||||
|
" </DcrslPosList>\n" +
|
||||||
|
" <CraftseatList>\n" +
|
||||||
|
" <Craftseat>\n" +
|
||||||
|
" <Code>32</Code>\n" +
|
||||||
|
" <PlanStart>20170920173500</PlanStart>\n" +
|
||||||
|
" <PlanEnd>20170920171500</PlanEnd>\n" +
|
||||||
|
" <RealStart>20170920173500</RealStart>\n" +
|
||||||
|
" <RealEnd>20170920173500</RealEnd>\n" +
|
||||||
|
" </Craftseat>\n" +
|
||||||
|
" </CraftseatList>\n" +
|
||||||
|
" </DynFlight>\n" +
|
||||||
|
" </DynFlightList> \n" +
|
||||||
|
"</Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String XML_RUNWAY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
" <Head>\n" +
|
||||||
|
" <Svc_ServiceCode>" +
|
||||||
|
"</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber></Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId> 20200331103923314</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp> 20200331103923314</Svc_SendTimeStamp>\n" +
|
||||||
|
" </Head>\n" +
|
||||||
|
" <Body>\n" +
|
||||||
|
" <Flight>\n" +
|
||||||
|
" <SourceKey>QDCDM</SourceKey>\n" +
|
||||||
|
" <BizKey> SC8775-D-20200331132500</BizKey>\n" +
|
||||||
|
" <RUNWAYDEP>35L</RUNWAYDEP>\n" +
|
||||||
|
" <RUNWAYARR></RUNWAYARR>\n" +
|
||||||
|
" </Flight>\n" +
|
||||||
|
" </Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
public static final String XML_AXOT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
" <Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_CDM_AXOT</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber></Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId> 20200331103923314</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp> 20200331103923314</Svc_SendTimeStamp>\n" +
|
||||||
|
" </Head>\n" +
|
||||||
|
" <Body>\n" +
|
||||||
|
" <Flight>\n" +
|
||||||
|
" <SourceKey>HCDM</SourceKey>\n" +
|
||||||
|
" <BizKey> SC8775-D-20200331132500</BizKey>\n" +
|
||||||
|
" <AXOT>202003311401</AXOT>\n" +
|
||||||
|
" </Flight>\n" +
|
||||||
|
" </Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
public static final String XML_TISFLIGHT = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
" <Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_TISFLIGHT</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>naomsdevc</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver> <Svc_SerialNumber>5b2fc9a7-c40b-4d53-8267-9e9ff36cb7a8</Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>20251110133327781</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20251110133327781</Svc_SendTimeStamp>\n" +
|
||||||
|
" </Head>\n" +
|
||||||
|
" <Body>\n" +
|
||||||
|
" <TisFlight>\n" +
|
||||||
|
" <TisFlightIdentity>\n" +
|
||||||
|
" <FuId>41317B75FC8311BCE0633D411CAC4CEB</FuId>\n" +
|
||||||
|
" <FlNo>CDG4969</FlNo>\n" +
|
||||||
|
" <Carrier>CDG</Carrier>\n" +
|
||||||
|
" <Adep>ZSQD</Adep>\n" +
|
||||||
|
" <Ades>ZLXY</Ades>\n" +
|
||||||
|
" <Stod>20251104123500</Stod>\n" +
|
||||||
|
" <Stoa>20251104145000</Stoa>\n" +
|
||||||
|
" </TisFlightIdentity>\n" +
|
||||||
|
" <TisInfo>\n" +
|
||||||
|
" <DeIceState>132</DeIceState>\n" +
|
||||||
|
" <ContactCross>道口22</ContactCross>\n" +
|
||||||
|
" <CtotInfo>前3后3;</CtotInfo>\n" +
|
||||||
|
" <DepartureCorridor>WFG</DepartureCorridor>\n" +
|
||||||
|
" </TisInfo>\n" +
|
||||||
|
" <TisStateTime>\n" +
|
||||||
|
" <Type>DEP</Type>\n" +
|
||||||
|
" <Seat>APE</Seat>\n" +
|
||||||
|
" <State>TXI</State>\n" +
|
||||||
|
" <Time>20251104123623</Time>\n" +
|
||||||
|
" </TisStateTime>\n" +
|
||||||
|
" </TisFlight>\n" +
|
||||||
|
" </Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String XML_DFDE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
"<Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_DFDE</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>NAOMS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org></Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver></Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber></Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>20171208140658867</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20171208140658867</Svc_SendTimeStamp>\n" +
|
||||||
|
"</Head>\n" +
|
||||||
|
"<Body>\n" +
|
||||||
|
" <DynFlight>\n" +
|
||||||
|
" <FlightId>4155920</FlightId>\n" +
|
||||||
|
" <BizKey>CZ3158-A-20170906230500</BizKey>\n" +
|
||||||
|
" </DynFlight>\n" +
|
||||||
|
"</Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
}
|
||||||
@ -37,4 +37,13 @@ public class FlightMessage {
|
|||||||
public void setContent(String content) {
|
public void setContent(String content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FlightMessage{" +
|
||||||
|
"serviceCode='" + serviceCode + '\'' +
|
||||||
|
", actionCode='" + actionCode + '\'' +
|
||||||
|
", content='" + content + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,13 +15,32 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.Marshaller;
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
import org.w3c.dom.*;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AdxpSdkService {
|
public class AdxpSdkService {
|
||||||
|
|
||||||
@ -186,6 +205,10 @@ public class AdxpSdkService {
|
|||||||
List<FlightMessage> messages = receiveMessages();
|
List<FlightMessage> messages = receiveMessages();
|
||||||
if (!messages.isEmpty()) {
|
if (!messages.isEmpty()) {
|
||||||
log.info("接收到 {} 条消息", messages.size());
|
log.info("接收到 {} 条消息", messages.size());
|
||||||
|
// 单独打印每条消息,使日志更清晰
|
||||||
|
for (int i = 0; i < messages.size(); i++) {
|
||||||
|
log.info("消息 {}: {}", i + 1, messages.get(i));
|
||||||
|
}
|
||||||
// 处理接收到的消息
|
// 处理接收到的消息
|
||||||
processMessages(messages);
|
processMessages(messages);
|
||||||
}
|
}
|
||||||
@ -219,7 +242,6 @@ public class AdxpSdkService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
MessageResult result = adxpClient.receiveMessage();
|
MessageResult result = adxpClient.receiveMessage();
|
||||||
|
|
||||||
// 使用统一的错误码处理方法
|
// 使用统一的错误码处理方法
|
||||||
if (handleMessageResultError(result)) {
|
if (handleMessageResultError(result)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -231,17 +253,24 @@ public class AdxpSdkService {
|
|||||||
|
|
||||||
List<FlightMessage> messages = new ArrayList<>();
|
List<FlightMessage> messages = new ArrayList<>();
|
||||||
MessageList messageList = result.getMessageList();
|
MessageList messageList = result.getMessageList();
|
||||||
|
|
||||||
|
// 处理XML字符串
|
||||||
|
List<String> messageStringList = result.getMessageStringList();
|
||||||
|
|
||||||
|
|
||||||
if (messageList != null && messageList.getMsg() != null) {
|
if (messageList != null && messageList.getMsg() != null) {
|
||||||
for (MsgType msg : messageList.getMsg()) {
|
for (int i = 0; i < messageList.getMsg().size(); i++) {
|
||||||
|
MsgType msg = messageList.getMsg().get(i); // 获取 MsgType
|
||||||
|
String messageString = messageStringList.get(i); // 获取对应的字符串
|
||||||
HeadType head = msg.getHead();
|
HeadType head = msg.getHead();
|
||||||
Object body = msg.getBody();
|
Object body = msg.getBody();
|
||||||
|
|
||||||
if (head != null && body != null) {
|
if (head != null && body != null) {
|
||||||
|
//log.info("本条消息的接收到消息头{},消息体{}", head.getSvcServiceCode(), messageString);
|
||||||
FlightMessage flightMessage = new FlightMessage(
|
FlightMessage flightMessage = new FlightMessage(
|
||||||
head.getSvcServiceCode(),
|
head.getSvcServiceCode(),
|
||||||
null, // actionCode 在 body 中
|
null, // actionCode 在 body 中
|
||||||
body.toString()
|
messageString
|
||||||
);
|
);
|
||||||
messages.add(flightMessage);
|
messages.add(flightMessage);
|
||||||
}
|
}
|
||||||
@ -266,8 +295,47 @@ public class AdxpSdkService {
|
|||||||
/**
|
/**
|
||||||
* 处理接收到的消息并广播到WebSocket客户端
|
* 处理接收到的消息并广播到WebSocket客户端
|
||||||
*/
|
*/
|
||||||
private void processMessages(List<FlightMessage> messages) {
|
private void processMessages(List<FlightMessage> messages) throws ParserConfigurationException, IOException, SAXException {
|
||||||
if (messages != null && !messages.isEmpty()) {
|
if (messages != null && !messages.isEmpty()) {
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
for (FlightMessage message : messages){
|
||||||
|
String txt = message.getContent();
|
||||||
|
//log.info("接收到的XML字符串:{}", txt);
|
||||||
|
// 解析 XML 字符串
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
InputStream is = new ByteArrayInputStream(txt.getBytes("UTF-8"));
|
||||||
|
Document document = builder.parse(is);
|
||||||
|
|
||||||
|
log.info("事件的类型是{}",message.getServiceCode());
|
||||||
|
switch (message.getServiceCode()){
|
||||||
|
case "ADXP_NAOMS_O_DYN_DFDL":
|
||||||
|
handleDFDL(document);
|
||||||
|
break;
|
||||||
|
case "ADXP_NAOMS_O_DYN_CRAFTSEAT":
|
||||||
|
handleCRAFTSEAT(document);
|
||||||
|
break;
|
||||||
|
case "ADXP_NAOMS_O_DYN_ARR":
|
||||||
|
handleARR(document);
|
||||||
|
break;
|
||||||
|
case "ADXP_NAOMS_O_DYN_DFIE":
|
||||||
|
handleDFIE(document);
|
||||||
|
break;
|
||||||
|
case "ADXP_NAOMS_O_CDM_AXOT":
|
||||||
|
handleAXOT(document);
|
||||||
|
break;
|
||||||
|
case "ADXP_NAOMS_O_CDM_RUNWAY":
|
||||||
|
handleRUNWAY(document);
|
||||||
|
break;
|
||||||
|
case "ADXP_NAOMS_O_DYN_TISFLIGHT":
|
||||||
|
handleTISFLIGHT(document);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("未定义的消息");
|
||||||
|
handleNEW(txt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log.info("接收到 {} 条消息,准备广播", messages.size());
|
log.info("接收到 {} 条消息,准备广播", messages.size());
|
||||||
// 将消息广播到WebSocket客户端
|
// 将消息广播到WebSocket客户端
|
||||||
@ -367,4 +435,208 @@ public class AdxpSdkService {
|
|||||||
|
|
||||||
return health;
|
return health;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*向数据中台发送 动态航班请求事件RQDF
|
||||||
|
*/
|
||||||
|
public MessageResult sendMessage(List<String> message) {
|
||||||
|
if (!connected) {
|
||||||
|
log.error("ADXP数据中台未连接,无法发送消息");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<Msg>\n" +
|
||||||
|
"<Head>\n" +
|
||||||
|
" <Svc_ServiceCode>ADXP_NAOMS_O_DYN_RQDF</Svc_ServiceCode>\n" +
|
||||||
|
" <Svc_Version>1.0</Svc_Version>\n" +
|
||||||
|
" <Svc_Sender_Org>ADXP</Svc_Sender_Org>\n" +
|
||||||
|
" <Svc_Sender>FIDS</Svc_Sender>\n" +
|
||||||
|
" <Svc_Receiver_Org>ADXP</Svc_Receiver_Org>\n" +
|
||||||
|
" <Svc_Receiver>NAOMS</Svc_Receiver>\n" +
|
||||||
|
" <Svc_SerialNumber></Svc_SerialNumber>\n" +
|
||||||
|
" <Svc_SessionId>2017120814065886</Svc_SessionId>\n" +
|
||||||
|
" <Svc_SendTimeStamp>20171208140658867</Svc_SendTimeStamp>\n" +
|
||||||
|
"</Head>\n" +
|
||||||
|
"<Body>\n" +
|
||||||
|
" <Request>\n" +
|
||||||
|
" <PlanDate>20171209</PlanDate>\n" +
|
||||||
|
" </Request> \n" +
|
||||||
|
"</Body>\n" +
|
||||||
|
"</Msg>";
|
||||||
|
List<String> xmls = new ArrayList<>();
|
||||||
|
xmls.add( xml);
|
||||||
|
adxpClient.sendMessage(xmls);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 动态航班响应事件DFDL 消息
|
||||||
|
* @param document
|
||||||
|
*/
|
||||||
|
private static void handleDFDL(Document document) {
|
||||||
|
// 获取 <Body> 元素下的 <DynFlightList>
|
||||||
|
NodeList dynFlightNodes = document.getElementsByTagName("DynFlight");
|
||||||
|
if (dynFlightNodes.getLength() > 0) {
|
||||||
|
Element dynFlight = (Element) dynFlightNodes.item(0);
|
||||||
|
|
||||||
|
// 提取所需的值
|
||||||
|
String flightId = getElementValue(dynFlight, "FlightId");
|
||||||
|
String inOut = getElementValue(dynFlight, "InOut");
|
||||||
|
String runwayNum = getElementValue(dynFlight, "RunwayNum");
|
||||||
|
|
||||||
|
// 输出提取的值
|
||||||
|
|
||||||
|
log.info("动态航班信息: {}", flightId);
|
||||||
|
log.info("动态航班信息: {}", inOut);
|
||||||
|
log.info("动态航班信息: {}", runwayNum);
|
||||||
|
log.info("RunwayNum: " + runwayNum);
|
||||||
|
|
||||||
|
// 获取 CraftseatList 并提取 Code
|
||||||
|
NodeList craftseatListNodes = dynFlight.getElementsByTagName("CraftseatList");
|
||||||
|
if (craftseatListNodes.getLength() > 0) {
|
||||||
|
Element craftseatList = (Element) craftseatListNodes.item(0);
|
||||||
|
NodeList craftseatNodes = craftseatList.getElementsByTagName("Craftseat");
|
||||||
|
|
||||||
|
for (int i = 0; i < craftseatNodes.getLength(); i++) {
|
||||||
|
Element craftseat = (Element) craftseatNodes.item(i);
|
||||||
|
|
||||||
|
// 提取 Code
|
||||||
|
String code = getElementValue(craftseat, "Code");
|
||||||
|
|
||||||
|
// 输出提取的值
|
||||||
|
log.info("Craftseat Code: " + code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 运行跑道响应事件RUNWAY 消息
|
||||||
|
* @param document
|
||||||
|
*/
|
||||||
|
private static void handleRUNWAY(Document document) {
|
||||||
|
// 获取 <Flight> 元素
|
||||||
|
NodeList flightList = document.getElementsByTagName("Flight");
|
||||||
|
if (flightList.getLength() > 0) {
|
||||||
|
Element flightElement = (Element) flightList.item(0);
|
||||||
|
|
||||||
|
// 提取 BizKey
|
||||||
|
String bizKey = getElementValue(flightElement, "BizKey");
|
||||||
|
log.info("BizKey: " + bizKey);
|
||||||
|
|
||||||
|
// 提取 RUNWAYDEP
|
||||||
|
String runwayDep = getElementValue(flightElement, "RUNWAYDEP");
|
||||||
|
log.info("RUNWAYDEP: " + runwayDep);
|
||||||
|
|
||||||
|
// 提取 RUNWAYARR
|
||||||
|
String runwayArr = getElementValue(flightElement, "RUNWAYARR");
|
||||||
|
log.info("RunwayArr: " + runwayArr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void handleCRAFTSEAT(Document document) {
|
||||||
|
// 获取 <DynFlight> 元素
|
||||||
|
NodeList dynFlightList = document.getElementsByTagName("DynFlight");
|
||||||
|
if (dynFlightList.getLength() > 0) {
|
||||||
|
Element dynFlightElement = (Element) dynFlightList.item(0);
|
||||||
|
|
||||||
|
// 提取 FlightId
|
||||||
|
String flightId = getElementValue(dynFlightElement, "FlightId");
|
||||||
|
log.info("FlightId: " + flightId);
|
||||||
|
|
||||||
|
// 获取 CraftseatList 元素
|
||||||
|
NodeList craftseatList = dynFlightElement.getElementsByTagName("Craftseat");
|
||||||
|
if (craftseatList.getLength() > 0) {
|
||||||
|
Element craftseatElement = (Element) craftseatList.item(0);
|
||||||
|
|
||||||
|
// 提取 Code
|
||||||
|
String code = getElementValue(craftseatElement, "Code");
|
||||||
|
log.info("Code: " + code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void handleARR(Document document) {
|
||||||
|
// 获取 <Body> 元素
|
||||||
|
NodeList dynFlightNodes = document.getElementsByTagName("DynFlight");
|
||||||
|
if (dynFlightNodes.getLength() > 0) {
|
||||||
|
Element dynFlight = (Element) dynFlightNodes.item(0);
|
||||||
|
|
||||||
|
// 提取所需的值
|
||||||
|
String flightId = getElementValue(dynFlight, "FlightId");
|
||||||
|
String bizKey = getElementValue(dynFlight, "BizKey");
|
||||||
|
log.info("FlightId: " + flightId);
|
||||||
|
log.info("BizKey: " + bizKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void handleAXOT(Document document) {
|
||||||
|
// 获取 <Body> 元素
|
||||||
|
NodeList bodyNodes = document.getElementsByTagName("Body");
|
||||||
|
if (bodyNodes.getLength() > 0) {
|
||||||
|
Element body = (Element) bodyNodes.item(0);
|
||||||
|
|
||||||
|
// 获取 <Flight> 元素
|
||||||
|
NodeList flightNodes = body.getElementsByTagName("Flight");
|
||||||
|
if (flightNodes.getLength() > 0) {
|
||||||
|
Element flight = (Element) flightNodes.item(0);
|
||||||
|
|
||||||
|
// 提取 BizKey 元素的值
|
||||||
|
String bizKey = getElementValue(flight, "BizKey");
|
||||||
|
log.info("BizKey: " + bizKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void handleDFIE(Document document) {
|
||||||
|
// 获取 <DynFlight> 元素
|
||||||
|
NodeList dynFlightNodes = document.getElementsByTagName("DynFlight");
|
||||||
|
if (dynFlightNodes.getLength() > 0) {
|
||||||
|
Element dynFlight = (Element) dynFlightNodes.item(0);
|
||||||
|
// 提取所需的值
|
||||||
|
String flightId = getElementValue(dynFlight, "FlightId");
|
||||||
|
String inOut = getElementValue(dynFlight, "InOut");
|
||||||
|
String runwayNum = getElementValue(dynFlight, "RunwayNum");
|
||||||
|
String bizKey = getElementValue(dynFlight, "BizKey");
|
||||||
|
|
||||||
|
log.info("FlightId: " + flightId);
|
||||||
|
log.info("InOut: " + inOut);
|
||||||
|
log.info("RunwayNum: " + runwayNum);
|
||||||
|
log.info("BizKey: " + bizKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleTISFLIGHT(Document document) {
|
||||||
|
// 获取 <TisFlight> 元素
|
||||||
|
NodeList tisFlightNodes = document.getElementsByTagName("TisFlight");
|
||||||
|
if (tisFlightNodes.getLength() > 0) {
|
||||||
|
Element tisFlight = (Element) tisFlightNodes.item(0);
|
||||||
|
|
||||||
|
// 提取所需的值
|
||||||
|
String fuId = getElementValue(tisFlight, "FuId");
|
||||||
|
String state = getElementValue(tisFlight, "State");
|
||||||
|
String contactCross = getElementValue(tisFlight, "ContactCross");
|
||||||
|
|
||||||
|
// 打印提取的内容
|
||||||
|
|
||||||
|
log.info("FuId: " + fuId);
|
||||||
|
log.info("State: " + state);
|
||||||
|
log.info("ContactCross: " + contactCross);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 未定义的消息
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
private static void handleNEW(String message) {
|
||||||
|
System.out.println("新的报文是: " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取元素的值
|
||||||
|
private static String getElementValue(Element parentElement, String tagName) {
|
||||||
|
NodeList nodeList = parentElement.getElementsByTagName(tagName);
|
||||||
|
if (nodeList.getLength() > 0) {
|
||||||
|
return nodeList.item(0).getTextContent();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.qaup.adxp.adapter.websocket;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.qaup.adxp.adapter.dto.AllXml;
|
||||||
import com.qaup.adxp.adapter.dto.FlightMessage;
|
import com.qaup.adxp.adapter.dto.FlightMessage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -41,7 +42,27 @@ public class AdxpWebSocketHandler extends TextWebSocketHandler {
|
|||||||
// 可以处理一些控制命令,比如心跳
|
// 可以处理一些控制命令,比如心跳
|
||||||
if ("ping".equals(message.getPayload())) {
|
if ("ping".equals(message.getPayload())) {
|
||||||
session.sendMessage(new TextMessage("pong"));
|
session.sendMessage(new TextMessage("pong"));
|
||||||
|
List<FlightMessage> messages = new CopyOnWriteArrayList<>();
|
||||||
|
FlightMessage mgDFIE = new FlightMessage("ADXP_NAOMS_O_DYN_DFIE", "pong", AllXml.XML_DFIE);
|
||||||
|
messages.add(mgDFIE);
|
||||||
|
FlightMessage mgRUNWAY = new FlightMessage("ADXP_NAOMS_O_CDM_RUNWAY", "pong", AllXml.XML_RUNWAY);
|
||||||
|
messages.add(mgRUNWAY);
|
||||||
|
FlightMessage mgCRAFTSEAT = new FlightMessage("ADXP_NAOMS_O_DYN_CRAFTSEAT", "pong", AllXml.XML_CRAFTSEAT);
|
||||||
|
messages.add(mgCRAFTSEAT);
|
||||||
|
FlightMessage mgTISFLIGHT = new FlightMessage("ADXP_NAOMS_O_DYN_TISFLIGHT", "pong", AllXml.XML_TISFLIGHT);
|
||||||
|
messages.add(mgTISFLIGHT);
|
||||||
|
FlightMessage mgAXOT = new FlightMessage("ADXP_NAOMS_O_CDM_AXOT", "pong", AllXml.XML_AXOT);
|
||||||
|
messages.add(mgAXOT);
|
||||||
|
FlightMessage mgARR = new FlightMessage("ADXP_NAOMS_O_DYN_ARR", "pong", AllXml.XML_ARR);
|
||||||
|
messages.add(mgARR);
|
||||||
|
broadcastMessages(messages);
|
||||||
log.debug("发送心跳响应到客户端: sessionId={}", session.getId());
|
log.debug("发送心跳响应到客户端: sessionId={}", session.getId());
|
||||||
|
}else if ("delete".equals(message.getPayload())) {
|
||||||
|
List<FlightMessage> messages = new CopyOnWriteArrayList<>();
|
||||||
|
FlightMessage mgDFIE = new FlightMessage("ADXP_NAOMS_O_DYN_DFDE", "pong", AllXml.XML_DFIE);
|
||||||
|
messages.add(mgDFIE);
|
||||||
|
broadcastMessages(messages);
|
||||||
|
log.debug("收到客户端心跳响应: sessionId={}", session.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,8 @@
|
|||||||
|
|
||||||
数据来源:接入并转发从空管接收到的融合数据
|
数据来源:接入并转发从空管接收到的融合数据
|
||||||
|
|
||||||
1. 接口地址:<http://IP:端口/openApi/getCurrentFlightPositions>
|
1. 接口地址:<http://IP:端口/openApi/getCurrentFlightPositionsPro>
|
||||||
|
弃用接口地址:<http://IP:端口/openApi/getCurrentFlightPositions>
|
||||||
|
|
||||||
2. 请求方式:get,需要在 Header 中携带认证信息,字段名为 Authorization,值为认证接口返回的token
|
2. 请求方式:get,需要在 Header 中携带认证信息,字段名为 Authorization,值为认证接口返回的token
|
||||||
|
|
||||||
|
|||||||
@ -134,8 +134,10 @@ public class FlightNotification {
|
|||||||
* 检查通知是否有效
|
* 检查通知是否有效
|
||||||
*/
|
*/
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
|
// return flightNo != null && !flightNo.trim().isEmpty()
|
||||||
|
// && type != null
|
||||||
|
// && eventTime != null;
|
||||||
return flightNo != null && !flightNo.trim().isEmpty()
|
return flightNo != null && !flightNo.trim().isEmpty()
|
||||||
&& type != null
|
&& type != null;
|
||||||
&& eventTime != null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,12 +6,31 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.web.socket.client.WebSocketClient;
|
import org.springframework.web.socket.client.WebSocketClient;
|
||||||
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class ADXPWebSocketConfig {
|
public class ADXPWebSocketConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public WebSocketClient webSocketClient() {
|
public WebSocketClient webSocketClient() {
|
||||||
return new StandardWebSocketClient();
|
StandardWebSocketClient client = new StandardWebSocketClient();
|
||||||
|
|
||||||
|
Map<String, Object> props = new HashMap<>();
|
||||||
|
// ====== JSR-356 标准配置(一定生效)======
|
||||||
|
props.put("javax.websocket.maxTextMessageBufferSize", 10 * 1024 * 1024); // 10MB
|
||||||
|
props.put("javax.websocket.maxBinaryMessageBufferSize", 10 * 1024 * 1024);
|
||||||
|
|
||||||
|
// ====== Tomcat 实现专用(有则更稳)======
|
||||||
|
props.put("org.apache.tomcat.websocket.textBufferSize", 10 * 1024 * 1024);
|
||||||
|
props.put("org.apache.tomcat.websocket.binaryBufferSize", 10 * 1024 * 1024);
|
||||||
|
|
||||||
|
client.setUserProperties(props);
|
||||||
|
|
||||||
|
client.setUserProperties(props);
|
||||||
|
|
||||||
|
return client;
|
||||||
|
//return new StandardWebSocketClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@ -354,44 +354,43 @@ public class DataCollectorDao {
|
|||||||
* @return 航班路由参数数据
|
* @return 航班路由参数数据
|
||||||
*/
|
*/
|
||||||
public AircraftRouteParamsDTO getAircraftRouteParams(String flightNo, String routeType) {
|
public AircraftRouteParamsDTO getAircraftRouteParams(String flightNo, String routeType) {
|
||||||
try {
|
// try {
|
||||||
String token = authService.getToken(airportBaseUrl);
|
// String token = authService.getToken(airportBaseUrl);
|
||||||
if (token == null) {
|
// if (token == null) {
|
||||||
log.error("无法获取有效的认证token");
|
// log.error("无法获取有效的认证token");
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
String url = UriComponentsBuilder.fromUriString(airportBaseUrl)
|
// String url = UriComponentsBuilder.fromUriString(airportBaseUrl)
|
||||||
.path("/aircraftRouteParamsController/getRouteParams")
|
// .path("/aircraftRouteParamsController/getRouteParams")
|
||||||
.queryParam("flightNo", flightNo)
|
// .queryParam("flightNo", flightNo)
|
||||||
.queryParam("routeType", routeType)
|
// .queryParam("routeType", routeType)
|
||||||
.toUriString();
|
// .toUriString();
|
||||||
|
//
|
||||||
HttpHeaders headers = new HttpHeaders();
|
// HttpHeaders headers = new HttpHeaders();
|
||||||
headers.set("Authorization", token);
|
// headers.set("Authorization", token);
|
||||||
headers.set("Content-Type", "application/json");
|
// headers.set("Content-Type", "application/json");
|
||||||
|
//
|
||||||
HttpEntity<String> requestEntity = new HttpEntity<>(headers);
|
// HttpEntity<String> requestEntity = new HttpEntity<>(headers);
|
||||||
|
// ResponseEntity<Response<AircraftRouteParamsDTO>> response = restTemplate.exchange(
|
||||||
ResponseEntity<Response<AircraftRouteParamsDTO>> response = restTemplate.exchange(
|
// url,
|
||||||
url,
|
// HttpMethod.GET,
|
||||||
HttpMethod.GET,
|
// requestEntity,
|
||||||
requestEntity,
|
// new ParameterizedTypeReference<Response<AircraftRouteParamsDTO>>() {}
|
||||||
new ParameterizedTypeReference<Response<AircraftRouteParamsDTO>>() {}
|
// );
|
||||||
);
|
// Response<AircraftRouteParamsDTO> responseBody = response.getBody();
|
||||||
|
// if (responseBody != null && responseBody.getStatus() == 200) {
|
||||||
Response<AircraftRouteParamsDTO> responseBody = response.getBody();
|
// log.info("成功获取航班路由参数: flightNo={}, routeType={}", flightNo, routeType);
|
||||||
if (responseBody != null && responseBody.getStatus() == 200) {
|
// return responseBody.getData();
|
||||||
log.info("成功获取航班路由参数: flightNo={}, routeType={}", flightNo, routeType);
|
// } else {
|
||||||
return responseBody.getData();
|
// log.warn("获取航班路由参数失败: {}", responseBody != null ? responseBody.getMsg() : "未知错误");
|
||||||
} else {
|
// return null;
|
||||||
log.warn("获取航班路由参数失败: {}", responseBody != null ? responseBody.getMsg() : "未知错误");
|
// }
|
||||||
return null;
|
// } catch (Exception e) {
|
||||||
}
|
// log.error("获取航班路由参数时发生异常: flightNo={}, routeType={}", flightNo, routeType, e);
|
||||||
} catch (Exception e) {
|
// return null;
|
||||||
log.error("获取航班路由参数时发生异常: flightNo={}, routeType={}", flightNo, routeType, e);
|
// }
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -137,7 +137,9 @@ public class DataCollectorService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("通过WebSocket接收到 {} 条航班进出港通知", notifications.size());
|
//log.info("通过WebSocket接收到 {} 条航班进出港通知", notifications.size());
|
||||||
|
log.error("通过WebSocket接收到 {} 条航班进出港通知hhhhhhhhhhhhhhh", notifications.size());
|
||||||
|
log.error("通过WebSocket接收到 {} 条航班进出港通知hhhhhhhhhhhhhhh", notifications);
|
||||||
|
|
||||||
// 将DTO转换为业务对象并处理
|
// 将DTO转换为业务对象并处理
|
||||||
for (FlightNotificationDTO dto : notifications) {
|
for (FlightNotificationDTO dto : notifications) {
|
||||||
@ -681,6 +683,7 @@ public class DataCollectorService {
|
|||||||
if (adxpFlightServiceWebSocketClient != null && adxpFlightServiceWebSocketClient.isConnected()) {
|
if (adxpFlightServiceWebSocketClient != null && adxpFlightServiceWebSocketClient.isConnected()) {
|
||||||
// WebSocket客户端已连接,消息通过WebSocket实时接收
|
// WebSocket客户端已连接,消息通过WebSocket实时接收
|
||||||
log.debug("使用WebSocket客户端接收航班通知");
|
log.debug("使用WebSocket客户端接收航班通知");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,9 +781,32 @@ public class DataCollectorService {
|
|||||||
*/
|
*/
|
||||||
private void cacheFlightNotification(FlightNotification notification) {
|
private void cacheFlightNotification(FlightNotification notification) {
|
||||||
String cacheKey = notification.getFlightNo() + ":" + notification.getType().name();
|
String cacheKey = notification.getFlightNo() + ":" + notification.getType().name();
|
||||||
flightNotificationCache.put(cacheKey, notification);
|
|
||||||
log.debug("缓存航班通知: flightNo={}, type={}, 缓存数量={}",
|
// 检查缓存中是否已有该键值
|
||||||
notification.getFlightNo(), notification.getType(), flightNotificationCache.size());
|
FlightNotification existingNotification = flightNotificationCache.get(cacheKey);
|
||||||
|
if (existingNotification != null) {
|
||||||
|
// 合并通知:新的有值的字段覆盖旧的,没有值的字段延用旧的
|
||||||
|
FlightNotification mergedNotification = FlightNotification.builder()
|
||||||
|
.flightNo(notification.getFlightNo())
|
||||||
|
.type(notification.getType())
|
||||||
|
.runway(notification.getRunway() != null ? notification.getRunway() : existingNotification.getRunway())
|
||||||
|
.contactCross(notification.getContactCross() != null ? notification.getContactCross() : existingNotification.getContactCross())
|
||||||
|
.seat(notification.getSeat() != null ? notification.getSeat() : existingNotification.getSeat())
|
||||||
|
.eventTime(notification.getEventTime() != null ? notification.getEventTime() : existingNotification.getEventTime())
|
||||||
|
.eventDateTime(notification.getEventDateTime() != null ? notification.getEventDateTime() : existingNotification.getEventDateTime())
|
||||||
|
.receivedTime(existingNotification.getReceivedTime()) // 保持接收时间不变
|
||||||
|
.active(notification.getActive() != null ? notification.getActive() : existingNotification.getActive())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
flightNotificationCache.put(cacheKey, mergedNotification);
|
||||||
|
log.info("合并航班通知缓存: flightNo={}, type={}, 缓存数量={}",
|
||||||
|
notification.getFlightNo(), notification.getType(), flightNotificationCache.size());
|
||||||
|
} else {
|
||||||
|
// 缓存中没有该键值,直接放入
|
||||||
|
flightNotificationCache.put(cacheKey, notification);
|
||||||
|
log.info("新增航班通知缓存: flightNo={}, type={}, 缓存数量={}",
|
||||||
|
notification.getFlightNo(), notification.getType(), flightNotificationCache.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -813,13 +839,13 @@ public class DataCollectorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 清理 flightNotificationCache - 使用 eventTime 字段判断
|
// 清理 flightNotificationCache - 使用 eventTime 字段判断
|
||||||
int sizeBefore = flightNotificationCache.size();
|
// int sizeBefore = flightNotificationCache.size();
|
||||||
flightNotificationCache.entrySet().removeIf(entry -> {
|
// flightNotificationCache.entrySet().removeIf(entry -> {
|
||||||
FlightNotification notification = entry.getValue();
|
// FlightNotification notification = entry.getValue();
|
||||||
long eventTime = (notification.getEventTime() != null) ? notification.getEventTime() : 0;
|
// long eventTime = (notification.getEventTime() != null) ? notification.getEventTime() : 0;
|
||||||
return (now - eventTime) > inactiveThreshold;
|
// return (now - eventTime) > inactiveThreshold;
|
||||||
});
|
// });
|
||||||
removedFlightNotifications = sizeBefore - flightNotificationCache.size();
|
// removedFlightNotifications = sizeBefore - flightNotificationCache.size();
|
||||||
|
|
||||||
if (removedMovingObjects > 0 || removedFlightNotifications > 0) {
|
if (removedMovingObjects > 0 || removedFlightNotifications > 0) {
|
||||||
log.info("清理不活跃缓存对象: {} 个移动对象, {} 个航班通知; 剩余: {} 个移动对象, {} 个航班通知",
|
log.info("清理不活跃缓存对象: {} 个移动对象, {} 个航班通知; 剩余: {} 个移动对象, {} 个航班通知",
|
||||||
@ -842,3 +868,4 @@ public class DataCollectorService {
|
|||||||
log.info("缓存已清理");
|
log.info("缓存已清理");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -177,7 +177,7 @@ public class RoutePersistenceService {
|
|||||||
* @param routeType 路由类型(IN/OUT)
|
* @param routeType 路由类型(IN/OUT)
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
private void saveRouteAssignment(String objectName, Long routeId, String routeType) {
|
public void saveRouteAssignment(String objectName, Long routeId, String routeType) {
|
||||||
try {
|
try {
|
||||||
// 查找当前路由信息
|
// 查找当前路由信息
|
||||||
Optional<TransportRoute> currentRoute = transportRouteRepository.findById(routeId);
|
Optional<TransportRoute> currentRoute = transportRouteRepository.findById(routeId);
|
||||||
|
|||||||
@ -4,9 +4,12 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.qaup.collision.datacollector.config.FlightSdkProperties;
|
import com.qaup.collision.datacollector.config.FlightSdkProperties;
|
||||||
import com.qaup.collision.datacollector.dto.FlightNotificationDTO;
|
import com.qaup.collision.datacollector.dto.FlightNotificationDTO;
|
||||||
|
import com.qaup.collision.dataprocessing.service.DataProcessingService;
|
||||||
|
import com.qaup.common.core.redis.RedisCache;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.socket.CloseStatus;
|
import org.springframework.web.socket.CloseStatus;
|
||||||
import org.springframework.web.socket.TextMessage;
|
import org.springframework.web.socket.TextMessage;
|
||||||
import org.springframework.web.socket.WebSocketHandler;
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
@ -38,6 +41,12 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
|
|
||||||
private Thread reconnectThread;
|
private Thread reconnectThread;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataProcessingService dataProcessingService;
|
||||||
|
|
||||||
public AdxpFlightServiceWebSocketClient(WebSocketClient webSocketClient,
|
public AdxpFlightServiceWebSocketClient(WebSocketClient webSocketClient,
|
||||||
FlightSdkProperties properties) {
|
FlightSdkProperties properties) {
|
||||||
this.webSocketClient = webSocketClient;
|
this.webSocketClient = webSocketClient;
|
||||||
@ -49,7 +58,7 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
/**
|
/**
|
||||||
* 启动WebSocket客户端
|
* 启动WebSocket客户端
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
//@PostConstruct
|
||||||
public void start() {
|
public void start() {
|
||||||
if (isRunning.compareAndSet(false, true)) {
|
if (isRunning.compareAndSet(false, true)) {
|
||||||
log.info("启动ADXP航班通知WebSocket客户端");
|
log.info("启动ADXP航班通知WebSocket客户端");
|
||||||
@ -75,6 +84,7 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
public void connect() {
|
public void connect() {
|
||||||
if (!properties.isConfigurationReady()) {
|
if (!properties.isConfigurationReady()) {
|
||||||
log.warn("数据中台航班 SDK 配置不完整,WebSocket客户端将无法正常工作");
|
log.warn("数据中台航班 SDK 配置不完整,WebSocket客户端将无法正常工作");
|
||||||
|
scheduleReconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,20 +169,48 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
isConnected.set(true);
|
isConnected.set(true);
|
||||||
messageCount.set(0); // 重置消息计数
|
messageCount.set(0); // 重置消息计数
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 【新增】用于拼接 WebSocket 分片消息
|
||||||
|
private final StringBuilder partialMessageBuffer = new StringBuilder(1024 * 1024);
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(@NonNull WebSocketSession session, @NonNull WebSocketMessage<?> message) throws Exception {
|
public void handleMessage(@NonNull WebSocketSession session, @NonNull WebSocketMessage<?> message) throws Exception {
|
||||||
if (message instanceof TextMessage) {
|
|
||||||
handleTextMessage(session, (TextMessage) message);
|
if (!(message instanceof TextMessage textMessage)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//每来一片就拼
|
||||||
|
partialMessageBuffer.append(textMessage.getPayload());
|
||||||
|
|
||||||
|
//不是最后一片,直接等
|
||||||
|
if (!textMessage.isLast()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//最后一片,才算一条完整消息
|
||||||
|
String fullPayload = partialMessageBuffer.toString();
|
||||||
|
partialMessageBuffer.setLength(0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 👇 用你原来的逻辑处理
|
||||||
|
handleTextMessage(session, fullPayload);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理完整 WebSocket 消息失败", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (message instanceof TextMessage) {
|
||||||
|
// handleTextMessage(session, (TextMessage) message);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
public void handleTextMessage(WebSocketSession session, String payload) throws Exception {
|
||||||
try {
|
try {
|
||||||
// 解析接收到的消息
|
// // 解析接收到的消息
|
||||||
String payload = message.getPayload();
|
// String payload = message.getPayload();
|
||||||
log.debug("📥 收到WebSocket消息 ({} bytes)", payload.length());
|
|
||||||
|
//log.debug("📥 收到WebSocket消息 ({} bytes)", payload.length());
|
||||||
|
|
||||||
// 增加消息计数
|
// 增加消息计数
|
||||||
messageCount.incrementAndGet();
|
messageCount.incrementAndGet();
|
||||||
|
|
||||||
@ -181,7 +219,8 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
|
|
||||||
if (!notifications.isEmpty()) {
|
if (!notifications.isEmpty()) {
|
||||||
log.info("🛬 接收到 {} 条航班通知", notifications.size());
|
log.info("🛬 接收到 {} 条航班通知", notifications.size());
|
||||||
|
log.error("🛬 接收到 {} 条航班通知", notifications.size());
|
||||||
|
|
||||||
// 通知所有监听器
|
// 通知所有监听器
|
||||||
for (Consumer<List<FlightNotificationDTO>> listener : messageListeners) {
|
for (Consumer<List<FlightNotificationDTO>> listener : messageListeners) {
|
||||||
try {
|
try {
|
||||||
@ -227,7 +266,7 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsPartialMessages() {
|
public boolean supportsPartialMessages() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,11 +277,15 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
// 解析FlightMessage列表
|
// 解析FlightMessage列表
|
||||||
List<FlightMessage> flightMessages =
|
List<FlightMessage> flightMessages =
|
||||||
objectMapper.readValue(jsonContent, new TypeReference<List<FlightMessage>>() {});
|
objectMapper.readValue(jsonContent, new TypeReference<List<FlightMessage>>() {});
|
||||||
|
|
||||||
|
//log.error("📥 收到WebSocket消息 ({})", flightMessages);
|
||||||
|
|
||||||
List<FlightNotificationDTO> notifications = new java.util.ArrayList<>();
|
List<FlightNotificationDTO> notifications = new java.util.ArrayList<>();
|
||||||
|
|
||||||
for (FlightMessage message : flightMessages) {
|
for (FlightMessage message : flightMessages) {
|
||||||
try {
|
try {
|
||||||
|
log.error("获取消息类型: serviceCode={}", message.getServiceCode());
|
||||||
|
//log.error("获取消息内容: content={}", message.getContent());
|
||||||
FlightNotificationDTO dto = parseXmlMessage(message.getServiceCode(), message.getContent());
|
FlightNotificationDTO dto = parseXmlMessage(message.getServiceCode(), message.getContent());
|
||||||
if (dto != null) {
|
if (dto != null) {
|
||||||
notifications.add(dto);
|
notifications.add(dto);
|
||||||
@ -252,7 +295,7 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
errorCount.incrementAndGet();
|
errorCount.incrementAndGet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.error("notifications={}", notifications);
|
||||||
return notifications;
|
return notifications;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("解析消息失败", e);
|
log.error("解析消息失败", e);
|
||||||
@ -272,13 +315,23 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
|
|
||||||
switch (serviceCode) {
|
switch (serviceCode) {
|
||||||
case "ADXP_NAOMS_O_DYN_ARR":
|
case "ADXP_NAOMS_O_DYN_ARR":
|
||||||
return parseArrival(root);
|
//return parseArrival(root);
|
||||||
|
return handleARR(root);
|
||||||
case "ADXP_NAOMS_O_CDM_AXOT":
|
case "ADXP_NAOMS_O_CDM_AXOT":
|
||||||
return parsePushback(root);
|
//return parsePushback(root);
|
||||||
|
return handleAXOT(root);
|
||||||
case "ADXP_NAOMS_O_CDM_RUNWAY":
|
case "ADXP_NAOMS_O_CDM_RUNWAY":
|
||||||
return parseRunway(root);
|
//return parseRunway(root);
|
||||||
|
return handleRUNWAY(root);
|
||||||
case "ADXP_NAOMS_O_DYN_CRAFTSEAT":
|
case "ADXP_NAOMS_O_DYN_CRAFTSEAT":
|
||||||
return parseGate(root);
|
//return parseGate(root);
|
||||||
|
return handleCRAFTSEAT(root);
|
||||||
|
case "ADXP_NAOMS_O_DYN_DFIE":
|
||||||
|
return handleDFIE(root);
|
||||||
|
case "ADXP_NAOMS_O_DYN_TISFLIGHT":
|
||||||
|
return handleTISFLIGHT(root);
|
||||||
|
case "ADXP_NAOMS_O_DYN_DFDE":
|
||||||
|
return handleDFDE(root);
|
||||||
default:
|
default:
|
||||||
log.debug("未知的服务代码: {}", serviceCode);
|
log.debug("未知的服务代码: {}", serviceCode);
|
||||||
return null;
|
return null;
|
||||||
@ -312,7 +365,7 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FlightNotificationDTO parsePushback(org.w3c.dom.Element root) {
|
private FlightNotificationDTO parsePushback(org.w3c.dom.Element root) {
|
||||||
String flightNo = getTextContent(root, "FlightNumber");
|
String flightNo = getTextContent(root, "FlightNumber");
|
||||||
String actualPushback = getTextContent(root, "ActualPushback");
|
String actualPushback = getTextContent(root, "ActualPushback");
|
||||||
@ -439,4 +492,191 @@ public class AdxpFlightServiceWebSocketClient implements WebSocketHandler {
|
|||||||
errorCount.get(),
|
errorCount.get(),
|
||||||
isRunning.get());
|
isRunning.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//处理ARR事件
|
||||||
|
private FlightNotificationDTO handleARR(org.w3c.dom.Element root) {
|
||||||
|
String flightNo = getTextContent(root, "BizKey");
|
||||||
|
//分解BizKey
|
||||||
|
String[] arr = flightNo.split("-", 3); // 最多切 3 段
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
dto.setFlightNo(flightNo);
|
||||||
|
dto.setType("IN");
|
||||||
|
// 存储到Redis
|
||||||
|
if (arr.length >= 3) {
|
||||||
|
try {
|
||||||
|
String key = "flight:" + arr[0]; // 使用航班号作为键
|
||||||
|
redisCache.setCacheMapValue(key, "flightNumber", arr[0]);
|
||||||
|
redisCache.setCacheMapValue(key, "type", arr[1]);
|
||||||
|
redisCache.setCacheMapValue(key, "time", arr[2]);
|
||||||
|
log.info("成功将航班数据存储到Redis: flightNumber={}, type={}, time={}", arr[0], arr[1], arr[2]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("存储航班数据到Redis失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//假装模拟请求接口
|
||||||
|
dataProcessingService.ARR(arr[0]);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FlightNotificationDTO handleDFIE(org.w3c.dom.Element root) {
|
||||||
|
String flightNo = getTextContent(root, "BizKey");
|
||||||
|
String RunwayNum = getTextContent(root, "RunwayNum");
|
||||||
|
String InOut = getTextContent(root, "InOut");
|
||||||
|
//分解BizKey
|
||||||
|
String[] arr = flightNo.split("-", 3); // 最多切 3 段
|
||||||
|
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
dto.setFlightNo(flightNo);
|
||||||
|
if (InOut.equals("A")){
|
||||||
|
dto.setType("IN");
|
||||||
|
}else {
|
||||||
|
dto.setType("OUT");
|
||||||
|
}
|
||||||
|
dto.setRunway(RunwayNum);
|
||||||
|
|
||||||
|
// 存储到Redis
|
||||||
|
if (arr.length >= 3) {
|
||||||
|
try {
|
||||||
|
String key = "flight:" + arr[0]; // 使用航班号作为键
|
||||||
|
redisCache.setCacheMapValue(key, "flightNumber", arr[0]);
|
||||||
|
redisCache.setCacheMapValue(key, "type", arr[1]);
|
||||||
|
redisCache.setCacheMapValue(key, "time", arr[2]);
|
||||||
|
if (InOut.equals("A")){
|
||||||
|
redisCache.setCacheMapValue(key, "inRunway", RunwayNum);
|
||||||
|
}else {
|
||||||
|
redisCache.setCacheMapValue(key, "outRunway", RunwayNum);
|
||||||
|
}
|
||||||
|
log.info("成功将航班数据存储到Redis: flightNumber={}, type={}, time={}", arr[0], arr[1], arr[2]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("存储航班数据到Redis失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理RUNWAY事件
|
||||||
|
private FlightNotificationDTO handleRUNWAY(org.w3c.dom.Element root) {
|
||||||
|
String flightNo = getTextContent(root, "BizKey");
|
||||||
|
String outRunway = getTextContent(root, "RUNWAYDEP");
|
||||||
|
String inRunway = getTextContent(root, "RUNWAYARR");
|
||||||
|
log.error("inRunway-{}",inRunway);
|
||||||
|
log.error("outRunway-{}",outRunway);
|
||||||
|
//分解BizKey
|
||||||
|
String[] arr = flightNo.split("-", 3); // 最多切 3 段
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
dto.setFlightNo(flightNo);
|
||||||
|
if (arr[1].equals("A")){
|
||||||
|
dto.setType("IN");
|
||||||
|
}else {
|
||||||
|
dto.setType("OUT");
|
||||||
|
}
|
||||||
|
// 存储到Redis
|
||||||
|
if (arr.length >= 3) {
|
||||||
|
try {
|
||||||
|
String key = "flight:" + arr[0]; // 使用航班号作为键
|
||||||
|
redisCache.setCacheMapValue(key, "flightNumber", arr[0]);
|
||||||
|
redisCache.setCacheMapValue(key, "type", arr[1]);
|
||||||
|
redisCache.setCacheMapValue(key, "time", arr[2]);
|
||||||
|
if (!inRunway.equals("")){
|
||||||
|
redisCache.setCacheMapValue(key, "inRunway", inRunway);
|
||||||
|
}
|
||||||
|
if (!outRunway.equals("")){
|
||||||
|
redisCache.setCacheMapValue(key, "outRunway", outRunway);
|
||||||
|
}
|
||||||
|
log.info("成功将航班数据存储到Redis: flightNumber={}, type={}, time={}", arr[0], arr[1], arr[2]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("存储航班数据到Redis失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理CRAFTSEAT事件
|
||||||
|
private FlightNotificationDTO handleCRAFTSEAT(org.w3c.dom.Element root) {
|
||||||
|
String flightNo = getTextContent(root, "BizKey");
|
||||||
|
String code = getTextContent(root, "Code");
|
||||||
|
log.error("seat-{}",code);
|
||||||
|
//分解BizKey
|
||||||
|
String[] arr = flightNo.split("-", 3); // 最多切 3 段
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
dto.setFlightNo(flightNo);
|
||||||
|
// 存储到Redis
|
||||||
|
if (arr.length >= 3) {
|
||||||
|
try {
|
||||||
|
String key = "flight:" + arr[0]; // 使用航班号作为键
|
||||||
|
redisCache.setCacheMapValue(key, "flightNumber", arr[0]);
|
||||||
|
redisCache.setCacheMapValue(key, "type", arr[1]);
|
||||||
|
redisCache.setCacheMapValue(key, "time", arr[2]);
|
||||||
|
redisCache.setCacheMapValue(key, "seat", code);
|
||||||
|
log.info("成功将航班数据存储到Redis: flightNumber={}, type={}, time={}", arr[0], arr[1], arr[2]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("存储航班数据到Redis失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FlightNotificationDTO handleTISFLIGHT(org.w3c.dom.Element root) {
|
||||||
|
String flightNumber = getTextContent(root, "FlNo");
|
||||||
|
String contactCross = getTextContent(root, "ContactCross");
|
||||||
|
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
dto.setFlightNo(flightNumber);
|
||||||
|
dto.setType("IN");
|
||||||
|
|
||||||
|
String key = "flight:" + flightNumber;
|
||||||
|
|
||||||
|
try {
|
||||||
|
redisCache.setCacheMapValue(key, "flightNumber", flightNumber);
|
||||||
|
redisCache.setCacheMapValue(key, "contactCross",contactCross);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("存储航班数据到Redis失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FlightNotificationDTO handleAXOT(org.w3c.dom.Element root) {
|
||||||
|
String flightNo = getTextContent(root, "BizKey");
|
||||||
|
//分解BizKey
|
||||||
|
String[] arr = flightNo.split("-", 3); // 最多切 3 段
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
dto.setFlightNo(flightNo);
|
||||||
|
dto.setType("OUT");
|
||||||
|
// 存储到Redis
|
||||||
|
if (arr.length >= 3) {
|
||||||
|
try {
|
||||||
|
String key = "flight:" + arr[0]; // 使用航班号作为键
|
||||||
|
redisCache.setCacheMapValue(key, "flightNumber", arr[0]);
|
||||||
|
redisCache.setCacheMapValue(key, "type", arr[1]);
|
||||||
|
redisCache.setCacheMapValue(key, "time", arr[2]);
|
||||||
|
log.info("成功将航班数据存储到Redis: flightNumber={}, type={}, time={}", arr[0], arr[1], arr[2]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("存储航班数据到Redis失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//假装模拟请求接口
|
||||||
|
dataProcessingService.AXOT(arr[0]);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FlightNotificationDTO handleDFDE(org.w3c.dom.Element root) {
|
||||||
|
String flightNo = getTextContent(root, "BizKey");
|
||||||
|
//分解BizKey
|
||||||
|
String[] arr = flightNo.split("-", 3); // 最多切 3 段
|
||||||
|
FlightNotificationDTO dto = new FlightNotificationDTO();
|
||||||
|
if (arr[1].equals("A")){
|
||||||
|
dto.setType("IN");
|
||||||
|
}else {
|
||||||
|
dto.setType("OUT");
|
||||||
|
}
|
||||||
|
String key = "flight:" + arr[0]; // 使用航班号作为键
|
||||||
|
redisCache.deleteObject(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.qaup.collision.datacollector.websocket;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AdxpWebSocketStarter {
|
||||||
|
|
||||||
|
private final AdxpFlightServiceWebSocketClient client;
|
||||||
|
|
||||||
|
public AdxpWebSocketStarter(AdxpFlightServiceWebSocketClient client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void startWhenReady() {
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import com.qaup.collision.websocket.event.VehicleStatusUpdateEvent;
|
|||||||
import com.qaup.collision.datacollector.service.DataCollectorService;
|
import com.qaup.collision.datacollector.service.DataCollectorService;
|
||||||
import com.qaup.collision.common.model.FlightNotification;
|
import com.qaup.collision.common.model.FlightNotification;
|
||||||
import com.qaup.collision.websocket.event.FlightNotificationEvent;
|
import com.qaup.collision.websocket.event.FlightNotificationEvent;
|
||||||
|
import com.qaup.common.core.redis.RedisCache;
|
||||||
import com.qaup.system.domain.SysVehicleInfo;
|
import com.qaup.system.domain.SysVehicleInfo;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -87,6 +88,9 @@ public class DataProcessingService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
// 从DataCollectorService获取缓存的引用
|
// 从DataCollectorService获取缓存的引用
|
||||||
private Map<String, MovingObject> activeMovingObjectsCache;
|
private Map<String, MovingObject> activeMovingObjectsCache;
|
||||||
|
|
||||||
@ -136,8 +140,8 @@ public class DataProcessingService {
|
|||||||
// 第三步:处理通用车辆状态数据并发送WebSocket更新
|
// 第三步:处理通用车辆状态数据并发送WebSocket更新
|
||||||
processUniversalVehicleStatusUpdates();
|
processUniversalVehicleStatusUpdates();
|
||||||
|
|
||||||
// 第四步:处理航班通知数据并发送WebSocket更新
|
// 第四步:处理航班通知数据并发送WebSocket更新, 暂时关闭改为用websocket接收
|
||||||
processFlightNotificationUpdates();
|
//processFlightNotificationUpdates();
|
||||||
|
|
||||||
// 第五步:执行路径冲突检测
|
// 第五步:执行路径冲突检测
|
||||||
pathConflictDetectionService.detectPathConflicts(currentActiveObjects);
|
pathConflictDetectionService.detectPathConflicts(currentActiveObjects);
|
||||||
@ -488,6 +492,10 @@ public class DataProcessingService {
|
|||||||
DataCollectorService dataCollectorService = applicationContext.getBean(DataCollectorService.class);
|
DataCollectorService dataCollectorService = applicationContext.getBean(DataCollectorService.class);
|
||||||
Map<String, FlightNotification> flightNotificationCache = dataCollectorService.getFlightNotificationCache();
|
Map<String, FlightNotification> flightNotificationCache = dataCollectorService.getFlightNotificationCache();
|
||||||
|
|
||||||
|
// 打印缓存数量
|
||||||
|
log.error("航班通知缓存数量: {}", flightNotificationCache.size());
|
||||||
|
log.error("航班通知缓存内容: {}", flightNotificationCache);
|
||||||
|
|
||||||
if (flightNotificationCache.isEmpty()) {
|
if (flightNotificationCache.isEmpty()) {
|
||||||
log.debug("航班通知缓存为空,跳过处理");
|
log.debug("航班通知缓存为空,跳过处理");
|
||||||
return;
|
return;
|
||||||
@ -1244,6 +1252,7 @@ public class DataProcessingService {
|
|||||||
*/
|
*/
|
||||||
private void publishAircraftRouteUpdateEvent(String flightNo, AircraftRoute route,
|
private void publishAircraftRouteUpdateEvent(String flightNo, AircraftRoute route,
|
||||||
com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO routeParams) {
|
com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO routeParams) {
|
||||||
|
log.error( "发布航空器路由更新事件: flightNo={}", flightNo);
|
||||||
try {
|
try {
|
||||||
// 创建路由更新事件
|
// 创建路由更新事件
|
||||||
com.qaup.collision.websocket.event.AircraftRouteUpdateEvent routeUpdateEvent =
|
com.qaup.collision.websocket.event.AircraftRouteUpdateEvent routeUpdateEvent =
|
||||||
@ -1268,4 +1277,112 @@ public class DataProcessingService {
|
|||||||
log.error("❌ 发布航空器路由更新事件失败: flightNo={}", flightNo, e);
|
log.error("❌ 发布航空器路由更新事件失败: flightNo={}", flightNo, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发查询航班号对应的路由
|
||||||
|
*/
|
||||||
|
public void ARR(String flightNo){
|
||||||
|
String key = "flight:"+flightNo;
|
||||||
|
|
||||||
|
String time =(String) redisCache.getCacheMapValue(key, "time");
|
||||||
|
log.error("time是{}",time);
|
||||||
|
// String inRunway = "35";
|
||||||
|
// String outRunway = "34";
|
||||||
|
// String contactCross = "F1";
|
||||||
|
// String seat = "138";
|
||||||
|
String inRunway = (String) redisCache.getCacheMapValue(key, "inRunway");
|
||||||
|
String outRunway = (String) redisCache.getCacheMapValue(key, "outRunway");
|
||||||
|
String contactCross = (String) redisCache.getCacheMapValue(key, "contactCross");
|
||||||
|
String seat = (String) redisCache.getCacheMapValue(key, "seat");
|
||||||
|
|
||||||
|
log.error("进港参数是{}",inRunway);
|
||||||
|
log.error("出港参数是{}",outRunway);
|
||||||
|
log.error("接触交叉参数是{}",contactCross);
|
||||||
|
log.error("座位参数是{}",seat);
|
||||||
|
|
||||||
|
// 获取DataCollectorDao进行路由数据查询
|
||||||
|
DataCollectorDao dataCollectorDao = applicationContext.getBean(DataCollectorDao.class);
|
||||||
|
AircraftRouteDTO routeData = null;
|
||||||
|
// 进港路由查询
|
||||||
|
routeData = dataCollectorDao.getArrivalRoute(
|
||||||
|
inRunway,
|
||||||
|
outRunway,
|
||||||
|
contactCross,
|
||||||
|
seat);
|
||||||
|
log.error("进港路由数据routeData是{}",routeData);
|
||||||
|
|
||||||
|
// 创建路由参数:目前有用的只有type
|
||||||
|
com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO routeParams = new com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO();
|
||||||
|
routeParams.setFlightNo(flightNo);
|
||||||
|
routeParams.setRouteType("IN");
|
||||||
|
routeParams.setInRunway(inRunway);
|
||||||
|
routeParams.setOutRunway(outRunway);
|
||||||
|
routeParams.setContactCross(contactCross);
|
||||||
|
routeParams.setSeat(seat);
|
||||||
|
|
||||||
|
//处理路由数据并发布
|
||||||
|
handleRouteData(flightNo, routeData, routeParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AXOT(String flightNo){
|
||||||
|
String key = "flight:"+flightNo;
|
||||||
|
|
||||||
|
String time =(String) redisCache.getCacheMapValue(key, "time");
|
||||||
|
log.error("time是{}",time);
|
||||||
|
// String inRunway = "17";
|
||||||
|
// String outRunway = "35";
|
||||||
|
// String startSeat = "201";
|
||||||
|
String inRunway = (String) redisCache.getCacheMapValue(key, "inRunway");
|
||||||
|
String outRunway = (String) redisCache.getCacheMapValue(key, "outRunway");
|
||||||
|
String startSeat = (String) redisCache.getCacheMapValue(key, "startSeat");
|
||||||
|
|
||||||
|
log.error("进港参数是{}",inRunway);
|
||||||
|
log.error("出港参数是{}",outRunway);
|
||||||
|
log.error("起始座位参数是{}",startSeat);
|
||||||
|
|
||||||
|
// 获取DataCollectorDao进行路由数据查询
|
||||||
|
DataCollectorDao dataCollectorDao = applicationContext.getBean(DataCollectorDao.class);
|
||||||
|
AircraftRouteDTO routeData = null;
|
||||||
|
// 进港路由查询
|
||||||
|
routeData = dataCollectorDao.getDepartureRoute(
|
||||||
|
inRunway,
|
||||||
|
outRunway,
|
||||||
|
startSeat);
|
||||||
|
log.error("出港路由数据是routeData是{}",routeData);
|
||||||
|
|
||||||
|
// 创建路由参数:目前有用的只有type
|
||||||
|
com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO routeParams = new com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO();
|
||||||
|
routeParams.setFlightNo(flightNo);
|
||||||
|
routeParams.setRouteType("OUT");
|
||||||
|
routeParams.setInRunway(inRunway);
|
||||||
|
routeParams.setOutRunway(outRunway);
|
||||||
|
routeParams.setStartSeat(startSeat);
|
||||||
|
|
||||||
|
//处理路由数据并发布
|
||||||
|
handleRouteData(flightNo, routeData, routeParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRouteData(String flightNo, AircraftRouteDTO routeData,
|
||||||
|
com.qaup.collision.datacollector.dto.AircraftRouteParamsDTO routeParams){
|
||||||
|
// 步骤3: 处理路由查询结果
|
||||||
|
if (routeData != null) {
|
||||||
|
log.info("🎯 成功获取{}路由数据: 编码={}, 状态={}",
|
||||||
|
routeData.getType(), routeData.getCodes(), routeData.getStatus());
|
||||||
|
|
||||||
|
// 转换DTO为航空器路由对象
|
||||||
|
AircraftRoute aircraftRoute = convertToAircraftRoute(routeData);
|
||||||
|
|
||||||
|
if (aircraftRoute != null) {
|
||||||
|
// 保存路由到数据库
|
||||||
|
saveAircraftRouteToDatabase(flightNo, aircraftRoute);
|
||||||
|
|
||||||
|
// 发布WebSocket路由更新事件
|
||||||
|
publishAircraftRouteUpdateEvent(flightNo, aircraftRoute, routeParams);
|
||||||
|
} else {
|
||||||
|
log.warn("⚠️ 路由数据转换失败: flightNo={}", flightNo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("⚠️ 未获取到路由数据: flightNo={}", flightNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ public class LocationRuleQueryServiceImpl implements LocationRuleQueryService {
|
|||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "locationRules", key = "#location.toString() + '_' + #vehicleType + '_' + #timestamp.toString()")
|
//@Cacheable(value = "locationRules", key = "#location.toString() + '_' + #vehicleType + '_' + #timestamp.toString()")
|
||||||
public List<SpatialRule> findApplicableRules(Point location, MovingObjectType vehicleType, LocalDateTime timestamp) {
|
public List<SpatialRule> findApplicableRules(Point location, MovingObjectType vehicleType, LocalDateTime timestamp) {
|
||||||
try {
|
try {
|
||||||
logger.debug("查询位置适用规则: location={}, vehicleType={}, timestamp={}",
|
logger.debug("查询位置适用规则: location={}, vehicleType={}, timestamp={}",
|
||||||
|
|||||||
@ -36,6 +36,7 @@ public class AircraftRouteUpdateEventListener {
|
|||||||
*/
|
*/
|
||||||
@EventListener
|
@EventListener
|
||||||
public void handleAircraftRouteUpdateEvent(AircraftRouteUpdateEvent event) {
|
public void handleAircraftRouteUpdateEvent(AircraftRouteUpdateEvent event) {
|
||||||
|
log.error("处理航空器路由更新事件: flightNo={}", event.getFlightNo());
|
||||||
try {
|
try {
|
||||||
// 构建WebSocket消息
|
// 构建WebSocket消息
|
||||||
String message = objectMapper.writeValueAsString(new WebSocketMessage(
|
String message = objectMapper.writeValueAsString(new WebSocketMessage(
|
||||||
|
|||||||
@ -236,8 +236,12 @@ public class RedisCache
|
|||||||
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
|
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
|
||||||
{
|
{
|
||||||
redisTemplate.opsForHash().put(key, hKey, value);
|
redisTemplate.opsForHash().put(key, hKey, value);
|
||||||
|
// 统一设置 Hash 的过期时间(对整个 key 生效)
|
||||||
|
//redisTemplate.expire(key, DEFAULT_EXPIRE_TIME, DEFAULT_TIME_UNIT);
|
||||||
|
redisTemplate.expire(key, 24 * DEFAULT_EXPIRE_TIME , DEFAULT_TIME_UNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取Hash中的数据
|
* 获取Hash中的数据
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user