基础铺垫
在java中,关于json的lib有很多,比如jackjson、fastjson、gson等等,本人都用过,但是对于我等只需要让java对象返回json字符串即可的程序员来说,还是显得过于繁重。而且有些功能定制性很差,比如一个java对象的属性为空时,这些组件都不会输出,于是本人在页面循环遍历列表对象时,总是得判断此属性是否为undefined,这一点让本人很不满意。所以决定花点时间研究下到底是怎么回事。
但经过一上午的细看,发现不管是fastjson还是gson都代码都写得相当的复杂,又没什么相关的文档与注释,最后放弃了。于是自己又在www.json.com上找到了相对很简单的返回json的java包,这个lib只需要5个java类即可运行,正合我意。需要注意的是,官方的JSONArray这个东西并不支持javabean的直接转换,比如List<User>这样的东西是不能转换的,必须要把它转换成List<Map>这样的格式,才能转换,所以我对它进行了改造。官方的文件有:
先介绍下基本用法。
处理基本的java对象使用JSONObject类,用法大体如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public void testMap(){ Map<String,Object> map = new HashMap<String,Object>(); map.put( "name" , "qiu" ); map.put( "password" , "123" ); map.put( "address" , "china" ); User user = new User(); user.setUserName( "qiuqiu" ); user.setPassword( "123456" ); user.getTels().add( "1234444556677" ); user.getTels().add( "6893493458585" ); map.put( "user" , user); JSONObject json = new JSONObject(map); System.out.println(json.toString()); } |
如果是collection对象,则采用JSONArray类,用法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public void testList() throws JSONException{ List<User> list = new ArrayList<User>(); User user = new User(); user.setUserName( "qiuqiu" ); user.setPassword( "123456" ); user.getTels().add( "1234444556677" ); user.getTels().add( "6893493458585" ); User user2 = new User(); user2.setUserName( "中国" ); user2.getTels().add( "1234444556677" ); user2.getTels().add( "6893493458585" ); list.add(user); list.add(user2); JSONArray json = new JSONArray(list); System.out.println(json.toString( 2 )); } |
由上面的代码可以看出,这个lib的用法相当的简单,不像什么gson之类得新创建个对象,fastjson的API设计也有些不合理。上面的第二段代码中,有个toString(2)表示按换行缩进两个空格的方式输出。
上面只是介绍了基本用法,但这并不是自己想要的,自己想要的是怎么让对象属性为空时返回一个空字符串,而不是什么都不返回。虽然只有5个类,但本人还是花了两三个小时的才找到地方,在JSONObject中有个叫populateMap的方法,在最后有小段代码:
1
2
3
4
|
Object result = method.invoke(bean, (Object[]) null ); if (result != null ) { this .map.put(key, wrap(result)); } |
即当调用get方法返回为null时,就不输出此属性。当然改起来就很简单了:
1
2
|
Object result = method.invoke(bean, (Object[]) null ); this .map.put(key, result== null ? "" :wrap(result)); |
这样总算解决了本人想要解决的问题。当然这个lib是json官方自带的,写得相当的简单,比较适合一次数据只有几条或者几十条的情况,如分页显示等。如果一次传输数据量比较大的话,可以考虑使用fastjson等。但个人觉得对于大多数场合来说,最需要的是可定制性。比如偶尔发现个某组件不能满足的需要,结果此组件即无文档也无注释,代码又比较难理解,基本上跟没开源差不多,那就没什么意义了。
实例总结
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; /** * * Web服务端返回JSON工具类 * 工具类依赖FastJSON * 工具类支持返回JSON和JSONP格式数据 * @author accountwcx@qq.com * */ public class ResponseJsonUtils { /** * 默认字符编码 */ private static String encoding = "UTF-8" ; /** * JSONP默认的回调函数 */ private static String callback = "callback" ; /** * FastJSON的序列化设置 */ private static SerializerFeature[] features = new SerializerFeature[]{ //输出Map中为Null的值 SerializerFeature.WriteMapNullValue, //如果Boolean对象为Null,则输出为false SerializerFeature.WriteNullBooleanAsFalse, //如果List为Null,则输出为[] SerializerFeature.WriteNullListAsEmpty, //如果Number为Null,则输出为0 SerializerFeature.WriteNullNumberAsZero, //输出Null字符串 SerializerFeature.WriteNullStringAsEmpty, //格式化输出日期 SerializerFeature.WriteDateUseDateFormat }; /** * 把Java对象JSON序列化 * @param obj 需要JSON序列化的Java对象 * @return JSON字符串 */ private static String toJSONString(Object obj){ return JSON.toJSONString(obj, features); } /** * 返回JSON格式数据 * @param response * @param data 待返回的Java对象 * @param encoding 返回JSON字符串的编码格式 */ public static void json(HttpServletResponse response, Object data, String encoding){ //设置编码格式 response.setContentType( "text/plain;charset=" + encoding); response.setCharacterEncoding(encoding); PrintWriter out = null ; try { out = response.getWriter(); out.write(toJSONString(data)); out.flush(); } catch (IOException e){ e.printStackTrace(); } } /** * 返回JSON格式数据,使用默认编码 * @param response * @param data 待返回的Java对象 */ public static void json(HttpServletResponse response, Object data){ json(response, data, encoding); } /** * 返回JSONP数据,使用默认编码和默认回调函数 * @param response * @param data JSONP数据 */ public static void jsonp(HttpServletResponse response, Object data){ jsonp(response, callback, data, encoding); } /** * 返回JSONP数据,使用默认编码 * @param response * @param callback JSONP回调函数名称 * @param data JSONP数据 */ public static void jsonp(HttpServletResponse response, String callback, Object data){ jsonp(response, callback, data, encoding); } /** * 返回JSONP数据 * @param response * @param callback JSONP回调函数名称 * @param data JSONP数据 * @param encoding JSONP数据编码 */ public static void jsonp(HttpServletResponse response, String callback, Object data, String encoding){ StringBuffer sb = new StringBuffer(callback); sb.append( "(" ); sb.append(toJSONString(data)); sb.append( ");" ); // 设置编码格式 response.setContentType( "text/plain;charset=" + encoding); response.setCharacterEncoding(encoding); PrintWriter out = null ; try { out = response.getWriter(); out.write(sb.toString()); out.flush(); } catch (IOException e) { e.printStackTrace(); } } public static String getEncoding() { return encoding; } public static void setEncoding(String encoding) { ResponseJsonUtils.encoding = encoding; } public static String getCallback() { return callback; } public static void setCallback(String callback) { ResponseJsonUtils.callback = callback; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/** * 在Servlet返回JSON数据 */ @WebServlet ( "/json.do" ) public class JsonServlet extends HttpServlet { private static final long serialVersionUID = 7500835936131982864L; /** * 返回json格式数据 */ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map<String, Object> data = new HashMap<String, Object>(); data.put( "date" , new Date()); data.put( "email" , "accountwcx@qq.com" ); data.put( "age" , 30 ); data.put( "name" , "csdn" ); data.put( "array" , new int []{ 1 , 2 , 3 , 4 }); ResponseJsonUtils.json(response, data); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/** * Servlet返回JSONP格式数据 */ @WebServlet ( "/jsonp.do" ) public class JsonpServlet extends HttpServlet { private static final long serialVersionUID = -8343408864035108293L; /** * 请求会发送callback参数作为回调函数,如果没有发送callback参数则使用默认回调函数 */ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //客户端发送的回调函数 String callback = request.getParameter( "callback" ); Map<String, Object> data = new HashMap<String, Object>(); data.put( "date" , new Date()); data.put( "email" , "accountwcx@qq.com" ); data.put( "age" , 30 ); data.put( "name" , "csdn" ); data.put( "array" , new int []{ 1 , 2 , 3 , 4 }); if (callback == null || callback.length() == 0 ){ //如果客户端没有发送回调函数,则使用默认的回调函数 ResponseJsonUtils.jsonp(response, data); } else { //使用客户端的回调函数 ResponseJsonUtils.jsonp(response, callback, data); } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
/** * 在Struts2中返回JSON和JSONP */ public class JsonAction extends ActionSupport { private static final long serialVersionUID = 5391000845385666048L; /** * JSONP的回调函数 */ private String callback; /** * 返回JSON */ public void json(){ HttpServletResponse response = ServletActionContext.getResponse(); Map<String, Object> data = new HashMap<String, Object>(); data.put( "date" , new Date()); data.put( "email" , "accountwcx@qq.com" ); data.put( "age" , 30 ); data.put( "name" , "csdn" ); data.put( "array" , new int []{ 1 , 2 , 3 , 4 }); ResponseJsonUtils.json(response, data); } /** * 返回JSONP */ public void jsonp(){ HttpServletResponse response = ServletActionContext.getResponse(); Map<String, Object> data = new HashMap<String, Object>(); data.put( "date" , new Date()); data.put( "email" , "accountwcx@qq.com" ); data.put( "age" , 30 ); data.put( "name" , "csdn" ); data.put( "array" , new int []{ 1 , 2 , 3 , 4 }); if (callback == null || callback.length() == 0 ){ //如果客户端没有发送回调函数,则使用默认的回调函数 ResponseJsonUtils.jsonp(response, data); } else { //使用客户端的回调函数 ResponseJsonUtils.jsonp(response, callback, data); } } public String getCallback() { return callback; } public void setCallback(String callback) { this .callback = callback; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * Spring MVC返回JSON和JSONP数据 */ @Controller @RequestMapping ( "/json" ) public class JsonController { /** * 返回JSON数据 * @param request * @param response */ @RequestMapping ( "/json.do" ) public void json(HttpServletRequest request, HttpServletResponse response){ Map<String, Object> data = new HashMap<String, Object>(); data.put( "date" , new Date()); data.put( "email" , "accountwcx@qq.com" ); data.put( "age" , 30 ); data.put( "name" , "csdn" ); data.put( "array" , new int []{ 1 , 2 , 3 , 4 }); ResponseJsonUtils.json(response, data); } /** * 返回JSONP数据 * @param callback JSONP的回调函数 * @param request * @param response */ @RequestMapping ( "/jsonp.do" ) public void json(String callback, HttpServletRequest request, HttpServletResponse response){ Map<String, Object> data = new HashMap<String, Object>(); data.put( "date" , new Date()); data.put( "email" , "accountwcx@qq.com" ); data.put( "age" , 30 ); data.put( "name" , "csdn" ); data.put( "array" , new int []{ 1 , 2 , 3 , 4 }); if (callback == null || callback.length() == 0 ){ //如果客户端没有发送回调函数,则使用默认的回调函数 ResponseJsonUtils.jsonp(response, data); } else { //使用客户端的回调函数 ResponseJsonUtils.jsonp(response, callback, data); } } } |