![](/img/trans.png)
[英]How to convert a method returning List<String> into Reactive Stream smallrye mutiny?
[英]How to convert a simple method that returns the List<String> into Multi<String> based on Smallrye Mutiny?
我正在開發一個應用程序,它讀取 XML 文件並根據 XML 中的詳細信息創建哈希 ID。 截至目前,一切正常,並且能夠獲得List<String>
。
我想使用Smallrye Mutiny
將此應用程序轉換為Reactive Streams
,所以我瀏覽了一些文檔,但不清楚如何將此應用程序轉換為Reactive Streams
,我不必等待所有 XML 文件完成返回List<String>
。 相反,我可以在Multi<String>
生成時開始返回它。
以下是我正在使用 SAX Parser 創建哈希 ID 的簡單 XML:
<customerList>
<customer>
<name>Batman</name>
<age>25</age>
</customer>
<customer>
<name>Superman</name>
<age>28</age>
</customer>
</customerList>
以下是調用SaxHandler
的主應用程序:
public Multi<String> xmlEventHashGenerator(final InputStream xmlStream) throws SAXException, ParserConfigurationException, IOException {
final SAXParserFactory factory = SAXParserFactory.newInstance();
final SaxHandler saxHandler = new SaxHandler();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.newSAXParser().parse(xmlStream, saxHandler);
return Multi.createFrom().emitter(em ->{
saxHandler.getRootNodes().forEach(contextNode -> {
final String preHashString = contextNode.toString();
try {
final StringBuilder hashId = new StringBuilder();
MessageDigest.getInstance("SHA-256").digest(preHashString.getBytes(StandardCharsets.UTF_8));
hashId.append(DatatypeConverter.printHexBinary(digest).toLowerCase());
em.emit(hashId.toString());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
});
em.complete();
});
}
以下是讀取 XML 並創建SaxHandler
的 SaxHandler:
public class SaxHandler extends DefaultHandler {
@Getter
private final List<String> eventHashIds = new ArrayList<>();
@Getter
private final List<ContextNode> rootNodes = new ArrayList<>();
private final HashMap<String, String> contextHeader = new HashMap<>();
private final String hashAlgorithm;
private ContextNode currentNode = null;
private ContextNode rootNode = null;
private final StringBuilder currentValue = new StringBuilder();
public SaxHandler(final String hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
@Override
public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) {
if (rootNode == null && qName.equals("customer")) {
rootNode = new ContextNode(contextHeader);
currentNode = rootNode;
rootNode.children.add(new ContextNode(rootNode, "type", qName));
}else if (currentNode != null) {
ContextNode n = new ContextNode(currentNode, qName, (String) null);
currentNode.children.add(n);
currentNode = n;
}
}
@Override
public void characters(char[] ch, int start, int length) {
currentValue.append(ch, start, length);
}
@Override
public void endElement(final String uri, final String localName, final String qName) {
if (rootNode != null && !qName.equals("customer")) {
final String value = !currentValue.toString().trim().equals("") ? currentValue.toString().trim() : null;
currentNode.children.add(new ContextNode(currentNode, qName, value));
}
if (qName.equals("customer")) {
rootNodes.add(rootNode);
rootNode = null;
}
currentValue.setLength(0);
}
}
以下是Test
:
@Test
public void xmlTest() throws Exception {
final HashGenerator eventHashGenerator = new HashGenerator();
final InputStream xmlStream = getClass().getResourceAsStream("/customer.xml");
final List<String> eventHashIds = eventHashGenerator.xmlHashGenerator(xmlStream, "sha3-256");
System.out.println("\nGenerated Event Hash Ids : \n" + eventHashIds);
}
有人可以指導我舉一些例子或提供一些關於如何將此應用程序轉換為SmallRye Mutinty Multi<String>
的應用程序的想法嗎?
我認為您可以將xmlEventHashGenerator
重構為
public Multi<String> xmlEventHashGenerator(final InputStream xmlStream) throws SAXException, ParserConfigurationException, IOException {
final SAXParserFactory factory = SAXParserFactory.newInstance();
final SaxHandler saxHandler = new SaxHandler();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.newSAXParser().parse(xmlStream, saxHandler);
return Multi.createFrom()
.iterable( saxHandler.getRootNodes() )
.map( RootNode::toString )
.map( this::convertDatatype );
}
private String convertDatatype(String preHashString) {
try {
// I think we could create the MessageDigest instance only once
byte[] digest = MessageDigest.getInstance( "SHA-256" )
.digest( preHashString.getBytes( StandardCharsets.UTF_8 ) );
return DatatypeConverter.printHexBinary( digest ).toLowerCase();
}
catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException( e );
}
}
測試方法看起來像:
@Test
public void xmlTest() throws Exception {
final HashGenerator eventHashGenerator = new HashGenerator();
final InputStream xmlStream = getClass().getResourceAsStream("/customer.xml");
System.out.println("Generated Event Hash Ids: ");
eventHashGenerator
.xmlHashGenerator(xmlStream)
// Print all the hash codes
.invoke( hash -> System.out.println( hash )
.await().indefinitely();
}
但是如果你想連接所有的哈希碼,你可以這樣做:
@Test
public void xmlTest() throws Exception {
final HashGenerator eventHashGenerator = new HashGenerator();
final InputStream xmlStream = getClass()
.getResourceAsStream("/customer.xml");
String hash = eventHashGenerator
.xmlHashGenerator(xmlStream)
// Concatenate all the results
.collect().with( Collectors.joining() );
// Print the hashcode
.invoke( hashcode -> System.out.println("\nGenerated Event Hash Ids : \n" + hashcode) )
.await().indefinitely();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.