Skip to content Skip to sidebar Skip to footer

Transferring Byte Array From Soap Service To Android

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

Solution 1:

@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


Solution 2:

It appears that you're missing an important decoding step. The code that generates the SOAP response has to be encoding the byte array so that it can be represented as a string in the XML. It's difficult to say how you should be decoding it without knowing the encoding mechanism used on the server side (base64, etc.).

In your code above you are calling 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 could not be used as a general purpose encoding mechanism since it cannot represent any arbitrary sequence of bytes (not all bytes sequences are valid UTF-8).

Check the service code to see how it is encoding the binary data and use an appropriate decoding mechanism on the client side, and it should resolve your issue.

HTH.

EDIT: This faq (for an older version but likely still applies) recommends encoding the byte array as base64 and wrapping it in a SoapPrimitive. Personally I would use Commons Codec and its Base64 class to encode the 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 watch out for... Android actually bundles an older version of Commons Codec so that might trip you up. In particular it does not include the encodeBase64String convenience method, so you'll 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 make sure to use the correct flags that match the encoding style you used on the server side. Good luck.


Solution 3:

we need to implement serialization before we send the byte array otherwise we are getting error can not serialize byte array.see below example

     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

Post a Comment for "Transferring Byte Array From Soap Service To Android"