Webwork JSON支持
在JSON.org上看到java实现的源码,想着自己写一个Result支持JSON的返回,但是一看webwork的新版本2.2.7版本已经支持JSON了
,但是有bug,第一,jsonObjectProperty的setter方法写成了setJSONObjectProperty所以,在配置中若使用了jsonObjectProperty做为参数名,那么是不能set参数进去的。另外,它不支持自定义返回js的编码,造成乱码,或者干脆都无法正常调用js,还有就是我觉得可以再封装得好一点,对于JSONObject的生成,可以利用反射来做,而不是在每个Action中都手工的写生成JSONObject的代码,所以我做了一下改进:
1
package
com.csair.hunan.common.web;
2![]()
3
import
java.io.OutputStream;
4
import
java.lang.reflect.Field;
5![]()
6
import
javax.servlet.http.HttpServletResponse;
7![]()
8
import
org.apache.commons.logging.Log;
9
import
org.apache.commons.logging.LogFactory;
10
import
org.json.JSONObject;
11![]()
12
import
com.opensymphony.webwork.ServletActionContext;
13
import
com.opensymphony.webwork.WebWorkException;
14
import
com.opensymphony.xwork.ActionContext;
15
import
com.opensymphony.xwork.ActionInvocation;
16
import
com.opensymphony.xwork.Result;
17![]()
18![]()
public
class
JSONResult
implements
Result
{
19![]()
20
private static final Log LOG = LogFactory.getLog(JSONResult.class);
21![]()
22
private String jsonObjectProperty = "jsonObject";
23
private String contentType = "application/json";
24
private String encoding = "utf-8";
25![]()
26![]()
public void setEncoding(String encoding)
{
27
this.encoding = encoding;
28
}
29![]()
/** *//**
30
* Returns the property which will be used to lookup {@link JSONObject} in WebWork's ValueStack. Default to
31
* 'jsonObject'.
32
*
33
* @return String
34
*/
35![]()
36![]()
public String getJsonObjectProperty()
{
37
return jsonObjectProperty;
38
}
39![]()
/** *//**
40
* Set the property which will be used to lookup {@link JSONObject} in WebWork's ValueStack. Default to
41
* 'jsonObject'.
42
*
43
* @param jsonObject
44
*/
45![]()
46![]()
public void setJsonObjectProperty(String jsonObjectProperty)
{
47
this.jsonObjectProperty = jsonObjectProperty;
48
}
49![]()
50![]()
/** *//**
51
* Returns the content-type header to be used. Default to 'application/json'.
52
*
53
* @return String
54
*/
55![]()
public String getContentType()
{
56
return contentType;
57
}
58![]()
59![]()
/** *//**
60
* Set the content-type header to be used. Default to 'application/json'.
61
*
62
* @param contentType
63
*/
64![]()
public void setContentType(String contentType)
{
65
this.contentType = contentType;
66
}
67![]()
68![]()
69![]()
/** *//**
70
* Writes the string representation of {@link JSONObject} defined through {@link #getJSONObjectProperty()}
71
* to {@link javax.servlet.http.HttpServletResponse}'s outputstream.
72
*
73
* @param invocation
74
* @throws Exception
75
*/
76![]()
public void execute(ActionInvocation invocation) throws Exception
{
77![]()
78![]()
if (LOG.isDebugEnabled())
{
79
LOG.debug("executing JSONResult");
80
}
81![]()
82
JSONObject jsonObject = getJSONObject(invocation);
83![]()
if (jsonObject != null)
{
84
String json = jsonObject.toString();
85
HttpServletResponse response = getServletResponse(invocation);
86
response.setContentType(getContentType());
87
//encoding
88
byte[] bs = json.getBytes(this.encoding);
89
response.setContentLength(bs.length);
90![]()
91
OutputStream os = response.getOutputStream();
92
os.write(bs);
93
os.flush();
94![]()
95![]()
if (LOG.isDebugEnabled())
{
96
LOG.debug("written ["+json+"] to HttpServletResponse outputstream");
97
}
98
}
99
}
100![]()
101![]()
/** *//**
102
* Attempt to look up a {@link com.opensymphony.webwork.dispatcher.json.JSONObject} instance through the property
103
* ({@link #getJSONObjectProperty()}) by looking up the property in WebWork's ValueStack. It shall be found if there's
104
* accessor method for the property in WebWork's action itself.
105
* <p/>
106
* Returns null if one cannot be found.
107
* <p/>
108
* We could override this method to return the desired JSONObject when writing testcases.
109
*
110
* @param invocation
111
* @return {@link JSONObject} or null if one cannot be found
112
*/
113![]()
protected JSONObject getJSONObject(ActionInvocation invocation) throws Exception
{
114
ActionContext actionContext = invocation.getInvocationContext();
115
Object obj = actionContext.getValueStack().findValue(jsonObjectProperty);
116![]()
117![]()
118![]()
if (obj == null)
{
119
LOG.error("property ["+ jsonObjectProperty +"] returns null, expecting JSONObject", new WebWorkException());
120
return null;
121
}
122
//if the assigned object is not an instance of JSONObject, try to build one use reflection
123![]()
if (! JSONObject.class.isInstance(obj))
{
124
LOG.warn("property ["+ jsonObjectProperty +"] is ["+obj+"] especting an instance of JSONObject", new WebWorkException());
125
LOG.debug("build json object by reflection.");
126
JSONObject jsonObj = new JSONObject();
127![]()
for (Field field : obj.getClass().getDeclaredFields())
{
128
String getter = "get" + Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
129
jsonObj.append(field.getName(), obj.getClass().getDeclaredMethod(getter).invoke(obj));
130
}
131
return jsonObj;
132
}
133
134
return (JSONObject) obj;
135
}
136![]()
137![]()
138![]()
/** *//**
139
* Returns a {@link javax.servlet.http.HttpServletResponse} by looking it up through WebWork's ActionContext Map.
140
* </p>
141
* We could override this method to return the desired Mock HttpServletResponse when writing testcases.
142
*
143
* @param invocation
144
* @return {@link javax.servlet.http.HttpServletResponse}
145
*/
146![]()
protected HttpServletResponse getServletResponse(ActionInvocation invocation)
{
147
return (HttpServletResponse) invocation.getInvocationContext().getContextMap().get(ServletActionContext.HTTP_RESPONSE);
148
}
149
}
150
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