GVKun编程网logo

HttpServletResponse 返回的json数据不是json字符串,而是json对象(servlet返回json给前端)

9

在本文中,我们将详细介绍HttpServletResponse返回的json数据不是json字符串,而是json对象的各个方面,并为您提供关于servlet返回json给前端的相关解答,同时,我们也将

在本文中,我们将详细介绍HttpServletResponse 返回的json数据不是json字符串,而是json对象的各个方面,并为您提供关于servlet返回json给前端的相关解答,同时,我们也将为您带来关于ajax – 为什么jqXHR.responseText返回字符串而不是JSON对象?、android – nullpointerexception试图从json字符串中获取json数组或json对象、android – 如何从OkHttp Response对象中提取原始JSON字符串?、Django用JsonResponse或者HttpResponse来返回JSON的有用知识。

本文目录一览:

HttpServletResponse 返回的json数据不是json字符串,而是json对象(servlet返回json给前端)

HttpServletResponse 返回的json数据不是json字符串,而是json对象(servlet返回json给前端)

 

今天在改一个bug

情况:

  在spring boot中写了一个类Result ,用来统一封装 各个API响应结果 , 其中重写了toString()方法来返回 json字符串 。

  在正常情况下,从其它API 返回给前端的结果都是json字符串,前端可以正确解析

  但遇到一些异常的情况,返回给前端的结果却是json对象数据,key少了双引号,前端无法正确解析

 

从一开始调试到后面网上查找各种资料,想过有可能是注解、方法重写、调用等方面出错,但都难以找到根源

直到后面看到一篇文章说到write() 方法对结果的处理问题,才有所悟,并调试确定了根源

其他能够正确返回json 字符串的,是因为 RestController 注解自动将对象转成了json字符串

而 response.getWriter().write() 是直接将json对象写进去,并没有自动转换成json字符串格式

 

 1     private void responseResult(HttpServletResponse response, Result<?> result) {
 2         response.setCharacterEncoding("UTF-8");
 3         response.setHeader("Content-Type", "application/json");
 4         response.setHeader("Access-Control-Allow-Credentials", "true");
 5         response.setHeader("Access-Control-Allow-Methods", "GET, POST");
 6         response.setHeader("Access-Control-Allow-Origin", "*");
 7         response.setHeader("Access-Control-Max-Age", "3600");       
 8 //        response.setHeader("Content-type", "application/json;charset=UTF-8");
 9         response.setStatus(HttpServletResponse.SC_OK);
10         response.setContentType("application/json;charset=UTF-8");
11 //        ServletOutputStream out = null;
12         PrintWriter writer=null;
13         try {
14             // JSON.toJSONString(result)要获取完整的json字符串,每一个字段都要有set和get方法,不然会缺少某个字段
15 //            response.getWriter().write(JSON.toJSONString(result));
16             writer=response.getWriter();
17 //            writer.write(result.toString());
18             writer.write(JSON.toJSONString(result));
19             writer.flush();
20         } catch (IOException ex) {
21             logger.error(ex.getMessage());
22         }finally {
23             if(writer!=null) {
24                 writer.close();
25             }
26         }
27     }

 

而至于重写的toString()方法为什么没有直接返回json字符串

 1       @Override
 2       public String toString() {
 3           Map<String, Object> resultMap=new ConcurrentHashMap<String, Object>();
 4           resultMap.put("code", code);
 5           resultMap.put("result", result);
 6           resultMap.put("msg", msg);
 7           if(data!=null) {
 8               resultMap.put("data", data);
 9           }else {
10              resultMap.put("data", "");
11           }
12           return JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES);
13       }

 现在终于找到问题了

resultMap:{result=false, msg=访问token无效, code=401, data=}
JSON.toJSONString(resultMap):{"result":false,"msg":"访问token无效","code":401,"data":""}
JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES):{result:false,msg:"访问token无效",code:401,data:""}

可以看到  JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES)  返回的字符串中,key 是没有双引号的 

这个算是 com.alibaba.fastjson 的一个坑吧

  

参考:

Spring的ResponseBody和RestController注解返回的json数据不是json字符串,而是json对象...   https://blog.csdn.net/weixin_33890526/article/details/87167889 

Object与json字符串的相互转换   https://blog.csdn.net/justry_deng/article/details/80780175  

fastjson:SerializerFeature属性使用   https://blog.csdn.net/zxl2016/article/details/80987414  

 

共同学习,共同进步,若有补充,欢迎指出,谢谢!

ajax – 为什么jqXHR.responseText返回字符串而不是JSON对象?

ajax – 为什么jqXHR.responseText返回字符串而不是JSON对象?

我有一个$ .ajax()请求,dataType设置为“json”。服务器返回带有“application / json”的正确MIME类型的JSON。然而在我的jqXHR对象的responseText总是一个字符串。我究竟做错了什么?这是它应该如何工作?

这是我打电话的方式:

var options = { 
    dataType:'json',type: 'GET',url: "http://example.com/api/"
};

var key = "PasstoCallback";

var jqXHRObject =  $.ajax(options).then(
    function(data,textStatus,jqXHR,key) {
        this.success(data,key);
    },function(jqXHR,errorThrown) { 
        this.error(jqXHR,errorThrown);
    }
);

console.log(jqXHRObject.getResponseHeader("content-type")); // application/json
console.log(typeof jqXHRObject.responseText); // string

所以我必须做一个$ .parseJSON(jqXHRObject.responseText)来获取一个实际的对象。这似乎不必要,因为$ .ajax()应该根据文档自动转换responseText。谢谢!

我有同样的问题。我返回一个字符串,因为它从一个异常。例如。我使用内核监听器序列化到我的Symfony2项目的json。这对于适当的REST标头是正确的。

无论如何,只是解析它;这对我工作:

$.ajaxSetup({
    "error": function(jqXHR,status,thrownError) {
        alert('error');
        var responseText = jQuery.parseJSON(jqXHR.responseText);
        console.log(responseText);
    }
});

android – nullpointerexception试图从json字符串中获取json数组或json对象

android – nullpointerexception试图从json字符串中获取json数组或json对象

参见英文答案 > Android problems with parsing json                                    2个
你好,当我试图从我的jsonString获取一个对象时,我继续得到NPE.我尝试了很多东西甚至改变了我的json一次,但它只是没有用. HTTPResponse工作正常,当我记录“myObject”时,它给出了正确的对象.但是当我试图让对象进入它时,它给了我一个NPE.我测试了json,它是有效的.我也尝试检索一个数组而不是一个对象,但它也提供了一个NPE.有人能告诉我如何解决这个问题.

我做了一个简单的jsontester活动来测试我的json:

public class JSONTester extends Activity {

private DefaultHttpClient createHttpClient() {
    HttpParams my_httpParams = new BasicHttpParams();
    httpconnectionParams.setConnectionTimeout(my_httpParams,3000);
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http",PlainSocketFactory.getSocketFactory(),80));
    ThreadSafeClientConnManager multiThreadedConnectionManager = new ThreadSafeClientConnManager(my_httpParams,registry);
    DefaultHttpClient httpclient = new DefaultHttpClient(multiThreadedConnectionManager,my_httpParams);
    return httpclient;
}

MikeyJSON mJSON;

Button mBtnGo;
TextView mTxt1;
TextView mTxt2;
TextView mTxt3;
TextView mTxt4;
ProgressDialog mProgressDialog;
private String lang;        
private int length;     // 0 - 6 (length 7 to length 12)
private int wordPos;        // 0 - array length

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

    mTxt1 = (TextView) findViewById(R.id.txt1);
    mTxt1 = (TextView) findViewById(R.id.txt1);
    mTxt1 = (TextView) findViewById(R.id.txt1);
    mTxt1 = (TextView) findViewById(R.id.txt1);
    mBtnGo = (Button) findViewById(R.id.btnGo);

}

public boolean isNumeric(String str) {

    for(int i=0;i<str.length();i++) {

        if(Character.isDigit(str.charat(i))) {
            return true;
        }
    }
    return false;
}

public void testJSON(View view) {
    if(view==mBtnGo) {

        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("loading");
        mProgressDialog.show();
        new DownloadNewWords().execute();
    }

}
private class DownloadNewWords extends AsyncTask<Void,Void,Void> {

    int mStatusCode = 0;
    String mResultString;
    Exception mConnectionException;

    @Override
    protected Void doInBackground(Void... args) {

            String fetchUrl = "http://www.mikeywebs.nl/json/jsonexample.html";
            DefaultHttpClient httpclient = createHttpClient();
        HttpGet httpget = new HttpGet(fetchUrl);

        try {
            HttpResponse response = httpclient.execute(httpget);
            StatusLine statusLine = response.getStatusLine();
            mStatusCode  = statusLine.getStatusCode();
                if (mStatusCode == 200){
                mResultString = EntityUtils.toString(response.getEntity());
            }
        } catch (ClientProtocolException e) {
            e.printstacktrace();
            mConnectionException = e;
        } catch (IOException e) {
            e.printstacktrace();
            mConnectionException = e;
        }
        return null;            
    }

        @Override
    protected void onPostExecute(Void arg) {
        mProgressDialog.dismiss();
        if (mStatusCode  == 200){
            mJSON = new MikeyJSON(mResultString);   
            lang = "English";   //Integer.parseInt(langu);
            length = 7;  //Integer.parseInt(wordl);
            wordPos = 0;
            String getWord = mJSON.getResult(lang,length,wordPos);
            mTxt4.setText(getWord);

        }
        else {
            Toast.makeText(JSONTester.this,"Gegevens konden niet worden opgehaald. Controleer uw internetverbinding en probeer het opnieuw (" +mConnectionException.toString() + ")",Toast.LENGTH_LONG).show();
            mJSON = null;
        }
    }
}

}

我使用的jsonclass是:

public class MikeyJSON {

private JSONObject myObject;
private JSONArray jsonArray;

int i;


public MikeyJSON(String jsonString) {
    Log.i("JSON","jsonString: " + jsonString);
    try {
        JSONObject myObject = new JSONObject(jsonString);
        Log.i("JSON","myObject_Object: " + myObject.toString());
    } catch (JSONException e) {
        // Todo Auto-generated catch block
        e.printstacktrace();
    }

}

public String getResult(String lang,int length,int wordPos) {
    String word = "0";  
    //0 is Nederlands 1 is English
    int la = 0;
    if(lang.equals("English")) { 
        la = 1;
    }
    //make String length
    String le = "length" + Integer.toString(length);
    Log.i("PARSE","get_length: " + le);

    //the json
    try {
        jsonArray = myObject.getJSONArray("galgjejson");
        Log.i("JSON","jsonArray: " + jsonArray.toString());
    } catch (JSONException e) {
        // Todo Auto-generated catch block
        e.printstacktrace();
    }

    return word;        
}
}

这是json:

{ "galgjejson" : [
                { "Nederlands" :  [
                                        { "length7" : [ 
                                                            { "word" : "android" },{ "word" : "camping" },{ "word" : "koekjes" }
                                                        ]
                                        }
                                ]   
                },{ "English" : [
                                        { "length7" : [ 
                                                            { "word" : "android" },{ "word" : "koekjes" }
                                                        ]
                                        }
                                ]
                }               
            ]                                               
}

这是日志:

03-18 14:06:23.178: I/JSON(6719): myObject_Object: {"Nederlands":[{"length7":
[{"word":"android"},{"word":"camping"},{"word":"koekjes"}]}]}
03-18 14:06:23.178: I/PARSE(6719): get_length: length7
03-18 14:06:23.178: D/AndroidRuntime(6719): Shutting down VM
03-18 14:06:23.178: W/dalvikvm(6719): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
03-18 14:06:23.207: E/AndroidRuntime(6719): FATAL EXCEPTION: main
03-18 14:06:23.207: E/AndroidRuntime(6719): java.lang.NullPointerException
03-18 14:06:23.207: E/AndroidRuntime(6719):     at me.mikey.my.games.galgjex.MikeyJSON.<init>(MikeyJSON.java:38)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at me.mikey.my.games.galgjex.JSONTester$DownloadNewWords.onPostExecute(JSONTester.java:128)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at me.mikey.my.games.galgjex.JSONTester$DownloadNewWords.onPostExecute(JSONTester.java:1)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at android.os.AsyncTask.finish(AsyncTask.java:631)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at android.os.Looper.loop(Looper.java:137)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at android.app.ActivityThread.main(ActivityThread.java:4745)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at java.lang.reflect.Method.invokeNative(Native Method)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at java.lang.reflect.Method.invoke(Method.java:511)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-18 14:06:23.207: E/AndroidRuntime(6719):     at dalvik.system.NativeStart.main(Native Method)

哦,第38行是:

jsonArray = myObject.getJSONArray("galgjejson");

解决方法

myObject很可能是null,因为你在类中拥有它,然后在mikeyJSON中私有.你应该尝试:

private JSONObject myObject;
private JSONArray jsonArray;

int i;


public MikeyJSON(String jsonString) {
Log.i("JSON","jsonString: " + jsonString);
try {
    myObject = new JSONObject(jsonString);
    Log.i("JSON","myObject_Object: " + myObject.toString());
} catch (JSONException e) {
    // Todo Auto-generated catch block
    e.printstacktrace();
}

}

看看那个JSON我很确定你可以使用构造函数中的字符串而不是JSONObject来创建JSONArray.

编辑的例子.

private JSONArray jsonArray;

int i;

public MikeyJSON(String jsonString) {
try {
    jsonArray = new JSONArray(jsonString);
} catch (JSONException e) {
    // Todo Auto-generated catch block
    e.printstacktrace();
}

}

android – 如何从OkHttp Response对象中提取原始JSON字符串?

android – 如何从OkHttp Response对象中提取原始JSON字符串?

private static final String URL = "http://www.livroandroid.com.br/livro/carros/carros_{tipo}.json";

public static List<Carro> getCarros(Context context,String tipo) throws IOException {
    String url = URL.replace("{tipo}",tipo);
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder()
            .url(URL)
            .build();
    Response response = okHttpClient.newCall(request).execute();
    String json = response.body().toString();
    List<Carro> carros = parserjson(context,json);
    return carros;
}

如果我在调用getCarros方法时打印出json变量的值,我在logcat中看到以下消息:

com.squareup.okhttp.internal.http.RealResponseBody@1e11866

如何记录我收到的实际JSON字符串?

解决方法

(最初回答OkHttp版本2.5.0).

更换

String json = response.body().toString();

String json = response.body().string();

response.body返回一个ResponseBody对象,该对象有自己的字符串方法:请参阅源here.

Django用JsonResponse或者HttpResponse来返回JSON

Django用JsonResponse或者HttpResponse来返回JSON

如果用HttpResponse一般这样用是正确的(记得要指明content_type="application/json"):

import json
from django.core import serializers
json_data = serializers.serialize(''json'', goods)
from django.http import HttpResponse
return HttpResponse(json_data, content_type="application/json")

下面这样写就可能出现有些类型序列化不了:

import json
from django.http import HttpResponse
return HttpResponse(json.dumps(json_list), content_type="application/json")

这是因为这个json.dumps不能序列化datetime这样类型的数据,所以才会用第一种那种serializers.serialize()来对其进行序列化。

当然json.loads就是serializers.serialize()它的逆操作了,逆回来再用json.dumps()也就没问题了。

 

JsonResponse做的工作也就是加上了dumps和content_type,要这样用(转过去再转回来,因为自带dumps没办法):

import json
from django.core import serializers
json_data = serializers.serialize(''json'', goods)
json_data = json.loads(json_data)
from django.http import JsonResponse
return JsonResponse(json_data, safe=False)

 

我们今天的关于HttpServletResponse 返回的json数据不是json字符串,而是json对象servlet返回json给前端的分享已经告一段落,感谢您的关注,如果您想了解更多关于ajax – 为什么jqXHR.responseText返回字符串而不是JSON对象?、android – nullpointerexception试图从json字符串中获取json数组或json对象、android – 如何从OkHttp Response对象中提取原始JSON字符串?、Django用JsonResponse或者HttpResponse来返回JSON的相关信息,请在本站查询。

本文标签: