1

我有一个在 asp.net mvc 4 中制作的 web api,它公开了数据库的 CRUD 操作,并且我正在制作一个 android 应用程序来尝试和操作这些数据。

我面临的问题是在带有更新操作的 json 解析器中,该操作由 http PUT 请求(/api/products/id)公开

这是我正在使用的解析器,我从一个示例中获得,我修改了 POST 部分,以便它改为 PUT:

public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static JSONArray jArr = null;
static String json = "";

// constructor
public JSONParser() {

}

// function get json from url
    // by making HTTP POST or GET method
    public JSONObject makeHttpRequest(String url, String method,
            List<NameValuePair> params) {

        // Making HTTP request
        try {

            // check for request method
            if (method == "PUT") {
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPut httpPut = new HttpPut(url);
                httpPut.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPut);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
            }
            if(method == "POST"){
                // request method is POST
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            }else if(method == "GET"){
                // request method is GET
                DefaultHttpClient httpClient = new DefaultHttpClient();
                String paramString = URLEncodedUtils.format(params, "utf-8");
                url += "?" + paramString;
                HttpGet httpGet = new HttpGet(url);

                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
            }           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }
}

当我尝试执行 PUT 操作时,记录会更新,但应用程序在尝试执行时因空指针异常而崩溃is = httpEntity.getContent();

我在试图弄清楚这到底有什么问题时遇到了问题,因为我找不到关于事情应该如何完成的详细解释,我所拥有的只是我设法找到的随机示例,没有一个超过 GET和 POST 操作。

作为参考,这是调用解析器的异步任务:

class SaveProductDetails extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... args) {
        String id = mTitleText.getText().toString();
        String desc = mBodyText.getText().toString();
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair(KEY_ID, id));
        params.add(new BasicNameValuePair(KEY_DESC, desc));
        JSONParser parser = new JSONParser();
        JSONObject json = parser.makeHttpRequest(URL + id, "PUT", params);

        try {
            Integer success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                // successfully updated
                Intent i = getIntent();
                // send result code 100 to notify about product update
                setResult(100, i);
                finish();
            } else {
                // failed to update product
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;

    }
}

我究竟做错了什么?

4

1 回答 1

2

三件事(其中两件事更重要)。

首先(重要),您需要在处理响应正文之前确定您的请求是否成功。鉴于您的代码结构,我建议在检索方法的开头声明一个状态代码变量,并在每个之后设置它execute

HttpResponse httpResponse = httpClient.execute(httpPut);
status = httpResponse.getStatusLine().getStatusCode();

其次(重要),您需要在调用任何方法之前检查您的响应实体是否为非空。EntityUtils总体而言,使用课程来处理您的回复会更好地为您服务。

httpEntity = httpResponse.getEntity(); // Declare httpentity outside your try/catch
is = httpEntity.getContent();          // Remove this line entirely

然后,实体将按以下方式处理:

try {
    if(status == HttpStatus.SC_OK) {
        json = httpentity != null ?
            EntityUtils.toString(httpentity, "iso-8859-1") : null;
    } else {
        Log.e("Server responded with error status " + status);
    }
} catch (Exception e) {
    Log.e("Buffer Error", "Error converting result " + e.toString());
}

最后(非常重要),您应该删除解析器类中的所有静态变量,并将它们设为方法的局部变量。

于 2013-03-20T10:43:42.323 回答