如何转换一个简单的方法来返回列表< string>将元>基于Smallrye Mutiny?

发布于 2025-02-10 04:15:02 字数 4321 浏览 2 评论 0原文

我正在开发一个应用程序,该应用程序读取XML文件并根据XML中存在的详细信息创建哈希ID。截至目前,一切都可以完美地工作,并且能够获得list< string>

我想使用Smallrye Mutiny将此应用程序转换为反应流,因此我浏览了一些文档,但不明确地了解如何将此应用程序转换为>反应流我不必等待所有XML文件的完成才能返回list< string>。相反,我可以在生成时开始返回multi< string>

以下是我正在使用SAX解析器来创建哈希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();
    });
}

以下是saxhandler将读取XML并创建Hashids:

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

有人可以指导我参加一些示例或提供有关如何将此应用程序转换为smallye mutinty mutinty multi&lt; string&gt; 基于应用程序?

I am developing an application that reads the XML file and creates the Hash ID based on the details present in XML. As of now, everything is working perfectly, and able to get the List<String>.

I would like to convert this application into Reactive Streams using the Smallrye Mutiny so I went through some of the documentation but did not understand clearly how to convert this application into Reactive Streams where I do not have to wait for the completion of all XML file to return the List<String>. Rather I can start returning the Multi<String> as and when the its generated.

Following is the simple XML that I am reading using SAX Parser to create the Hash ID:

<customerList>
    <customer>
        <name>Batman</name>
        <age>25</age>
    </customer>
    <customer>
        <name>Superman</name>
        <age>28</age>
    </customer>
</customerList>

Following is the Main application which will make a call to 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();
    });
}

Following is the SaxHandler which will read the XML and create HashIDs:

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

Following is the 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);
    }

Can someone please guide me to some example or provide some idea on how to convert this application into SmallRye Mutinty Multi<String> based application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终陌 2025-02-17 04:15:02

我认为您可以重构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();
     }

I think you can refactor xmlEventHashGenerator to

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

The test method will look something like:

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

But if you want to concatenate all the hash codes, you can do:

    @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();
     }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文