Skip to content

Commit

Permalink
refactor toJSONBytes code
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Apr 21, 2016
1 parent ac64943 commit dfdfb37
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 51 deletions.
9 changes: 1 addition & 8 deletions src/main/java/com/alibaba/fastjson/JSON.java
Expand Up @@ -397,9 +397,7 @@ public static String toJSONString(Object object, SerializerFeature... features)


try { try {
JSONSerializer serializer = new JSONSerializer(out); JSONSerializer serializer = new JSONSerializer(out);

serializer.write(object); serializer.write(object);

return out.toString(); return out.toString();
} finally { } finally {
out.close(); out.close();
Expand All @@ -423,16 +421,11 @@ public static String toJSONString(Object object, SerializeFilter[] filters, Seri
} }


public static byte[] toJSONBytes(Object object, SerializerFeature... features) { public static byte[] toJSONBytes(Object object, SerializerFeature... features) {
SerializeWriter out = new SerializeWriter(); SerializeWriter out = new SerializeWriter(null, DEFAULT_GENERATE_FEATURE, features);


try { try {
JSONSerializer serializer = new JSONSerializer(out); JSONSerializer serializer = new JSONSerializer(out);
for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
serializer.config(feature, true);
}

serializer.write(object); serializer.write(object);

return out.toUTF8Bytes(); return out.toUTF8Bytes();
} finally { } finally {
out.close(); out.close();
Expand Down
73 changes: 31 additions & 42 deletions src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java
Expand Up @@ -20,7 +20,6 @@
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Writer; import java.io.Writer;
import java.lang.ref.SoftReference;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
Expand All @@ -40,22 +39,18 @@
*/ */
public final class SerializeWriter extends Writer { public final class SerializeWriter extends Writer {


static Charset utf8 = Charset.forName("UTF-8"); private final static ThreadLocal<char[]> bufLocal = new ThreadLocal<char[]>();
private final static ThreadLocal<byte[]> bytesBufLocal = new ThreadLocal<byte[]>();
private final static ThreadLocal<CharsetEncoder> encoderLocal = new ThreadLocal<CharsetEncoder>();
private final static Charset utf8 = Charset.forName("UTF-8");


/**
* The buffer where data is stored.
*/
protected char buf[]; protected char buf[];


protected SoftReference<char[]> bufLocalRef;

/** /**
* The number of chars in the buffer. * The number of chars in the buffer.
*/ */
protected int count; protected int count;


private final static ThreadLocal<SoftReference<char[]>> bufLocal = new ThreadLocal<SoftReference<char[]>>();

protected int features; protected int features;


private final Writer writer; private final Writer writer;
Expand Down Expand Up @@ -87,21 +82,7 @@ public SerializeWriter(){
} }


public SerializeWriter(Writer writer){ public SerializeWriter(Writer writer){
this.writer = writer; this(writer, JSON.DEFAULT_GENERATE_FEATURE, SerializerFeature.EMPTY);
this.features = JSON.DEFAULT_GENERATE_FEATURE;

computeFeatures();

bufLocalRef = bufLocal.get();

if (bufLocalRef != null) {
buf = bufLocalRef.get();
bufLocal.set(null);
}

if (buf == null) {
buf = new char[1024];
}
} }


public SerializeWriter(SerializerFeature... features){ public SerializeWriter(SerializerFeature... features){
Expand All @@ -112,17 +93,20 @@ public SerializeWriter(Writer writer, SerializerFeature... features){
this(writer, 0, features); this(writer, 0, features);
} }


/**
* @since 1.2.9
* @param writer
* @param defaultFeatures
* @param features
*/
public SerializeWriter(Writer writer, int defaultFeatures, SerializerFeature... features){ public SerializeWriter(Writer writer, int defaultFeatures, SerializerFeature... features){
this.writer = writer; this.writer = writer;


bufLocalRef = bufLocal.get(); buf = bufLocal.get();


if (bufLocalRef != null) { if (buf != null) {
buf = bufLocalRef.get();
bufLocal.set(null); bufLocal.set(null);
} } else {

if (buf == null) {
buf = new char[1024]; buf = new char[1024];
} }


Expand Down Expand Up @@ -408,16 +392,27 @@ private byte[] toBytes(Charset charset) {
if (this.writer != null) { if (this.writer != null) {
throw new UnsupportedOperationException("writer not null"); throw new UnsupportedOperationException("writer not null");
} }

CharsetEncoder encoder;
if (charset == utf8) {
encoder = encoderLocal.get();
if (encoder == null) {
encoder = utf8.newEncoder() //
.onMalformedInput(CodingErrorAction.REPLACE) //
.onUnmappableCharacter(CodingErrorAction.REPLACE);
encoderLocal.set(encoder);
}
} else {
encoder = charset.newEncoder() //
.onMalformedInput(CodingErrorAction.REPLACE) //
.onUnmappableCharacter(CodingErrorAction.REPLACE);
}


CharsetEncoder encoder = charset.newEncoder() //
.onMalformedInput(CodingErrorAction.REPLACE) //
.onUnmappableCharacter(CodingErrorAction.REPLACE);


return encode(encoder, buf, 0, count); return encode(encoder, buf, 0, count);
} }


private final static ThreadLocal<byte[]> bytesBufLocal = new ThreadLocal<byte[]>();

private static byte[] encode(CharsetEncoder encoder, char[] chars, int off, int len) { private static byte[] encode(CharsetEncoder encoder, char[] chars, int off, int len) {
if (len == 0) { if (len == 0) {
return new byte[0]; return new byte[0];
Expand Down Expand Up @@ -480,13 +475,7 @@ public void close() {
flush(); flush();
} }
if (buf.length <= 1024 * 8) { if (buf.length <= 1024 * 8) {
SoftReference<char[]> ref; bufLocal.set(buf);
if (bufLocalRef == null || bufLocalRef.get() != buf) {
ref = new SoftReference<char[]>(buf);
} else {
ref = bufLocalRef;
}
bufLocal.set(ref);
} }


this.buf = null; this.buf = null;
Expand Down
Expand Up @@ -15,7 +15,8 @@ public static void main(String[] args) throws Exception {
// executor.getCodecList().add(new FastjsonGenCodec()); // executor.getCodecList().add(new FastjsonGenCodec());
// executor.getCodecList().add(new FastjsonBeanToArrayCodec()); // executor.getCodecList().add(new FastjsonBeanToArrayCodec());
// executor.getCodecList().add(new JacksonCodec()); // executor.getCodecList().add(new JacksonCodec());
// executor.getCodecList().add(new Jackson2Codec()); executor.getCodecList().add(new Jackson2Codec());
executor.getCodecList().add(new Jackson2AfterBurnCodec());
// //
// executor.getCodecList().add(new SimpleJsonCodec()); // executor.getCodecList().add(new SimpleJsonCodec());
// executor.getCodecList().add(new JsonLibCodec()); // executor.getCodecList().add(new JsonLibCodec());
Expand Down
@@ -0,0 +1,73 @@
package com.alibaba.json.test.codec;

import java.util.Collection;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;


public class Jackson2AfterBurnCodec implements Codec {

private ObjectMapper mapper = new ObjectMapper();

public Jackson2AfterBurnCodec() {
mapper.registerModule(new AfterburnerModule());
}

public String getName() {
return "jackson2AfterBurn";
}

public final <T> T decodeObject(String text, Class<T> clazz) {
try {
return mapper.readValue(text, clazz);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}


public <T> T decodeObject(byte[] input, Class<T> clazz) throws Exception {
try {
return mapper.readValue(input, clazz);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

public <T> Collection<T> decodeArray(String text, Class<T> clazz) throws Exception {
try {
return (Collection<T>) mapper.readValue(text, new TypeReference<T>() {
});
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

public final Object decodeObject(String text) {
try {
return (ObjectNode) mapper.readTree(text);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

public Object decode(String text) {
try {
return mapper.readTree(text);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

public String encode(Object object) throws Exception {
return mapper.writeValueAsString(object);
}

@Override
public byte[] encodeToBytes(Object object) throws Exception {
return mapper.writeValueAsBytes(object);
}
}

0 comments on commit dfdfb37

Please sign in to comment.