Android HttpURLConnection在post请求中发送数据不起作用,但javascript XMLHttpRequest确实有效

时间:2016-02-02 17:46:50

标签: android xmlhttprequest httpurlconnection

我有一台使用mongodb,mongoose和node.js的服务器。 我已经实现了一些GET和POST方法。

在HTML网站中,我可以在XMLHttpRequest中将数据发布到服务器中,如javascript中所示:

function postPlantType(base64){
    var httpPost = new XMLHttpRequest(),
        path = "http://...",               // real URL taken out here
        header = ('Content-Type','application/json'),
        data = JSON.stringify({image:base64});
    httpPost.onreadystatechange = function(err) {
        if (httpPost.readyState == 4 && httpPost.status == 201){
            console.log(httpPost.responseText);
        } else {
            console.log(err);
        }
    };

    path = "http://..."                   // real URL taken out here
    httpPost.open("POST", path, true);
    httpPost.send(data);
}

这很好用。现在我想创建一个Android应用程序,利用这样的POST请求,但我的代码无法成功运行。这是我的代码:

    private class PostNewPlantTask extends AsyncTask<String, Integer, String> {
    String responseString = "";
    int response;
    InputStream is = null;

    protected String doInBackground(String... urls){
        DataOutputStream wr=null;
        try {
            URL url = new URL(urls[0]);  // urls[0] is the url of the http request "http://www..."
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000 /* milliseconds */);
            conn.setConnectTimeout(15000 /* milliseconds */);
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

            String json = "{\"image\":\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYE...\"}";

            Log.d("json", json.toString());

            conn.setRequestProperty("Content-length", json.getBytes().length + "");
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setAllowUserInteraction(false);

            OutputStream os = conn.getOutputStream();
            os.write( json.getBytes("UTF-8"));
            os.close();

            // Starts the query
            conn.connect();
            response = conn.getResponseCode();
            if (response >= 200 && response <=399){
                is = conn.getInputStream();
            } else {
                is = conn.getErrorStream();
            }

            // Convert the InputStream into a string
            String contentAsString = readIt(is, 200);
            responseString = contentAsString;
            conn.disconnect();
        } catch (Exception e) {
            responseString = "error occured: "+e;


        } finally {
            if (is != null){
                try { is.close();} catch (Exception e) {Log.d("HTTP POST planttypes","Exception occured at closing InputStream: "+e);}
            }
        }
        Log.d("HTTP POST plants", "The response is: " + response + responseString);
        return responseString;
    }

    protected void onPostExecute(String result){

        // TODO: nothing(?)
        // give user feedback(?)
    }

}

注意:如果我将json String更改为无效的json内容,例如删除最后一个“}”,服务器的响应是

400 "code":"InvalidContent","message":"Invalid JSON: Unexpected end of input"

所以我假设整个json字符串必须正确,如果它没有改变。

由于测试问题,我在这里硬编码base64encoded图像字符串而不是编码真实图像。您可以在此jsfiddle查看图片。 如果我看到它正确,它与我的javascript完全相同的请求,但我得到500内部服务器错误。 但是,为了获得更多信息,这里是为该请求url调用的服务器函数:

function postNewPlantType(req, res, next){
    var json = JSON.parse(req.body);
    newPlantTypeData = {
        image:json.image
    };

    var imageBuffer = decodeBase64Image(json.image);

    newPlantType = new Planttype(newPlantTypeData);

    newPlantType.save(function(err){
        if (err) return next(new    restify.InvalidArgumentError(JSON.stringify(err.errors)));
        var fileName = cfg.imageFolder + "" + newPlantType._id + '.jpeg';
        fs.writeFile(fileName, imageBuffer.data, function(error){
            if (error) log.debug(error);
            log.debug("PlantType-ImageFile successfully created on server.");
        });
        res.send(201, newPlantType);
        log.debug("PlantType successfully saved in database.");
    });
}

我想知道的是,javascript请求正在运行,但android请求不是。所以我假设我的android代码一定有错误。你能帮助我解释一下,错误是什么以及我必须改变什么?

2 个答案:

答案 0 :(得分:0)

您可能需要对其进行正确编码:

conn.connect();
DataOutputStream  printout = new DataOutputStream(conn.getOutputStream ());
printout.write(URLEncoder.encode(json.toString(),"UTF-8"));
printout.flush ();
printout.close ();
response = conn.getResponseCode();
...

答案 1 :(得分:0)

经过多天的调查后,我终于通过更改线路获得了201响应

conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

嗯..我发送的是编码的JSON而不是json本身...