Android Async Http客户端 - 使用InputStream的POST请求

时间:2014-04-10 14:47:03

标签: android web-services httprequest restlet android-async-http

我尝试使用Android Async Http库作为我的客户端向我的REST网络服务发送POST请求。

对于我的网络服务,我使用的是RESTlet框架。

这是我的webservice上的处理程序方法:

@Override
public void handle(Request request, Response response) {
    String type = request.getMethod().getName();

    if(type.equalsIgnoreCase("get"))
    {
        response.setStatus(new Status(Status.CLIENT_ERROR_BAD_REQUEST, "GET Requests are not accepted"));
    }
    else if(type.equalsIgnoreCase("put"))
    {
        response.setStatus(new Status(Status.CLIENT_ERROR_BAD_REQUEST, "PUT Requests are not accepted"));
    }
    else if(type.equalsIgnoreCase("post"))
    {
        Vcard vcard = new Vcard(context);

        String vcf = "";
        try {
            vcf = vcard.echoVcard(request.getEntity().getStream());
        } catch (IOException e) {
            Log.d(TAG, "Exception echoVcard: " + e.getMessage());
            e.printStackTrace();
        }

        response.setEntity(vcf, MediaType.TEXT_PLAIN);
    }
    else if(type.equalsIgnoreCase("delete"))
    {
        response.setStatus(new Status(Status.CLIENT_ERROR_BAD_REQUEST, "DELETE Requests are not accepted"));
    }
}

这是我在Vcard类中的echoVcard方法:

public String echoVcard(final InputStream is)
{
    String vcf = "";
    try {

        final InputStream inputStream = is; //request.getEntity().getStream();          

        // Read the stream into a byte array  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();    

        byte[] data;

        int reads = inputStream.read(); 

        while(reads != -1)
        {
            baos.write(reads); 
            reads = inputStream.read(); 
        }

        data = baos.toByteArray();

        String content = new String(data, "UTF-8");
        int delimiterEndIndex = content.indexOf("\r\n");

        if (delimiterEndIndex > -1)
        {
            String delimiter = content.substring(0, content.indexOf("\r\n"));                      

            Pattern p = Pattern.compile("(?:Content-Type:)(.*)(?:\r\n\r\n)");
            Matcher m = p.matcher(content);
            String type="";

            Pattern p2 = Pattern.compile("(?:filename=\")(.*)(?:\").*");
            Matcher m2 = p2.matcher(content);
            String filename = "";

            if (m2.find() && m.find())
            {

                type = m.group(1).trim(); // Access a submatch group; String can't do this.

                filename = m2.group(1).trim(); // Access a submatch group; String can't do this.
                int indexO1 = content.indexOf("filename=\""+filename+"\"\r\n\r\n");
                int indexO2 = content.indexOf("Content-Type: "+type+"\r\n\r\n");

                if(indexO1!=-1 || indexO2 != -1)
                { 
                    int contentStart = 0;
                    int indexO = (indexO1 == -1 ? indexO2 : indexO1);
                    if(indexO1 > -1){
                        contentStart=indexO+("filename=\""+filename+"\"\r\n\r\n").length();
                    }else{
                        contentStart=indexO+("Content-Type: "+type+"\r\n\r\n").length();
                    }

                    byte[] delimiterBytes = ("\r\n" + delimiter).getBytes("UTF-8");
                    int endIndex = indexOf(data, delimiterBytes, contentStart);

                    int contentLength = endIndex - contentStart;

                    // Extract the file contents from the byte array
                    byte[] fileData = new byte[contentLength];

                    fileData = Arrays.copyOfRange(data, contentStart, endIndex);

                    vcf = new String(fileData, "UTF-8");

                }else{
                    ResourceException e2 = new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
                    throw e2;
                }
            }else{
                ResourceException e2 = new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
                throw e2;
            }
        }else{
            ResourceException e2 = new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
            throw e2;
        }

    } catch (Exception e) {
        e.printStackTrace();
        ResourceException e2 = new ResourceException(Status.SERVER_ERROR_INTERNAL);
        throw e2;
    }
    return vcf;
}

这是我的Android Async Http客户端:

public void testPostRequest()
{
    try {
        SyncHttpClient client = new SyncHttpClient();

        String vcardSample = "BEGIN:VCARD " +
                "\\nVERSION:2.1" +
                "\\nN:Diane;Woolnough;;;" +
                "\\nFN:Woolnough Diane" +
                "\\nTEL;CELL:52388" +
                "\\nORG:Norfolk Phone Book" +
                "\\nEND:VCARD";

        HttpEntity entity = new StringEntity(vcardSample);
        InputStream is = new ByteArrayInputStream(vcardSample.getBytes());
        HttpEntity entity2 = new InputStreamEntity(is, -1); 

        client.post(context, "http://localhost:8080/echo/file", entity2, "application/json", new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(String response) {
                Log.d(TAG, "POST - Success expected -> Got success");
                Log.d(TAG, "Echo back: " + response);
            }

            @Override
            public void onFailure(int code, Header[] headers, byte[] responseBody, Throwable error) {
                super.onFailure(code, headers, responseBody, error);

                Log.d(TAG, "POST - Success expected -> Got failure");
                Log.d(TAG, "POST Error: " + error.getLocalizedMessage());

                Header[] headerArray = getRequestHeaders();
                Log.d(TAG, "POST Code: " + code + " Header: " + headerArray.toString());
            }
        });
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
}

