Как подписать XML-документ, содержащий специальные символы, в Java? - PullRequest
0 голосов
/ 02 октября 2018

Я подписываю документ XML, который содержит специальные символы (не-ASCII-символы, такие как ã, á, à, ç и т. Д.), В классе Java, который вызывается системой PeopleSoft.Чтобы избежать каких-либо проблем, я удаляю эти символы, но на самом деле мне нужно распечатать этот подписанный документ с ними.Есть какой-либо способ сделать это?Это образец XML-документа для подписи (он готов к подписи):

<PedidoEnvioLoteRPS xmlns="http://www.prefeitura.sp.gov.br/nfe" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Cabecalho Versao="1" xmlns="">
    <CPFCNPJRemetente>
      <CNPJ>99999999999999</CNPJ>
    </CPFCNPJRemetente>
    <transacao>false</transacao>
    <dtInicio>2018-10-02</dtInicio>
    <dtFim>2018-10-02</dtFim>
    <QtdRPS>1</QtdRPS>
    <ValorTotalServicos>40</ValorTotalServicos>
    <ValorTotalDeducoes>0</ValorTotalDeducoes>
  </Cabecalho>
  <RPS xmlns="">
    <Assinatura>FavH23VVIbPWzlvJ28OZZ26Lv2aEgWfmsdhPN1qQN19UCxv6xzu8fHC50wnji3i3G49DuYoXy354U2IxzooPtZYWv7KFUwWLWC4xJYpNKNLOg3txx4znxDNbdC9l/ot9liIMKHf/8rJdciGMpwUOMxt3z95sFVJDcvx/3si1yQG0TaQsWLLLKHH4rUwfE+OWYBIwp/CWBf1/IRzYsFb/q2UgpvfvU1RaXIgI+aNqwYyKulhfUZItI4nYJTsGcXG0y+iXxW3oRWiCGJ5leOysHyJ4VLJcg/vehwT8f8ZQLhvClKeDQUQpL9ts+9oX4PHdc8WXDgN5ekUmvCHS/GW0ew==</Assinatura>
    <ChaveRPS>
      <InscricaoPrestador>99999999</InscricaoPrestador>
      <SerieRPS>1</SerieRPS>
      <NumeroRPS>180</NumeroRPS>
    </ChaveRPS>
    <TipoRPS>RPS</TipoRPS>
    <DataEmissao>2018-10-02</DataEmissao>
    <StatusRPS>N</StatusRPS>
    <TributacaoRPS>T</TributacaoRPS>
    <ValorServicos>40</ValorServicos>
    <ValorDeducoes>0</ValorDeducoes>
    <CodigoServico>3205</CodigoServico>
    <AliquotaServicos>2</AliquotaServicos>
    <ISSRetido>false</ISSRetido>
    <CPFCNPJTomador>
      <CNPJ>88888888888888</CNPJ>
    </CPFCNPJTomador>
    <RazaoSocialTomador>XPTO S.A.</RazaoSocialTomador>
    <EnderecoTomador>
      <Logradouro>Av do Lago</Logradouro>
      <NumeroEndereco>999</NumeroEndereco>
      <ComplementoEndereco>9 andar - cj. 99</ComplementoEndereco>
      <Bairro>Vila Guilherme</Bairro>
      <Cidade>3505708</Cidade>
      <UF>SP</UF>
      <CEP>99999999</CEP>
    </EnderecoTomador>
    <EmailTomador>teste@teste.com.br</EmailTomador>
    <Discriminacao>Tarifa de antecipação de entrega VR Saúde Familiar: R$ 40,00||||||||||||||||IRRF 1,5% Sob Responsabilidade de VR Benefícios Serv  Proc Ltda conforme I.N. 153/87 e |Lei 7450/85, art. 53 - R$ 0,60|Trib aprox. Lei nº 12.741/12: R$5,38 Federal, R$1,68 Municipal e R$32,94 pelos serviços|Fonte:IBPT/empresometro.com.br  A3S28F 18.2.B|Contrato XPTO|Autorização de Regime especial - SEI 6017.2018/0055420-5 (32600,94)|REALIZE O PAGAMENTO APENAS DE BOLETOS EMITIDOS POR VOCÊ NA ÁREA LOGADA E SEGURA DO SEU|PORTAL RH. PREVINA-SE E EVITE PREJUÍZOS FINANCEIROS.</Discriminacao>
    <ValorCargaTributaria>7.06</ValorCargaTributaria>
    <PercentualCargaTributaria>17.64</PercentualCargaTributaria>
    <FonteCargaTributaria>IBPT</FonteCargaTributaria>
  </RPS>

