Android客户端发送byte []到REST Web服务时出错

时间:2011-10-10 00:20:09

标签: java android web-services rest httpclient

这是我的第一篇文章;我是Android开发的新手,我写了一个REST Web服务来接收一个byte []:

@Path("scp")
public class ScpResources {

    // ...  

    @POST
    @Produces("text/plain")
    @Consumes(MediaType.APPLICATION_OCTET_STREAM)    
    public String upload(byte[] input) {

        System.out.println("Input: " + new String(input));

        return "File Sent!";
    }    

} // End

我用java独立应用程序(apache httpclient库)测试了这个ws,一切都很好,但是,当我尝试在Android应用程序中做同样的事情时......:

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";   

    @Override /** Called when the activity is first created. */    
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);

        Log.v(TAG, "--------------> to WS");

        try {
            HttpClient client = new DefaultHttpClient();

            String tmp = "abcdefghijklmnopqrstuvwxyz";
            byte b[] = tmp.getBytes();            
            HttpPost httpPost = new HttpPost("http://192.168.0.116:8080/WSfEclipse/resources/scp");  

            ByteArrayEntity entity = new ByteArrayEntity(b);
            entity.setContentType("application/octet-stream");
            httpPost.setEntity(entity);

            Log.e(TAG, ">Before error");
            //if(client == null) Log.e(TAG, "HttpClient null");
            //if(httpPost == null) Log.e(TAG, "HttpPost null");            

            client.execute(httpPost); // ERROR            

        } catch (Exception e) {
            //if(e == null) Log.e(TAG, "Exception(e) null");
            Log.e(TAG, e.getMessage());
        }

    } // End : onCreate

} // End : MainActivity

... logcat打印:

ERROR/MainActivity(368):   >Before error
    AndroidRuntime(368):   Shutting down VM
WARNING/dalvikvm(368):     threadid=1: thread exiting with uncaught exception (group=0x40014760)
ERROR/AndroidRuntime(368): FATAL EXCEPTION: main
ERROR/AndroidRuntime(368): java.lang.RuntimeException: Unable to start activity ComponentInfo{.....
ERROR/AndroidRuntime(368):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
ERROR/AndroidRuntime(368):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
ERROR/AndroidRuntime(368):     at android.app.ActivityThread.access$500(ActivityThread.java:122)
ERROR/AndroidRuntime(368):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
ERROR/AndroidRuntime(368):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(368):     at android.os.Looper.loop(Looper.java:132)
ERROR/AndroidRuntime(368):     at android.app.ActivityThread.main(ActivityThread.java:3948)
ERROR/AndroidRuntime(368):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(368):     at java.lang.reflect.Method.invoke(Method.java:491)
ERROR/AndroidRuntime(368):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
ERROR/AndroidRuntime(368):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
ERROR/AndroidRuntime(368):     at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(368): Caused by: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(368):     at android.util.Log.println_native(Native Method)
ERROR/AndroidRuntime(368):     at android.util.Log.e(Log.java:230)
ERROR/AndroidRuntime(368):     at MainActivity.onCreate(MainActivity.java:44)
ERROR/AndroidRuntime(368):     at android.app.Activity.performCreate(Activity.java:4397)
ERROR/AndroidRuntime(368):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
ERROR/AndroidRuntime(368):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
ERROR/AndroidRuntime(368):     ... 11 more

我的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.edu.radiogis.scpecg.clientecelular.activities"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="13" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application android:icon="@drawable/icon" android:label="ClienteSCP">
        <activity android:name=".MainActivity"
                  android:label="ClienteSCP">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

当我删除catch代码时,不会出现错误;尽管如此,应用程序不会将字节发送到Web服务。我检查是否有空引用(使用注释中的代码),但一切都很好。我不知道发生了什么,也许我忘记了什么。

!!提前致谢!!

3 个答案:

答案 0 :(得分:2)

您看到的是Log.e方法引发的异常,因为传递给它的消息文本(e.getMessage)为null。

您应该检查从http代码中获得的异常类型。用e.printStackTrace()替换你的日志语句。

答案 1 :(得分:2)

我找到了解决方案,包没问题(抱歉我没有显示包语句),我使用了e.printStackTrace(),它显示了Android NetworkOnMainThreadException,所以我把代码移到了AsyncTask:

public class WSConnectionTask extends AsyncTask<Void, String, String> {

HttpClient client;
HttpPost httpPost; 
HttpResponse response;

String tmp = "abcdefghijklmnopqrstuvwxyz";
byte[] b;   

@Override
protected void onPreExecute() {
    client = new DefaultHttpClient(); 
    b = tmp.getBytes();  
} // End : onPreExecute 

@Override
protected String doInBackground(Void... arg0) {

    httpPost = new HttpPost("http://192.168.0.116:8080/WSfEclipse/resources/scp");      
    ByteArrayEntity entity = new ByteArrayEntity(b);
    entity.setContentType("application/octet-stream");
    httpPost.setEntity(entity);

    try {
        client.execute(httpPost); // Send request       
    }
    catch (Exception e) {           
        e.printStackTrace();
    }       
    return "OK";

} // End : doInBackground

} // End : WSConnectionTask

!! !! Jackpot !!,成功,非常感谢你。

答案 2 :(得分:0)

基于异常和代码中缺少包定义,我认为您忘记将代码放在Manifest中列出的包中,特别是:com.edu.radiogis.scpecg.clientecelular.activities