Transferring byte array from soap service to android

Joeblackdev picture Joeblackdev · Jul 24, 2011 · Viewed 17.3k times · Source

I have an android client that makes a request to a soap service. The soap service reads an image into a series of bytes and returns a byte array (quite a large one). Would this be seen as a primitive transfer type? The reason I ask is because I have the service code that reads an image and prints the first 5 bytes. Then it returns the byte array.

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

The output from the service on the server is

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

When I receive this on my android emulator, I print the first 5 bytes and they are completely different to those 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 the output is

****** 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 be happening?

Answer

Joeblackdev picture Joeblackdev · Jul 25, 2011

@Michael, that worked a charm. Here is my final working code that will send a jpeg from a soap service to an android emulator and display it. I'm using jax-ws. Here is the service implementation bean for the operation getImage(), which returns a base64 encoded string of the 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 invoke the service and get the encoded image content, decode it to a byte array, create a bitmap and display it 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 else who may need it. You must also set the permission: <uses-permission android:name="android.permission.INTERNET"></uses-permission>. Also, note that the emulator is connecting to the machine's localhost on 10.0.2.2, not 127.0.0.1