</PedidoEnvioLoteRPS>

Ява метод, который я использую для подписи:

public void AssinaXML(String ArqAssinar) {

    try {
        /* Creates the DOM document DOM from the file in ArqAssinar */
        DocumentBuilderFactory DocBuilderFactory = DocumentBuilderFactory.newInstance();
        DocBuilderFactory.setNamespaceAware(true);
        DocumentBuilder DocBuilder = DocBuilderFactory.newDocumentBuilder();
        FileInputStream Input = new FileInputStream(ArqAssinar);
        Document Doc = DocBuilder.parse(Input);

        /* Gets the position of the Signature tag */
        Node Tag = Doc.getDocumentElement();

        if (Tag != null) {
            /* Signs the document */
            DOMSignContext DocSignCont = new DOMSignContext(PrivPass, Tag);
            XMLSignature Signature = XmlSignFac.newXMLSignature(SignInfo, KeyInf);
            Signature.sign(DocSignCont);

            /* Creates the Signature tag with the results */
            OutputStream Saida = new FileOutputStream(ArqAssinar);
            TransformerFactory TransformFac = TransformerFactory.newInstance();
            Transformer Transf = TransformFac.newTransformer();
            Transf.transform(new DOMSource(Doc), new StreamResult(Saida));  
        }
        else {
            System.out.println("Java Assinatura_Digital, método AssinaXML - A tag especificada para inserir a assinatura não foi encontrada");
        }
    }
    catch (Exception E) {
        E.PrintStackTrace();
    }
}

Но у меня естьэта ошибка, когда я пытаюсь подписать XML-документ выше:

com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: недопустимый байт 2 3-байтовой последовательности UTF-8,на com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte (неизвестный источник) на com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read (неизвестный источник) на com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load (неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipChar (неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl $ FragmentContentDriver.next (неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next (неизвестный источник) по адресу com.sun.org.apache.xercesinternal.impl.XMLNSDocumentScannerImpl.next (неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument (неизвестный источник) по адресу com.sun.org.apache.xerces.internal.parsers.Xparconfiguration(Неизвестный источник) в com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse (Неизвестный источник) в com.sun.org.apache.xerces.internal.parsers.XMLParser.parse (Неизвестный источник) в com.sun.org.apache.xerces.internal.parsers.DOMParser.parse (Неизвестный источник) на com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse (Неизвестный источник) на javax.xml.parsers.DocumentBuilder.parse (Неизвестный источник) вGVR_Assinatura_Digital.AssinaXML (GVR_Assinatura_Digital.java:551) в GVR_Assinatura_Digital.main (GVR_Assinatura_Digital.java:778)

Кто-нибудь знает, почему это происходит?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я получил решение: я просто обменял это:

FileInputStream Input = new FileInputStream(ArqAssinar);
Document Doc = DocBuilder.parse(Input);

на это:

InputStream Input = new FileInputStream(ArqAssinar);
Reader Leitor = new InputStreamReader(Input, "UTF-8");
InputSource Origem = new InputSource(Leitor);
Document Doc = DocBuilder.parse(Origem);
0 голосов
/ 03 октября 2018

Как сказали комментаторы, вы можете подписать любой действительный документ XML.

Таким образом, реальный вопрос должен быть таким: Как мне создать действительный документ XML, который содержит символы, такие как ã?

Ответ:

  • По умолчанию документы XML кодируются в формате UTF-8
  • Таким образом, вы можете напрямую добавить любой символ в документ XML с помощью кодировки UTF-8последовательность символов Unicode.Ниже приведен действительный документ XML:

Кодировка UTF-8

<test>Ã¥</test>
  • Вы также можете включать символы в качестве символьных объектов.Но если у вас есть символы UTF-8, вам не нужно преобразовывать их в символьные объекты.

Если у вас возникли проблемы с созданием действительного документа XML, содержащего символы, отличные от ASCII, создайте новыйВопрос переполнения стека, который включает фрагмент кода, который (или должен) создавать файл XML.

См. Также:

Статья Microsoft о кодировании символов в XML

...