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 com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.Result;
import org.json.JSONObject;
/**
* 支持自动组装JSONObject的JSONResult,支持encoding编码。
*
* @author WUZHENZHONG
* @data 2012-07-02
*/
public class JSONResult implements Result {
/**
*
*/
private static final long serialVersionUID = 9010804483391553391L;
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 {
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;
}
}
配置文件:
<xwork>
<package name="system-default" extends="webwork-default">
<result-types>
<result-type name="json" class="com.guagua.chat.search.JSONResult" />
</result-types>
<action name="search" class="com.guagua.chat.search.SearchAction">
<result name="cjcategory" type="json">
<param name="jsonObjectProperty">cjroomcategory</param>
</result>
</action>
</package>
</xwork>
类例子:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.guagua.base.AuthFactory;
import com.guagua.base.AuthToken;
import com.guagua.base.UnauthorizedException;
import com.guagua.vas.constants.CacheConstants;
import com.guagua.vas.redis.RedIsService;
import com.opensymphony.webwork.ServletActionContext;
public class SearchAction {
private static Logger logger = Logger.getLogger(SearchAction.class.getName());
public CjRoomCategoryVo cjroomcategory = new CjRoomCategoryVo();
/**
* 获取房间分类接口
* @return JSON
* @throws Exception
*/
@SuppressWarnings("unchecked")
public String getcjcategory() throws Exception {
Map<String,String> catemap = RedIsService.getJedisByKey(CacheConstants.CJ_ROOM_CATEGORY);
String returnstr = "";
if(catemap==null || catemap.size()<=0){
catemap.put("cj_room_category_101_0", "{'category_id':101,'name':'桂林','parent_id':0}");
catemap.put("cj_room_category_1011_101", "{'category_id':1011,'name':'桂林s','parent_id':101}");
catemap.put("cj_room_category_1012_101", "{'category_id':1012,'name':'桂林sf','parent_id':101}");
catemap.put("cj_room_category_102_0", "{'category_id':102,'name':'桂林1','parent_id':0}");
catemap.put("cj_room_category_1013_102", "{'category_id':1013,'name':'桂林sf','parent_id':102}");
}
List arrayList = new ArrayList(catemap.entrySet());
Collections.sort(arrayList, new TariffMapComparator());
for(Iterator it = arrayList.iterator();it.hasNext();){
Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next();
if(entry.getKey().endsWith("_0")){
String tempstr = "'category':"+entry.getValue();
String[] tp = entry.getKey().split("_");
StringBuffer subtempstr = new StringBuffer("");
for(Iterator subit = arrayList.iterator();subit.hasNext();){
Map.Entry<String,String> subentry = (Map.Entry<String,String>)subit.next();
if(subentry.getKey().endsWith("_"+tp[3])){
subtempstr.append(subentry.getValue()+",");
}
}
String tempsubstr = subtempstr.toString();
if(tempsubstr.length()>0){
tempsubstr = tempsubstr.substring(0, tempsubstr.length()-1);
}
tempsubstr = "'subcategory':["+tempsubstr+"]";
String tempcountstr = "{"+tempstr+","+tempsubstr+"}";
returnstr = returnstr + tempcountstr+",";
}
}
returnstr = "["+returnstr.substring(0, returnstr.length()-1)+"]";
cjroomcategory.setJsonstr(returnstr);
return "cjcategory";
}
public CjRoomCategoryVo getCjroomcategory() {
return cjroomcategory;
}
public void setCjroomcategory(CjRoomCategoryVo cjroomcategory) {
this.cjroomcategory = cjroomcategory;
}
/**
* 分类排序
* @author WUZHENZHONG
*
*/
@SuppressWarnings({"unused", "unchecked"})
private class TariffMapComparator implements Comparator{
public int compare(Object o1, Object o2) {
Map.Entry<String,String> obj1 = (Map.Entry<String,String>)o1;
Map.Entry<String,String> obj2 = (Map.Entry<String,String>)o2;
return obj1.getKey().toString().compareTo(obj2.getKey().toString());
}
}
}