package com.hundsun.jresplus.web.view; import java.io.BufferedOutputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.util.CollectionUtils; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.view.AbstractView; import com.alibaba.fastjson.JSON; /** * 基于fastjson的json view,支持编码为UTF-8,支持驼峰转下划线,支持模型转换 * @author XIE (xjj@hundsun.com) * */ public class FastJsonView extends AbstractView { public static final String DEFAULT_CONTENT_TYPE = "application/json"; private Set<String> renderedAttributes; private String charset = "UTF-8"; private boolean disableCaching = true; private boolean cameToUnderline = false; private ModelConverter modelConverter; public FastJsonView() { setContentType(DEFAULT_CONTENT_TYPE); } @Override protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { response.setContentType(getContentType()); response.setCharacterEncoding(charset); if (disableCaching) { response.addHeader("Pragma", "no-cache"); response.addHeader("Cache-Control", "no-cache, no-store, max-age=0"); response.addDateHeader("Expires", 1L); } } @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { String json = ""; if (modelConverter != null) { Model modelObj = modelConverter.convert(filterModel(model)); json = JSON.toJSONString(modelObj); } else { json = JSON.toJSONString(filterModel(model)); } if (cameToUnderline) { json = camel2underline(json); } OutputStream out = new BufferedOutputStream(response.getOutputStream()); out.write(json.getBytes(charset)); out.flush(); } protected Map filterModel(Map<String, Object> model) { Map<String, Object> result = new HashMap<String, Object>(model.size()); Set<String> renderedAttributes = !CollectionUtils .isEmpty(this.renderedAttributes) ? this.renderedAttributes : model.keySet(); for (Map.Entry<String, Object> entry : model.entrySet()) { if (!(entry.getValue() instanceof BindingResult) && renderedAttributes.contains(entry.getKey())) { result.put(entry.getKey(), entry.getValue()); } } return result; } public Set<String> getRenderedAttributes() { return renderedAttributes; } public void setRenderedAttributes(Set<String> renderedAttributes) { this.renderedAttributes = renderedAttributes; } public String getCharset() { return charset; } public void setCharset(String charset) { this.charset = charset; } public boolean isDisableCaching() { return disableCaching; } public void setDisableCaching(boolean disableCaching) { this.disableCaching = disableCaching; } public boolean isCameToUnderline() { return cameToUnderline; } public void setCameToUnderline(boolean cameToUnderline) { this.cameToUnderline = cameToUnderline; } public ModelConverter getModelConverter() { return modelConverter; } public void setModelConverter(ModelConverter modelConverter) { this.modelConverter = modelConverter; } private String camel2underline(String param) { Pattern p = Pattern.compile("[A-Z]"); if (param == null || param.equals("")) { return ""; } StringBuilder builder = new StringBuilder(param); Matcher mc = p.matcher(param); int i = 0; while (mc.find()) { builder.replace(mc.start() + i, mc.end() + i, "_" + mc.group().toLowerCase()); i++; } if ('_' == builder.charAt(0)) { builder.deleteCharAt(0); } return builder.toString(); } }