2010-08-04 4 views
4

Je dois envoyer un fichier à mon webservice, mais le webservice suppose que le fichier (byte Array) est un base64Binary.Codage base64 en Java et décodage en C#

Avant le codage, le fichier byteArrayFile est enregistré sur le disque en tant que fichier standard. (Je le fais juste pour le test)

Ainsi, dans mon client Java pour webservice, j'envoie les informations de cette façon:

String file = new sun.misc.BASE64Encoder().encode(byteArrayFile); 
port.sendFileToWebService(file); 

webservice doivent décoder les informations et enregistrer Received fichier sur le disque.

[WebMethod] 
    public string sendFileToWebService(string file) 
    { 

     string dirname = HttpContext.Current.Request.PhysicalApplicationPath + "\\Attachments\\"; 
     if (!System.IO.Directory.Exists(dirname)) 
     { 
      System.IO.Directory.CreateDirectory(dirname); 
     } 
     string filename = dirname + "/" + "file.sim"; 
     WebClient myWebClient = new WebClient(); 
     myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); 
     byte[] byteArray = null; 

     byteArray = Convert.FromBase64String(file.Replace("\n", "")); 

     byte[] responseArray = myWebClient.UploadData(filename, "POST", byteArray); 
     return "Webservice says OK"; 
    } 

Le problème est:

Le fichier enregistré sur le disque (avant le codage) et le fichier décodé avec C# ne sont pas égaux. Je ne sais pas si c'est un problème de codage Java ou de décodage C#. Toutes les suggestions, y compris la modification des types de fichiers ou du processus logique, seront toujours appréciées.

Merci d'avance!

EDIT - comparaison du fichier:

Original File http://img819.imageshack.us/img819/820/originalu.png

Decoded File (after Java encoding) http://img826.imageshack.us/img826/3184/processed.png

+0

Le fichier d'origine est enregistré sur mon disque local. L'autre fichier est envoyé à Webservice qui sauvegarde le fichier sur le disque du serveur. Je suis en mesure d'accéder aux deux emplacements et d'ouvrir les fichiers avec Notepad ++ et de confirmer que la taille et le contenu sont différents dans les deux fichiers. – CalypsOOO

+0

Pourquoi utilisez-vous un WebClient dans votre code C#? – nos

+0

Je ne suis pas sûr ... J'ai pris ce code sur un forum. – CalypsOOO

Répondre

2

Je sais que la norme XSD spécifie un type de données appelé base64Binary. Cela devrait permettre à votre paramètre [WebMethod] d'être un byte[]. Ensuite, la pile de service sous-jacente encodera le tableau d'octets en une chaîne base64.

Par exemple, je viens de faire un service Java rapide comme celui-ci

@WebMethod(operationName = "TestByteArray") 
    public void testByteArray(byte[] data) { 

    } 

Et les parties pertinentes du regard WSDL généré comme ceci:

<operation name="TestByteArray"> 
    <input wsam:Action="jordan.services/EncodingTests/TestByteArrayRequest" message="tns:TestByteArray"/> 
    <output wsam:Action="jordan.services/EncodingTests/TestByteArrayResponse" message="tns:TestByteArrayResponse"/> 
</operation> 

Et

<xs:complexType name="TestByteArray"> 
    <xs:sequence> 
     <xs:element name="arg0" type="xs:base64Binary" nillable="true" minOccurs="0"/> 
    </xs:sequence> 
</xs:complexType> 

J'ai aussi fait un test.Net:

[WebMethod] 
public void testByteArray(byte[] bytes) { 
} 

parties pertinentes du WSDL généré:

<wsdl:portType name="TestWSSoap"> 
    <wsdl:operation name="testByteArray"> 
     <wsdl:input message="tns:testByteArraySoapIn"/> 
     <wsdl:output message="tns:testByteArraySoapOut"/> 
    </wsdl:operation> 
</wsdl:portType> 

Et

<wsdl:types> 
    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/"> 
     <s:element name="testByteArray"> 
      <s:complexType> 
       <s:sequence> 
        <s:element minOccurs="0" maxOccurs="1" name="bytes" type="s:base64Binary"/> 
       </s:sequence> 
      </s:complexType> 
     </s:element> 
     <s:element name="testByteArrayResponse"> 
      <s:complexType/> 
     </s:element> 
    </s:schema> 
</wsdl:types> 
+0

Merci. Commentaire très utile. Mon problème est lié à l'encodage et au décodage en base64 entre Java et C# – CalypsOOO

+1

@CalypsOOO - A droite, ma suggestion est que vous n'avez pas besoin de faire le codage base64 avant/après l'appel WS. Envoyez juste le tableau d'octets brut. Lorsque vous le recevez dans C#, il suffit de publier le tableau d'octets (ou, écrivez-le directement). Si vous codez avant, alors vous envoyez une chaîne xsd: sur le réseau au lieu de xsd: base64Binary comme vous l'avez mentionné dans la première phrase de votre question. –

+0

Hum, Ok. Désolé, je n'ai pas compris votre suggestion. L'avez-vous déjà testé auparavant? Je pensais que base64Binary était une chaîne, car tout encoder en base64Binary renvoie une chaîne. Question similaire ici: http://stackoverflow.com/questions/2551525/failed-sending-bytes-array-to-jax-ws-web-service-on-axis – CalypsOOO

-3

Je suis probablement mal peu, je pense que vous avez besoin de convertir le fichier dans un format de chaîne pour une conversion de base64 appropriée.

Ne sait pas que c'est nécessaire en java mais en javascript Vous devez d'abord lancer en chaîne, puis convertir en base64.

+0

Ne comprends pas le vote négatif, juste essayé d'aider. : S – Ecarrion

+0

Ouais, voici tellement de crétins stupides autour .. – Sylar

+0

Vous attendiez un vote up parce que vous essayiez d'aider? Ne pensez-vous pas que cela va à l'encontre du but du vote? – bzlm

1

Utiliser fichier normal i/o au lieu d'un WebClient

public string sendFileToWebService(string file) 
{ 

    string dirname = HttpContext.Current.Request.PhysicalApplicationPath + "\\Attachments\\"; 
    if (!System.IO.Directory.Exists(dirname)) 
    { 
     System.IO.Directory.CreateDirectory(dirname); 
    } 
    string filename = dirname + "/" + "file.sim"; 
    byte[] byteArray = Convert.FromBase64String(file); 
    File.WriteAllBytes(filename, byteArray); //might wanna catch exceptions that could occur here 
    return "Webservice says OK"; 
}