如何在Volley的GET请求中发送请求头"Content-Type":"application/json"

8
我尝试在Volley中使用GET方法,但我需要发送一个请求到application/json。我查找了一些答案,尝试使用jsonBody,但出现错误:

null com.android.volley.ServerError

这是我的代码:
public class MainActivity extends AppCompatActivity {

    String url = "http://114.35.246.42:2212/MobileApp/DEST_WebService.asmx/GetNews";
    JSONObject jsonBody;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            //I try to use this for send Header is application/json
            jsonBody = new JSONObject("{\"type\":\"example\"}");
        } catch (JSONException ex) {
            ex.printStackTrace();
        }

        RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext());

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, jsonBody,
                new Response.Listener<JSONObject>() {


                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d("TAG", response.toString());
                    }
                }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("TAG", error.getMessage(), error);
            }


        });


        mQueue.add(jsonObjectRequest);

    }


}

有人能教我如何解决这个问题吗?非常感谢任何帮助。

这是我的url: String url = "http://114.35.246.42:2212/MobileApp/DEST_WebService.asmx/GetNews";


jsonBody 是请求的 消息体,而不是请求头。由于您遇到了一个服务器错误,所以应该阅读某个日志信息中的内容,而不是在 logcat 中查看。 - OneCricketeer
重写您的请求队列的get headers()方法。 - Mukeshkumar S
4个回答

17
@Override 
public Map<String, String> getHeaders() throws AuthFailureError { 
    Map<String, String> params = new HashMap<String, String>();                
    params.put("Content-Type", "application/json");
    return params; 
} 

在你的实现中

public class MainActivity extends AppCompatActivity {

    String url = "http://114.35.246.42:2212/MobileApp/DEST_WebService.asmx/GetNews";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext());

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, jsonBody,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d("TAG", response.toString());
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("TAG", error.getMessage(), error);
                }
            }) { //no semicolon or coma
            @Override 
            public Map<String, String> getHeaders() throws AuthFailureError { 
                Map<String, String> params = new HashMap<String, String>();                
                params.put("Content-Type", "application/json");
                return params; 
            } 
        };
        mQueue.add(jsonObjectRequest);
    }
}

谢谢您的回复,我应该把这段代码放在哪里? - Morton
@徐博俊 您的响应是XML而不是JSON。 - Mukeshkumar S
@徐博俊,请查看图片并告诉我。 - Mukeshkumar S
我检查了网站,图片已被删除。 - Morton
让我们在聊天中继续这个讨论 - Mukeshkumar S
显示剩余4条评论

5
一般来说,要设置自定义标头,您需要覆盖 getHeaders 并手动设置自定义标头。然而,volley会以不同的方式处理内容类型标头,因此 getHeaders 的方法并不总是有效。
因此,在您的情况下,您需要覆盖 getBodyContentType。 因此,您的代码将如下所示:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, jsonBody,new Response.Listener<JSONObject>() {

@Override
public void onResponse(JSONObject response) {
   Log.d("TAG", response.toString());
}, new Response.ErrorListener(){
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("TAG", error.getMessage(), error);
        }


    }){
         @Override
         public String getBodyContentType(){
              return "application/json";
         }
    };

是的,我知道。但似乎对OP不起作用,所以我发布了手动操作的方式。 - ashkhn
谢谢你的回复,我尝试使用@Override public String getBodyContentType(){ return "application/json"; },但它显示'org.json.JSONException: Value <?xml of type java.lang.String cannot be conv',不像我在 Postman 中使用 application/json 的 GET 方法,我已经在我的问题中更新了我的 URL。 - Morton
正文以XML格式返回,但没有头部。服务器会处理头部,所以你使用的服务器可能无法正确读取头部信息。@akash93 - OneCricketeer
所以我尝试使用application/json,让数据{ "d": "{\"Msg\":\"Successful [0000]"....更容易处理。 - Morton

4
我尝试在Volley中使用GET方法。
你正在调用的方法文档如下:
默认使用GET构造函数,如果jsonRequest为null,则默认使用POST。
使用HTTP JSON正文无法进行GET请求。这可能是错误的原因。
//I try to use this for send Header is application/json
jsonBody = new JSONObject("{\"type\":\"example\"}");

这不是头部,因此在此处传入 null 进行 GET

new JsonObjectRequest(url, null,

在请求的最后,覆盖一个方法以请求JSON。

        ... 

        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("TAG", error.getMessage(), error);
        }


    }) { // Notice no semi-colon here
        @Override 
        public Map<String, String> getHeaders() throws AuthFailureError { 
            Map<String, String> params = new HashMap<String, String>();                
            params.put("Content-Type", "application/json");
            return params; 
        } 
    };

我的数据不正确,是 <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">{"Msg":"Successful [0000]".... ,但如果我使用 Postman 发送 GET 请求并使用 application/json,它将会得到 { "d": "{\"Msg\":\"Successful [0000]".... ,所以我提出了这个问题。 - Morton
好的,也许你需要重写getHeaders()方法。 - OneCricketeer
没问题,谢谢你关于 new JsonObjectRequest(url, null, 的回答。 - Morton
看起来真正的问题在于你收到的JSON无效,因为它包含XML标记。一旦你解决了这个问题,你的代码应该能够正常工作,而不需要重写任何方法,因为JsonRequest会自动设置内容类型头,就像@cricket_007之前提到的那样。 - ashkhn
@akash93 我已经尝试了这个请求。当添加了标头后,它会返回 JSON。 - OneCricketeer

1
请使用字符串请求(String request)代替jsonrequest,像这样:
            StringRequest loginMe = new StringRequest(Request.Method.GET, "http://114.35.246.42:2212/MobileApp/DEST_WebService.asmx/GetNews", new Response.Listener<String>() {

                @Override
                public void onResponse(String response) {

                    System.out.println("LoginActivity -- onResponse --> " + response);

                    if (progressDialog != null) {

                        progressDialog.dismiss();

                    }

                    try {

                        JSONObject jsonObject = new JSONObject(response);

                    } catch (Exception e) {

                        CommonUtility.somethingWentWrongDialog(activity,
                                "LoginActivity -- onResponse-- Exception --> ".concat(e.getMessage()));

                    }
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {

                    if (progressDialog != null) {

                        progressDialog.dismiss();

                    }

                    CommonUtility.somethingWentWrongDialog(activity,
                            "LoginActivity -- onErrorResponse --> ".concat(error.getMessage()));

                }
            }) {

                @Override
                protected Map<String, String> getParams() {

                    Map<String, String> params = new HashMap<>();


                    System.out.println("LoginActivity -- LoginParams --> " + params.toString());

                    return params;

                }
            };

            loginMe.setRetryPolicy(new DefaultRetryPolicy(60000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

            Volley.newRequestQueue(activity).add(loginMe);

1
不要复制粘贴示例代码。根据问题要求进行编辑。以上代码包含与问题无关的随机行。 - ashkhn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接