最近接触到webwork框架,因为项目需求,需要将后台的数据采用json格式返回。
通过百度搜索,找到的方法也很多,但都讲得不够具体,不容易看懂。这里找到一个方法,写了一个返回json的类继承Result(http://www.thinksaas.cn/group/topic/329708/),觉得这种方法不错。具体代码如下:
JSONResult.java
package com.web.action;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.Result;
import java.io.OutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import com.opensymphony.webwork.ServletActionContext;
import com.opensymphony.xwork.ActionContext;
import org.json.JSONObject;
public class JSONResult implements Result {
private static final Log LOG = LogFactory.getLog(JSONResult.class);
// action中的json对象的名词
private String jsonObjectProperty = "jsonObject";
private String contentType = "application/json";
private String encoding = "utf-8";
@Override
public void execute(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
if (LOG.isDebugEnabled()) {
LOG.debug("executing JSONResult");
}
// 通过xwork的invocation从webwork的action中获得JSONObject对象
JSONObject jsonObject = getJSONObject(invocation);
if (jsonObject != null) {
String json = jsonObject.toString();
HttpServletResponse response = getServletResponse(invocation);
response.setContentType(getContentType());
// encoding
byte[] bs = json.getBytes(this.encoding);
response.setContentLength(bs.length);
OutputStream os = response.getOutputStream();
os.write(bs);
os.flush();
if (LOG.isDebugEnabled()) {
LOG.debug("written [" + json
+ "] to HttpServletResponse outputstream");
}
}
}
protected JSONObject getJSONObject(ActionInvocation invocation)
throws Exception {
ActionContext actionContext = invocation.getInvocationContext();
// 从xwork配置中获得JSON对象名词
Object obj = actionContext.getValueStack()
.findValue(jsonObjectProperty);
if (obj == null) {
LOG.error("property [" + jsonObjectProperty
+ "] returns null, please check xwork.xml file");
return null;
}
// 如果Action中的对象是JSONObject,那么就不需要反射动态转换为JSONObject
// 如果Action中的对象就是POJO,那么这里自动组装JSONObject
if (!JSONObject.class.isInstance(obj)) {
LOG.debug("build json object by reflection.");
JSONObject jsonObj = new JSONObject();
for (Field field : obj.getClass().getDeclaredFields()) {
String getter = "get"
+ Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
jsonObj.append(field.getName(), obj.getClass()
.getDeclaredMethod(getter).invoke(obj));
}
return jsonObj;
}
return (JSONObject) obj;
}
protected HttpServletResponse getServletResponse(ActionInvocation invocation) {
return (HttpServletResponse) invocation.getInvocationContext()
.getContextMap().get(ServletActionContext.HTTP_RESPONSE);
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getEncoding() {
return encoding;
}
public void setJsonObjectProperty(String jsonObjectProperty) {
this.jsonObjectProperty = jsonObjectProperty;
}
public String getJsonObjectProperty() {
return jsonObjectProperty;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getContentType() {
return contentType;
}
}
Action类:JSONAction.java
package com.web.action;
import org.json.JSONObject;
import com.opensymphony.xwork.Action;
import com.persistence.model.SysStation;
public class JSONAction implements Action {
private SysStation sysStation;//这是一个实体映射,映射实体方法这里不再讲述
public SysStation getSysStation() {
return sysStation;
}
public void setSysStation(SysStation sysStation) {
this.sysStation = sysStation;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
sysStation = new SysStation();
sysStation.setCity("江苏");
sysStation.setMobile("123456");
return Action.SUCCESS;
}
}
配置xwork.xml文件
<result-types>
<result-type name="json" class="com.web.action.JSONResult" />
</result-types>
<action name="jsonTest" class="com.web.action.JSONAction">
<result name="success" type="json">
<param name="jsonObjectProperty">sysStation</param>
</result>
</action>
这里需要注意,如果action配置节较多的情况下,result-types需要放在package下面,注意配置节的顺序如下,否则出现报错:
package里元素必须按照一定的顺序排列:
result-types
interceptors
default-interceptor-ref
default-action-ref
default-class-ref
global-results
global-exception-mappings
action*(所有action放到最后)
接下来,重启服务,就应该可以直接用地址访问json数据
关于json数据,还需要注意一个问题就是json与jsonp的区别,获取json数据不能跨域,而jsonp则可以,具体说明可以百度了解。