Transferring an array of bytes from a soap service to android

I have an android client that makes a soap service request. The soap service reads the image in a series of bytes and returns an array of bytes (quite large). Will this be considered a primitive type of carry? The reason I'm asking is because I have a utility code that reads an image and prints the first 5 bytes. Then it returns an array of bytes.

@Override public byte[] getImage() { byte[] imageBytes = null; try { File imageFile = new File("C:\\images\\car.jpg"); BufferedImage img = ImageIO.read(imageFile); ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); ImageIO.write(img, "jpg", baos); baos.flush(); imageBytes = baos.toByteArray(); baos.close(); } catch (IOException ioe) { ioe.printStackTrace(); } System.out.println("Got request"); System.out.println("****** FIRST 5 BYTES: "); for(int i=0; i<5; i++) { System.out.println("****** " + imageBytes[i]); } return imageBytes; } 

Server service output

 ****** FIRST 5 BYTES: ****** -119 ****** 80 ****** 78 ****** 71 ****** 13 

When I get this on my Android emulator, I print the first 5 bytes, and they are completely different from those that were printed on the server. Here is my Android code:

  androidHttpTransport.call(SOAP_ACTION, envelope); SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse(); String result = resultsRequestSOAP.toString(); System.out.println("****** RESULT: " + result); byte[] b = result.getBytes(); System.out.println("****** FIRST 5 BYTES: "); for(int i=0; i<5; i++) { System.out.println("****** " + b[i]); } 

And conclusion

 ****** FIRST 5 BYTES: ****** 105 ****** 86 ****** 66 ****** 79 ****** 82 

It works fine if I test it with a simple service client written in java. Any ideas why this might happen?

+4
source share
3 answers

It looks like you are missing an important decoding step. The code that generates the SOAP response must encode an array of bytes so that it can be represented as a string in XML. It is hard to say how you should decode it without knowing the encoding mechanism used on the server side ( base64, etc. ).

In the above code, you call String # getBytes () , which encodes the given string as binary data using the default character set (which is UTF-8 on Android). This is not the same as decoding the original image data. UTF-8 cannot be used as a general-purpose encoding mechanism, since it cannot represent an arbitrary sequence of bytes (not all byte sequences are valid UTF-8).

Check the service code to see how it encodes binary data and uses the appropriate client-side decoding mechanism, and it should solve your problem.

NTN.

EDIT : This faq (for an older version, but probably still applicable) recommends encoding the byte array as base64 and wrapping it in SoapPrimitive. Personally, I used Commons Codec and my Base64 class to encode a byte array as a string on the server side and use it on the client side to decode this string back to the original byte array.

One thing to consider ... Android actually combines the older version of Commons Codec so you can kill yourself. In particular, it does not include the convenient encodeBase64String method, so you will need to experiment or do some research to find out what decoding methods exist on the Android platform. You can use android.util.Base64 on the client side, but be sure to use the correct flags corresponding to the encoding style that you used on the server side, Good luck.

+5
source

@Michael, it worked a charm. Here is my last working code that will send jpeg from the soap service to the Android emulator and show it. I am using jax-ws. The following is an implementation of the bean service for the getImage () operation, which returns a base64 encoded string of image bytes.

 @Override public String getImage() { byte[] imageBytes = null; try { File imageFile = new File("C:\\images\\fiesta.jpg"); BufferedImage img = ImageIO.read(imageFile); ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); ImageIO.write(img, "jpg", baos); baos.flush(); imageBytes = baos.toByteArray(); baos.close(); } catch (IOException ioe) { ioe.printStackTrace(); } return (imageBytes != null) ? Base64.encodeBase64String(imageBytes) : ""; } 

Now here is the Android code that will call the service and receive the contents of the encoded image, decode it into an array of bytes, create bitmap images and display them in the emulator:

 public class ImageSoapActivity extends Activity { private static final String NAMESPACE = "http://image.webservice"; private static final String URL = "http://10.0.2.2:8080/images?wsdl"; private static final String METHOD_NAME = "getImage"; private static final String SOAP_ACTION = "http://image.webservice/getImage"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); try { androidHttpTransport.call(SOAP_ACTION, envelope); SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse(); String result = resultsRequestSOAP.toString(); if (result != "") { byte[] bloc = Base64.decode(result, Base64.DEFAULT); Bitmap bmp = BitmapFactory.decodeByteArray(bloc,0,bloc.length); ImageView image = new ImageView(this); image.setImageBitmap(bmp); setContentView(image); } } catch (Exception e) { System.out.println("******* THERE WAS AN ERROR ACCESSING THE WEB SERVICE"); e.printStackTrace(); } } } 

enter image description here

I hope this is useful for someone who might need it. You must also set the permission: <uses-permission android:name="android.permission.INTERNET"></uses-permission> . Also note that the emulator connects to the localhost machine at 10.0.2.2, not 127.0.0.1

+10
source

we need to serialize before sending an array of bytes, otherwise we get an error, we cannot serialize an array of bytes. see example below

  private static final String NAMESPACE = ".xsd url taken from the web service URL"; private static final String URL = "web service URL"; private static final String SOAP_ACTION = "Action port typr"; private static final String METHOD_NAME = "Method name"; the above parameter can be taken from the users web service (?WSDL) url SoapObject request = new SoapObject(NAMESPACE, AUTH_METHOD); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11); new MarshalBase64().register(envelope); //serialization envelope.encodingStyle = SoapEnvelope.ENC; request.addProperty("body", str); request.addProperty("image", imagebyte); envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); try{ androidHttpTransport.call(SOAP_ACTION, envelope); SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn; String str=resultsRequestSOAP.toString(); }catch(Exception e) { } see 
+1
source

All Articles