簡體   English   中英

如何轉換返回列表的簡單方法<String>進入多<String>基於 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM