在本文中,我们将详细介绍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给前端)
- ajax – 为什么jqXHR.responseText返回字符串而不是JSON对象?
- android – nullpointerexception试图从json字符串中获取json数组或json对象
- android – 如何从OkHttp Response对象中提取原始JSON字符串?
- Django用JsonResponse或者HttpResponse来返回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对象?
这是我打电话的方式:
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。谢谢!
无论如何,只是解析它;这对我工作:
$.ajaxSetup({ "error": function(jqXHR,status,thrownError) { alert('error'); var responseText = jQuery.parseJSON(jqXHR.responseText); console.log(responseText); } });
android – nullpointerexception试图从json字符串中获取json数组或json对象
你好,当我试图从我的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");
解决方法
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字符串?
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字符串?
解决方法
更换
String json = response.body().toString();
同
String json = response.body().string();
response.body返回一个ResponseBody对象,该对象有自己的字符串方法:请参阅源here.
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的相关信息,请在本站查询。
本文标签: