Browse Source

优化json

zhouhao 8 years ago
parent
commit
5c7f6f56a6

+ 58 - 5
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/HswebAutoConfiguration.java

@@ -18,17 +18,25 @@
 
 package org.hswebframework.web.starter;
 
+import com.alibaba.fastjson.parser.ParserConfig;
+import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
+import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import org.hswebframework.web.ThreadLocalUtils;
-import org.hswebframework.web.authorization.AuthenticationSupplier;
+import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.commons.entity.factory.MapperEntityFactory;
+import org.hswebframework.web.commons.entity.factory.PropertyCopier;
+import org.hswebframework.web.commons.model.Model;
 import org.hswebframework.web.starter.convert.FastJsonHttpMessageConverter;
 import org.hswebframework.web.starter.resolver.AuthorizationArgumentResolver;
 import org.hswebframework.web.starter.resolver.JsonParamResolver;
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
@@ -45,6 +53,8 @@ import javax.servlet.http.HttpServletResponse;
 import javax.validation.Validation;
 import javax.validation.Validator;
 import javax.validation.ValidatorFactory;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 import java.util.List;
 
 /**
@@ -62,16 +72,38 @@ public class HswebAutoConfiguration {
 
     @Bean
     @Primary
+    @ConfigurationProperties(prefix = "fastjson")
     public FastJsonHttpMessageConverter fastJsonHttpMessageConverter(@Autowired(required = false) EntityFactory entityFactory) {
         FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
-        // TODO: 16-12-24  应该可配置
         converter.setFeatures(
                 SerializerFeature.WriteNullListAsEmpty,
                 SerializerFeature.WriteNullNumberAsZero,
                 SerializerFeature.WriteNullBooleanAsFalse
-//                SerializerFeature.WriteDateUseDateFormat
         );
         converter.setEntityFactory(entityFactory);
+        ParserConfig.global = new ParserConfig() {
+            @Override
+            public ObjectDeserializer getDeserializer(Type type) {
+                ObjectDeserializer derializer = getDeserializers().get(type);
+                if (derializer != null) {
+                    return derializer;
+                }
+                if (type instanceof Class) {
+                    Class classType = ((Class) type);
+                    if (Modifier.isAbstract(classType.getModifiers()) || Modifier.isInterface(classType.getModifiers())) {
+                        if (entityFactory != null && (Entity.class.isAssignableFrom(classType) || Model.class.isAssignableFrom(classType))) {
+                            return new JavaBeanDeserializer(this, entityFactory.getInstanceType(classType), type);
+                        }
+                    } else {
+                        return new JavaBeanDeserializer(this, classType);
+                    }
+                }
+                return super.getDeserializer(type);
+            }
+        };
+        ParserConfig.getGlobalInstance().addAccept("org.hswebframework.web.entity.");
+        ParserConfig.getGlobalInstance().addAccept("org.hsweb.");
+        ParserConfig.getGlobalInstance().addDeny("org.hsweb.ezorm.core.param.SqlTerm");
         return converter;
     }
 
@@ -111,8 +143,7 @@ public class HswebAutoConfiguration {
     @ConditionalOnMissingBean(Validator.class)
     public Validator validator() {
         ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
-        Validator validator = factory.getValidator();
-        return validator;
+        return factory.getValidator();
     }
 
     @Bean(name = "entityFactory")
@@ -121,4 +152,26 @@ public class HswebAutoConfiguration {
         return new MapperEntityFactory(entityProperties.createMappers());
     }
 
+
+    @Configuration
+    @ConditionalOnBean(MapperEntityFactory.class)
+    public class EntityFactoryInitConfiguration implements BeanPostProcessor {
+
+        @Autowired
+        private MapperEntityFactory mapperEntityFactory;
+
+
+        @Override
+        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+            return bean;
+        }
+
+        @Override
+        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+            if (bean instanceof PropertyCopier) {
+                mapperEntityFactory.addCopier(((PropertyCopier) bean));
+            }
+            return bean;
+        }
+    }
 }

+ 1 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/RestControllerExceptionTranslator.java

@@ -44,6 +44,7 @@ public class RestControllerExceptionTranslator {
     @ResponseStatus(HttpStatus.BAD_REQUEST)
     @ResponseBody
     ResponseMessage handleException(JSONException exception) {
+        logger.error("json error", exception);
         return ResponseMessage.error(400, exception.getMessage());
     }
 

+ 7 - 9
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonHttpMessageConverter.java

@@ -2,6 +2,8 @@ package org.hswebframework.web.starter.convert;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.parser.ParserConfig;
+import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
+import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
 import com.alibaba.fastjson.serializer.PropertyFilter;
 import com.alibaba.fastjson.serializer.SerializeFilter;
 import com.alibaba.fastjson.serializer.SerializerFeature;
@@ -9,6 +11,7 @@ import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
 import org.hswebframework.web.ThreadLocalUtils;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
+import org.hswebframework.web.commons.model.Model;
 import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframwork.utils.StringUtils;
 import org.springframework.http.HttpInputMessage;
@@ -22,6 +25,8 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
@@ -30,13 +35,6 @@ import java.util.Set;
 
 public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
 
-    static {
-        // TODO: 17-3-16  白名单应可配置
-        ParserConfig.getGlobalInstance().addAccept("org.hswebframework.web.entity.");
-        ParserConfig.getGlobalInstance().addAccept("org.hsweb.");
-        ParserConfig.getGlobalInstance().addDeny("org.hsweb.ezorm.core.param.SqlTerm");
-    }
-
     public final static Charset UTF8 = Charset.forName("UTF-8");
 
     private Charset charset = UTF8;
@@ -85,9 +83,9 @@ public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<O
 
     public Object readByBytes(Class<?> clazz, byte[] bytes) {
         if (clazz == String.class) return new String(bytes, charset);
-        if (entityFactory != null && Entity.class.isAssignableFrom(clazz)) {
+        if (entityFactory != null && (Entity.class.isAssignableFrom(clazz) || Model.class.isAssignableFrom(clazz))) {
             @SuppressWarnings("unchecked")
-            Class<Entity> tmp = entityFactory.getInstanceType((Class<Entity>) clazz);
+            Class tmp = entityFactory.getInstanceType(clazz);
             if (tmp != null) clazz = tmp;
         }
         return JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(), clazz);