这是我的堆栈跟踪:

W/System.err(10314): Bad Request (400) - The request could not be understood by the server due to malformed syntax
W/System.err(10314):    at com.maineavtech.android.contactswebservicecrud.data.Vcard.echoVcard(Vcard.java:139)
W/System.err(10314):    at com.maineavtech.android.contactswebservicecrud.resources.EchoFileRestlet.handle(EchoFileRestlet.java:45)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)
W/System.err(10314):    at org.restlet.Component.handle(Component.java:392)
W/System.err(10314):    at org.restlet.Server.handle(Server.java:516)
W/System.err(10314):    at org.restlet.engine.connector.ServerConnectionHelper.handle(ServerConnectionHelper.java:257)
W/System.err(10314):    at org.restlet.engine.connector.ServerConnectionHelper.doHandleInbound(ServerConnectionHelper.java:186)
W/System.err(10314):    at org.restlet.engine.connector.BaseHelper$2.run(BaseHelper.java:593)
W/System.err(10314):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err(10314):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err(10314):    at java.lang.Thread.run(Thread.java:841)
W/System.err(10314): Exception or error caught in status service
W/System.err(10314): Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request
W/System.err(10314):    at com.maineavtech.android.contactswebservicecrud.data.Vcard.echoVcard(Vcard.java:145)
W/System.err(10314):    at com.maineavtech.android.contactswebservicecrud.resources.EchoFileRestlet.handle(EchoFileRestlet.java:45)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Router.doHandle(Router.java:431)
W/System.err(10314):    at org.restlet.routing.Router.handle(Router.java:648)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.routing.Filter.doHandle(Filter.java:159)
W/System.err(10314):    at org.restlet.routing.Filter.handle(Filter.java:206)
W/System.err(10314):    at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)
W/System.err(10314):    at org.restlet.Component.handle(Component.java:392)
W/System.err(10314):    at org.restlet.Server.handle(Server.java:516)
W/System.err(10314):    at org.restlet.engine.connector.ServerConnectionHelper.handle(ServerConnectionHelper.java:257)
W/System.err(10314):    at org.restlet.engine.connector.ServerConnectionHelper.doHandleInbound(ServerConnectionHelper.java:186)
W/System.err(10314):    at org.restlet.engine.connector.BaseHelper$2.run(BaseHelper.java:593)
W/System.err(10314):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err(10314):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err(10314):    at java.lang.Thread.run(Thread.java:841)
W/System.err(10314): 2014-04-10 03:30:13    127.0.0.1   -   -   8080    POST    /echo/file  -   500 486 -   71  http://localhost:8080   android-async-http/1.4.4 (http://loopj.com/android-async-http)  -
D/EchoFileRestletTest(10314): POST - Success expected -> Got failure
D/EchoFileRestletTest(10314): POST Error: Internal Server Error
W/System.err(10314): java.io.IOException: NPE in HttpClient: null
W/System.err(10314):    at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:103)
W/System.err(10314):    at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:54)
W/System.err(10314):    at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:72)
W/System.err(10314):    at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:688)
W/System.err(10314):    at com.pedro.notesquirrel.test.resources.EchoFileRestletTest.testPostRequest(EchoFileRestletTest.java:131)
W/System.err(10314):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(10314):    at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err(10314):    at junit.framework.TestCase.runTest(TestCase.java:168)
W/System.err(10314):    at junit.framework.TestCase.runBare(TestCase.java:134)
W/System.err(10314):    at junit.framework.TestResult$1.protect(TestResult.java:115)
W/System.err(10314):    at junit.framework.TestResult.runProtected(TestResult.java:133)
W/System.err(10314):    at junit.framework.TestResult.run(TestResult.java:118)
W/System.err(10314):    at junit.framework.TestCase.run(TestCase.java:124)
W/System.err(10314):    at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
W/System.err(10314):    at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
W/System.err(10314):    at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
W/System.err(10314):    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
D/EchoFileRestletTest(10314): POST - Success expected -> Got failure
D/EchoFileRestletTest(10314): POST Error: NPE in HttpClient: null

任何人都可以请我指出我收到的400 Bad Request的错误在哪里?

1 个答案:

答案 0 :(得分:0)

从你的评论中我把它读作最外面的,如果是这样的话,在这种情况下,instr无法在数据中找到\n\r字符对,这可能是因为在VCARD创建中你只使用了一个新的行字符( \n)。我将假设\\正确地转义\,然后生成的\n实际编码。