可以将其中的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;
    }
    
    
}



GitHub 加速计划 / fastj / fastjson
25.69 K
6.51 K
下载
FASTJSON 2.0.x has been released, faster and more secure, recommend you upgrade.
最近提交(Master分支:3 个月前 )
c942c834 - 1 年前
5bc4709b - 1 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