Я проанализировал xml-ответ от веб-службы, используя анализатор DOM.Я установил некоторые стандартные поля в классе SessionStdFields.java, поля, которые не совпадают, будут назначены как настраиваемые поля, определенные в классе SessionCustomFields.java, который встраивается в класс SessionStdFields с аннотацией @ElementCollection.
Пока все просто отличносинтаксический анализатор встречает такие узлы, как speaker, sessionTime и т. д. Он хранит несколько данных в одном столбце, на который ссылается идентификатор, но я хочу, чтобы он сохранялся таким образом, чтобы эти столбцы были разбиты на строки, на которые ссылается их идентификатор.
This is snippet of xml response from WS.
<session-data>
<session>
<sessionID>236728</sessionID>
<abbreviation>INN-005</abbreviation>
<title>DXC Insurance Platform and OmniChannel Engagement</title>
<abstract>Zero code is our mantra for building insurance applications. With OmniChannel Visual Configurator and OmniChannel UI Framework we can build up new applications quickly without any coding intervention, just by means of a visual canvas where we can drag and drop UI components from a catalog and integrate them with existing PAS REST APIs. The result is a working insurance application, built in minutes, automatically deployed and ready to be used from multiple channels (web, mobile, chatbot, voice).</abstract>
<timesOffered>1</timesOffered>
<capacity>0</capacity>
<type>Innovation</type>
<status>Approved</status>
<length>55</length>
<created>2018-08-03 10:28:21</created>
<modified>2018-08-15 10:32:02</modified>
<published>2018-08-03 11:58:05</published>
<publishedAuthenticated></publishedAuthenticated>
<publicViewPrivateSchedule></publicViewPrivateSchedule>
<privateViewPrivateSchedule></privateViewPrivateSchedule>
<cannotViewOrSchedule></cannotViewOrSchedule>
<isMultiDaySession>false</isMultiDaySession>
<agendaItem>false</agendaItem>
<deletedSessionTimes/>
<sessionTime>
<sessionTimeID>108486</sessionTimeID>
<room>Innovation Room 1</room>
<date>2018-10-31</date>
<time>14:05</time>
<length>55</length>
<capacity>100</capacity>
<registered>4</registered>
<publicViewPrivateSchedule></publicViewPrivateSchedule>
<privateViewPrivateSchedule></privateViewPrivateSchedule>
<cannotViewOrSchedule></cannotViewOrSchedule>
</sessionTime>
<Industry>innovation</Industry>
<Keyword-Search>innovation, omnichannel, visual configurator, user interface, ui, drag and drop, rest api</Keyword-Search>
<Keywords>userInterface</Keywords>
<Keywords>dragAndDrop</Keywords>
<Keywords>restApi</Keywords>
<Keywords>innovation</Keywords>
<Keywords>visualConfigurator</Keywords>
<Keywords>omnichannel</Keywords>
<Keywords>ui</Keywords>
<Operationally-where-do-you-think-your-company-could-use-technology-to-advance-your-companys-strategic-priorities-choose-all-that-apply>improvingWorkplaceAccessThroughMobilitySolutions</Operationally-where-do-you-think-your-company-could-use-technology-to-advance-your-companys-strategic-priorities-choose-all-that-apply>
<Operationally-where-do-you-think-your-company-could-use-technology-to-advance-your-companys-strategic-priorities-choose-all-that-apply>easierToUseEnterpriseToolsApplications</Operationally-where-do-you-think-your-company-could-use-technology-to-advance-your-companys-strategic-priorities-choose-all-that-apply>
<Operationally-where-do-you-think-your-company-could-use-technology-to-advance-your-companys-strategic-priorities-choose-all-that-apply>digitalSolutionsToImproveCustomerIntimacyAndEngage</Operationally-where-do-you-think-your-company-could-use-technology-to-advance-your-companys-strategic-priorities-choose-all-that-apply>
<What-is-your-primary-reason-for-attending-the-DXC-Insurance-Conference>learnAboutTheLatestSoftwareUpdates</What-is-your-primary-reason-for-attending-the-DXC-Insurance-Conference>
<What-is-your-primary-reason-for-attending-the-DXC-Insurance-Conference>learnAboutDxcSolutionsForMyIndustry</What-is-your-primary-reason-for-attending-the-DXC-Insurance-Conference>
<What-is-your-primary-reason-for-attending-the-DXC-Insurance-Conference>learnAboutEnterpriseDigitalTransformationStrategie</What-is-your-primary-reason-for-attending-the-DXC-Insurance-Conference>
<What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>insuranceSoftware</What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>
<What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>platformArchitecture</What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>
<What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>applicationDevelopment</What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>
<What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>digitalTransformation</What-topics-are-you-most-interested-in-hearing-about-choose-all-that-apply>
<Which-of-the-following-functions-is-closest-to-your-role>itLeader</Which-of-the-following-functions-is-closest-to-your-role>
<Which-of-the-following-functions-is-closest-to-your-role>lineOfBusinessHead</Which-of-the-following-functions-is-closest-to-your-role>
<Which-of-the-following-functions-is-closest-to-your-role>riskManager</Which-of-the-following-functions-is-closest-to-your-role>
<Which-of-the-following-functions-is-closest-to-your-role>technologist</Which-of-the-following-functions-is-closest-to-your-role>
<Which-of-the-following-functions-is-closest-to-your-role>cSuiteExecutive</Which-of-the-following-functions-is-closest-to-your-role>
<Which-of-the-following-functions-is-closest-to-your-role>softwareEndUser</Which-of-the-following-functions-is-closest-to-your-role>
<Which-of-the-following-functions-is-closest-to-your-role>businessAnalyst</Which-of-the-following-functions-is-closest-to-your-role>
<speaker>
<userRef>1EAEECA77ED0BA27</userRef>
<fullName>Brian Bacsu</fullName>
<preferredName></preferredName>
<jobTitle>Insurance Global Chief Technologist, Digital Insurance Paltform Engineering and Operations Leader</jobTitle>
<company>DXC Technology</company>
<roles>Speaker</roles>
</speaker>
<speaker>
<userRef>9775AC1F3CB3EEAF</userRef>
<fullName>Pablo Bermejo</fullName>
<preferredName></preferredName>
<jobTitle>Insurance OmniChannel Development Manager</jobTitle>
<company>DXC Technology</company>
<roles>Speaker</roles>
</speaker>
</session>
</session-data>
@Entity
@Table(name = "SESSIONS")
public class SessionStdFields {
@Id
private String sessionID;
private String abbreviation;
private String title;
private String description;
private String timesOffered;
private String capacity;
private String type;
private String status;
private String length;
private String created;
private String modified;
private String published;
private String publishedAuthenticated;
private String publicViewPrivateSchedule;
private String privateViewPrivateSchedule;
private String cannotViewOrSchedule;
private String isMultiDaySession;
private String agendaItem;
@ElementCollection
private List<SessionCustomFields> sessionCustomFields = new ArrayList<>();
@ElementCollection
private List<SessionSpeakerFields> sessionSpeakerFields = new ArrayList<>();
// GETTERS AND SETTERS
}
Это класс SessionCustomFields.java.
@Embeddable
public class SessionCustomFields {
@Column
private String customField;
//GETTER/SETTER
}
Это класс SessionSpeakerFields.java
@Embeddable
public class SessionSpeakerFields {
@Column
private String speakerFields;
//GETTER/SETTER
}
Это класс обслуживания.
@Service
@Component
public class SessionCustomFieldService {
@Autowired
SaveCustomSessionRepo customSessionRepo;
private RestTemplate restTemplate = new RestTemplate();
private String uri = "https://webServicUrl?apiToken=lorem";
public String getAllCustomFields() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> entity = new HttpEntity<>(null, httpHeaders);
String response = restTemplate.postForObject(uri, entity, String.class);
return response;
}
@PostConstruct
public void responseParser() throws Exception {
// Get the DOM Builder Factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Get the DOM BUilder
DocumentBuilder builder = factory.newDocumentBuilder();
// Load and Parse XML document
InputSource src = new InputSource();
src.setCharacterStream(new StringReader(getAllCustomFields()));
Document document = builder.parse(src);
List<SessionStdFields> sessionList = new ArrayList<>();
// Iterating through the nodes and extracting the data.
NodeList nodeList = document.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
// We have encountered a <session> tag
Node node = nodeList.item(i);
if (node instanceof Element) {
SessionStdFields sessionFields = new SessionStdFields();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node cNode = childNodes.item(j);
// Identifying child tag of session encountered.
if (cNode instanceof Element) {
String content = cNode.getTextContent().trim();
switch (cNode.getNodeName()) {
case "sessionID":
sessionFields.setSessionID(content);
break;
case "abbreviation":
sessionFields.setAbbreviation(content);
break;
case "title":
sessionFields.setTitle(content);
break;
case "abstract":
sessionFields.setDescription(content);
break;
case "timesOffered":
sessionFields.setTimesOffered(content);
break;
case "capacity":
sessionFields.setCapacity(content);
break;
case "type":
sessionFields.setType(content);
break;
case "status":
sessionFields.setStatus(content);
break;
case "length":
sessionFields.setLength(content);
break;
case "created":
sessionFields.setCreated(content);
break;
case "modified":
sessionFields.setModified(content);
break;
case "published":
sessionFields.setPublished(content);
break;
case "publishedAuthenticated":
sessionFields.setPublishedAuthenticated(content);
break;
case "publicViewPrivateSchedule":
sessionFields.setPublicViewPrivateSchedule(content);
break;
case "privateViewPrivateSchedule":
sessionFields.setPrivateViewPrivateSchedule(content);
break;
case "cannotViewOrSchedule":
sessionFields.setCannotViewOrSchedule(content);
break;
case "isMultiDaySession":
sessionFields.setIsMultiDaySession(content);
break;
case "agendaItem":
sessionFields.setAgendaItem(content);
break;
default:
if(((Element) cNode).getTagName() == "speaker") {
SessionSpeakerFields sessionSpeakerFields = new SessionSpeakerFields();
sessionSpeakerFields.setSpeakerFields(content);
sessionFields.getSessionSpeakerFields().add(sessionSpeakerFields);
}
else {
SessionCustomFields fields = new SessionCustomFields();
fields.setCustomField(content);
sessionFields.getSessionCustomFields().add(fields);
}}}}
sessionList.add(sessionFields);
}}
for (SessionStdFields sessionFields : sessionList) {
System.out.println(sessionFields);
customSessionRepo.save(sessionFields);
}}}
Данные хранятсяв дБ как:
session_std_fields_sessionid speaker_fields
236728 1EAEECA77ED0BA27
Brian Bacsu
Insurance Global Chief Technologist, Digital Insurance Paltform Engineering and Operations Leader
DXC Technology
Speaker
Что мне нужно, так это.
session_std_fields_sessionid speaker_fields
236728 1EAEECA77ED0BA27
236728 Brian Bacsu
236728 Insurance Global Chief Technologist, Digital Insurance Paltform Engineering and Operations Leader
236728 DXC Technology
236728 Speaker
Было бы лучше, если бы я мог также хранить имя поля в столбце, например.
id field name field value
236728 userRef 1EAEECA77ED0BA27
236728 fullName Brian Bacsu
...... ......... ..........
Заранее спасибо.