封装fastjson为spring mvc的json view
可以将其中的main方法删掉。测试用的。我测试的结果是,jackson比fastjson快。
fastjson是1.1.36
jackson是2.2.3
jdk是1.7.40,client
cpu是intel i3
内存4g
package org.springframework.web.servlet.view.json;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
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;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.test.User;
public class MappingFastJsonView extends AbstractView {
/**
* Default content type: "application/json".
* Overridable through {@link #setContentType}.
*/
public static final String DEFAULT_CONTENT_TYPE = "application/json";
private String encoding = "UTF-8";
private String jsonPrefix;
private Boolean prettyPrint;
private Set<String> modelKeys;
private boolean extractValueFromSingleKeyModel = false;
private boolean disableCaching = true;
private boolean updateContentLength = false;
/**
* Construct a new {@code MappingFastJsonView}, setting the content type to {@code application/json}.
*/
public MappingFastJsonView() {
setContentType(DEFAULT_CONTENT_TYPE);
setExposePathVariables(false);
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Specify a custom prefix to use for this view's JSON output.
* Default is none.
* @see #setPrefixJson
*/
public void setJsonPrefix(String jsonPrefix) {
this.jsonPrefix = jsonPrefix;
}
/**
* Indicates whether the JSON output by this view should be prefixed with <tt>"{} && "</tt>.
* Default is {@code false}.
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed
* on the string, the prefix would need to be ignored.
* @see #setJsonPrefix
*/
public void setPrefixJson(boolean prefixJson) {
// if (prefixJson) {
// if (jsonPrefix == null) {
// jsonPrefix = "{} && ";
// }
// }
this.jsonPrefix = (prefixJson ? "{} && " : null);
}
/**
* Whether to use the default pretty printer when writing JSON.
* This is a shortcut for setting up an {@code JSON}
* <p>The default value is {@code false}.
*/
public void setPrettyPrint(boolean prettyPrint) {
this.prettyPrint = prettyPrint;
}
/**
* Set the attribute in the model that should be rendered by this view.
* When set, all other model attributes will be ignored.
*/
public void setModelKey(String modelKey) {
this.modelKeys = Collections.singleton(modelKey);
}
/**
* Set the attributes in the model that should be rendered by this view.
* When set, all other model attributes will be ignored.
*/
public void setModelKeys(Set<String> modelKeys) {
this.modelKeys = modelKeys;
}
/**
* Return the attributes in the model that should be rendered by this view.
*/
public final Set<String> getModelKeys() {
return this.modelKeys;
}
/**
* Set whether to serialize models containing a single attribute as a map or whether to
* extract the single value from the model and serialize it directly.
* <p>The effect of setting this flag is similar to using {@code MappingJacksonHttpMessageConverter}
* with an {@code @ResponseBody} request-handling method.
* <p>Default is {@code false}.
*/
public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) {
this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel;
}
/**
* Disables caching of the generated JSON.
* <p>Default is {@code true}, which will prevent the client from caching the generated JSON.
*/
public void setDisableCaching(boolean disableCaching) {
this.disableCaching = disableCaching;
}
/**
* Whether to update the 'Content-Length' header of the response. When set to
* {@code true}, the response is buffered in order to determine the content
* length and set the 'Content-Length' header of the response.
* <p>The default setting is {@code false}.
*/
public void setUpdateContentLength(boolean updateContentLength) {
this.updateContentLength = updateContentLength;
}
@Override
protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) {
setResponseContentType(request, response);
response.setCharacterEncoding(encoding);
if (this.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 {
OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream());
Object value = filterModel(model);
writeContent(stream, value, this.jsonPrefix);
if (this.updateContentLength) {
writeToResponse(response, (ByteArrayOutputStream) stream);
}
}
/**
* Filter out undesired attributes from the given model.
* The return value can be either another {@link Map} or a single value object.
* <p>The default implementation removes {@link BindingResult} instances and entries
* not included in the {@link #setRenderedAttributes renderedAttributes} property.
* @param model the model, as passed on to {@link #renderMergedOutputModel}
* @return the value to be rendered
*/
protected Object filterModel(Map<String, Object> model) {
Map<String, Object> result = new HashMap<String, Object>(model.size());
Set<String> renderedAttributes = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : 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 (this.extractValueFromSingleKeyModel && result.size() == 1 ? result.values().iterator().next() : result);
}
/**
* Write the actual JSON content to the stream.
* @param stream the output stream to use
* @param value the value to be rendered, as returned from {@link #filterModel}
* @param jsonPrefix the prefix for this view's JSON output
* (as indicated through {@link #setJsonPrefix}/{@link #setPrefixJson})
* @throws IOException if writing failed
*/
protected void writeContent(OutputStream stream, Object value, String jsonPrefix) throws IOException {
List<SerializerFeature> list = new ArrayList<SerializerFeature>();
if (prettyPrint != null && prettyPrint) {
list.add(SerializerFeature.PrettyFormat);
}
SerializerFeature[] features = new SerializerFeature[list.size()];
list.toArray(features);
byte[] jsonBytes = JSON.toJSONBytes(value, features);
if (jsonPrefix != null) {//此处亦可字符串相加,然后转成字节数组
byte[] prefixBytes = jsonPrefix.getBytes(Charset.forName("UTF-8"));
int prefixLength = prefixBytes.length;
int jsonLength = jsonBytes.length;
byte[] finalJsonBytes = new byte[prefixLength + jsonLength];
System.arraycopy(prefixBytes, 0, finalJsonBytes, 0, prefixLength);
System.arraycopy(jsonBytes, 0, finalJsonBytes, prefixLength, jsonLength);
stream.write(finalJsonBytes);
} else {
stream.write(jsonBytes);
}
stream.flush();
}
public static void main(String[] args) {
List<User> users = Lists.newArrayList();
for (int j = 0; j < 10; j++) {
User value = new User();
value.setAddress("asdfjklasdjf");
value.setAge(22);
value.setGender(1);
value.setPassword("jkljklj");
value.setUserName("");
List<String> strList = Lists.newArrayList();
Map<String, String> strMap = Maps.newHashMap();
Set<Integer> setInt = Sets.newHashSet();
for (int i = 0; i < 10; i++) {
strList.add("a" + i);
strMap.put("a" + i, "a" + i);
setInt.add(i);
}
value.setSetInt(setInt);
value.setStrList(strList);
value.setStrMap(strMap);
users.add(value);
}
int times = 1;
// long d = System.currentTimeMillis();
// String jsonPrefix = "aaa{}";
//
// for (int i = 0; i < times; i++) {
// byte[] jsonBytes = JSON.toJSONBytes(value);
// byte[] prefixBytes = jsonPrefix.getBytes(Charset.forName("UTF-8"));
// int prefixLength = prefixBytes.length;
// int jsonLength = jsonBytes.length;
// byte[] finalJsonBytes = new byte[prefixLength + jsonLength];
//
// System.arraycopy(prefixBytes, 0, finalJsonBytes, 0, prefixLength);
// System.arraycopy(jsonBytes, 0, finalJsonBytes, prefixLength, jsonLength);
// }
// System.out.println(System.currentTimeMillis() - d);
String json = "";
String json2 = "";
long d2 = System.currentTimeMillis();
//String jsonPrefix2 = "aaa{}";
for (int i = 0; i < times; i++) {
json = JSON.toJSONString(users);
// jsonBytes = jsonPrefix2 + jsonBytes;
//
// byte[] prefixBytes = jsonBytes.getBytes(Charset.forName("UTF-8"));
}
System.out.println("fastjson parser :" + (System.currentTimeMillis() - d2));
ObjectMapper mapper = new ObjectMapper();
//org.codehaus.jackson.map.ObjectMapper mapper = new org.codehaus.jackson.map.ObjectMapper();
long d3 = System.currentTimeMillis();
//String jsonPrefix3 = "aaa{}";
for (int i = 0; i < times; i++) {
//String jsonBytes = null;
try {
//StringWriter writer = new StringWriter();
//JsonGenerator generator = new JsonFactory().createGenerator(writer);
//mapper.writeValue(writer, value);
//jsonBytes = writer.toString();
json2 = mapper.writeValueAsString(users);
//mapper.readValue(new StringReader(""), class1);
} catch (Exception e) {
e.printStackTrace();
}
// jsonBytes = jsonPrefix3 + jsonBytes;
//
// byte[] prefixBytes = jsonBytes.getBytes(Charset.forName("UTF-8"));
}
System.out.println("jackson parser :" + (System.currentTimeMillis() - d3));
long d5 = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
JSON.parseArray(json, User.class);
}
System.out.println("fastjson deserializer :" + (System.currentTimeMillis() - d5));
long d4 = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
try {
//List<User> userList = Lists.newArrayList();
mapper.readValue(json2, new TypeReference<List<User>>() {});
// List<User> userList = Lists.newArrayList();
// for (;iterator.hasNext();) {
// userList.add(iterator.nextValue());
// }
//System.out.println(userList);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("jackson deserializer :" + (System.currentTimeMillis() - d4));
}
}
package com.test;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
private String userName;
private String address;
private int age;
private int gender;
private String password;
private List<String> strList;
private Map<String, String> strMap;
private Set<Integer> setInt;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getStrList() {
return strList;
}
public void setStrList(List<String> strList) {
this.strList = strList;
}
public Map<String, String> getStrMap() {
return strMap;
}
public void setStrMap(Map<String, String> strMap) {
this.strMap = strMap;
}
public Set<Integer> getSetInt() {
return setInt;
}
public void setSetInt(Set<Integer> setInt) {
this.setInt = setInt;
}
}
封装fastjson为spring mvc的json view的更多相关文章
- spring mvc返回json字符串的方式
spring mvc返回json字符串的方式 方案一:使用@ResponseBody 注解返回响应体 直接将返回值序列化json 优点:不需要自己再处理 步骤一:在spring- ...
- spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable
1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(val ...
- Spring Mvc 输出Json(iwantmoon.com出品)
原文:http://iwantmoon.com/Post/f94e49caf9b6455db7158474bab4c4dd 因为工作需要,现在要去做开放平台,考虑了多种方案之后,基本确定 下来,Htt ...
- Spring MVC 的json问题(406 Not Acceptable)
原因 : 就是程序转换JSON失败. 在pom.xml 加上 <dependency> <groupId>com.fasterxml.jackson.core</grou ...
- ajax使用向Spring MVC发送JSON数据出现 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported错误
ajax使用向Spring MVC发送JSON数据时,后端Controller在接受JSON数据时报org.springframework.web.HttpMediaTypeNotSupportedE ...
- Spring MVC返回json数据给Android端
原先做Android项目时,服务端接口一直是别人写的,自己拿来调用一下,但下个项目,接口也要自己搞定了,我想用Spring MVC框架来提供接口,这两天便抽空浅学了一下该框架以及该框架如何返回json ...
- spring mvc 返回json的配置
转载自:http://my.oschina.net/haopeng/blog/324934 springMVC-servlet.xml 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- 使用spring mvc返回JSON,chrome可以,firefox不行的问题定位
转载http://ks.netease.com/blog?id=4024 作者:李景 场景: 前端Post请求同一个url地址,在chrome浏览器上有正常返回json,而在 ...
- Spring MVC之JSON数据交互和RESTful的支持
1.JSON概述 1.1 什么是JSON JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式.它是基于JavaScript的一个子集,使用了C.C ...
随机推荐
- ASP.NET用户自定义控件配置
一直以来开发中碰到要写自定义控件的时候总是习惯性的找度娘,而没有自己记住,结果今天就悲剧了,找了半天才找到,想想还是自己积累起来吧! 第一种配置方式: 配置写在webconfig文件中,位置如下: w ...
- Histats申请Counter网站计数器 - Blog透视镜
为了计算网页被浏览的次数,访客人数等统计数据,作为未来分析之用,可以向Histats申请免费的Counter网站计数器,它的功能相当齐全,同时也会保留一段时间的资料,当作统计比较的资料,更可以进一步付 ...
- python使用post登陆电子科大信息门户并保存登陆后页面
python使用post登陆电子科大信息门户并保存登陆后页面 作者:vpoet mail:vpoet_sir@163.com #coding=utf-8 import HTMLParser impor ...
- 2013长沙网络赛H题Hypersphere (蛋疼的题目 神似邀请赛A题)
Hypersphere Time Limit: 1 Second Memory Limit: 32768 KB In the world of k-dimension, there's a ...
- java开发中遇到的问题及解决方法(持续更新)
摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...
- No module named MYSQLdb 问题解决
问题描述: 报错:ImportError: No module named MySQLdb 对于不同的系统和程序有如下的解决方法: easy_install mysql-python (mix os) ...
- python 性能优化
1.优化循环 循环之外能做的事不要放在循环内,比如下面的优化可以快一倍 2.使用join合并迭代器中的字符串 join对于累加的方式,有大约5倍的提升 3.使用if is 使用if is True比i ...
- flappy bird游戏源代码揭秘和下载
转:http://blog.csdn.net/touchsnow/article/details/19071961 背景: 最近火爆全球的游戏flappy bird让笔者叹为观止,于是花了一天的时间山 ...
- ArcSDE for Oracle表空间管理——暂时(TEMP)表空间
Oracle暂时表空间主要用来做查询和存放一些缓冲区数据.暂时表空间消耗的主要原因是须要对查询的中间结果进行排序. 重新启动数据库能够释放暂时表空间,假设不能重新启动实例,而一直保持问题sql语句的运 ...
- [Node.js]在windows下不得不防的小错误
TypeError: Arguments to path.join must be strings at f (path.js:204:15) at Object.filter (native) at ...