mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-06-20 11:42:24 +08:00
优化拓展实体支持
This commit is contained in:
@@ -38,6 +38,13 @@
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -13,12 +13,14 @@
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.api.crud.entity;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* 实体工厂接口,系统各个地方使用此接口来创建实体,在实际编码中也应该使用此接口来创建实体,而不是使用new方式来创建
|
||||
*
|
||||
@@ -97,11 +99,12 @@ public interface EntityFactory {
|
||||
* @param <T> 泛型
|
||||
* @return 实体类型
|
||||
*/
|
||||
default <T> Class<T> getInstanceType(Class<T> entityClass){
|
||||
return getInstanceType(entityClass,false);
|
||||
}
|
||||
default <T> Class<T> getInstanceType(Class<T> entityClass) {
|
||||
return getInstanceType(entityClass, false);
|
||||
}
|
||||
|
||||
<T> Class<T> getInstanceType(Class<T> entityClass,boolean autoRegister);
|
||||
@Nullable
|
||||
<T> Class<T> getInstanceType(Class<T> entityClass, boolean autoRegister);
|
||||
|
||||
/**
|
||||
* 拷贝对象的属性
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.hswebframework.web.api.crud.entity;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public final class EntityFactoryHolder {
|
||||
|
||||
static EntityFactory FACTORY;
|
||||
|
||||
public static EntityFactory get() {
|
||||
if (FACTORY == null) {
|
||||
throw new IllegalStateException("EntityFactory Not Ready Yet");
|
||||
}
|
||||
return FACTORY;
|
||||
}
|
||||
|
||||
public static <T> T newInstance(Class<T> type,
|
||||
Supplier<T> mapper) {
|
||||
if (FACTORY != null) {
|
||||
return FACTORY.newInstance(type);
|
||||
}
|
||||
return mapper.get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.hswebframework.web.api.crud.entity;
|
||||
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class EntityFactoryHolderConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
public ApplicationContextAware entityFactoryHolder() {
|
||||
return context -> EntityFactoryHolder.FACTORY = context.getBean(EntityFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,9 @@ package org.hswebframework.web.api.crud.entity;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.hswebframework.ezorm.core.param.QueryParam;
|
||||
|
||||
@@ -33,15 +35,20 @@ public class PagerResult<E> {
|
||||
private static final long serialVersionUID = -6171751136953308027L;
|
||||
|
||||
public static <E> PagerResult<E> empty() {
|
||||
return new PagerResult<>(0, new ArrayList<>());
|
||||
return of(0, new ArrayList<>());
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static <E> PagerResult<E> of(int total, List<E> list) {
|
||||
return new PagerResult<>(total, list);
|
||||
PagerResult<E> result;
|
||||
result = EntityFactoryHolder.newInstance(PagerResult.class, PagerResult::new);
|
||||
result.setTotal(total);
|
||||
result.setData(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <E> PagerResult<E> of(int total, List<E> list, QueryParam entity) {
|
||||
PagerResult<E> pagerResult = new PagerResult<>(total, list);
|
||||
PagerResult<E> pagerResult = of(total, list);
|
||||
pagerResult.setPageIndex(entity.getThinkPageIndex());
|
||||
pagerResult.setPageSize(entity.getPageSize());
|
||||
return pagerResult;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.hswebframework.web.api.crud.entity.EntityFactoryHolderConfiguration
|
||||
@@ -17,6 +17,7 @@ import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
|
||||
import org.hswebframework.ezorm.rdb.operator.DefaultDatabaseOperator;
|
||||
import org.hswebframework.web.api.crud.entity.EntityFactory;
|
||||
import org.hswebframework.web.crud.annotation.EnableEasyormRepository;
|
||||
import org.hswebframework.web.crud.entity.factory.EntityMappingCustomizer;
|
||||
import org.hswebframework.web.crud.entity.factory.MapperEntityFactory;
|
||||
import org.hswebframework.web.crud.events.CompositeEventListener;
|
||||
import org.hswebframework.web.crud.events.EntityEventListener;
|
||||
@@ -26,6 +27,7 @@ import org.hswebframework.web.crud.generator.DefaultIdGenerator;
|
||||
import org.hswebframework.web.crud.generator.MD5Generator;
|
||||
import org.hswebframework.web.crud.generator.SnowFlakeStringIdGenerator;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -52,8 +54,12 @@ public class EasyormConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EntityFactory entityFactory() {
|
||||
return new MapperEntityFactory();
|
||||
public EntityFactory entityFactory(ObjectProvider<EntityMappingCustomizer> customizers) {
|
||||
MapperEntityFactory factory= new MapperEntityFactory();
|
||||
for (EntityMappingCustomizer customizer : customizers) {
|
||||
customizer.custom(factory);
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.hswebframework.web.crud.entity.factory;
|
||||
|
||||
public interface EntityMappingCustomizer {
|
||||
|
||||
void custom(MapperEntityFactory factory);
|
||||
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
|
||||
private static final DefaultMapperFactory DEFAULT_MAPPER_FACTORY = clazz -> {
|
||||
String simpleClassName = clazz.getPackage().getName().concat(".Simple").concat(clazz.getSimpleName());
|
||||
try {
|
||||
return defaultMapper(org.springframework.util.ClassUtils.forName(simpleClassName,null));
|
||||
return defaultMapper(org.springframework.util.ClassUtils.forName(simpleClassName, null));
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
// throw new NotFoundException(e.getMessage());
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
|
||||
public MapperEntityFactory() {
|
||||
}
|
||||
|
||||
public MapperEntityFactory(Map<Class<?>, Mapper> realTypeMapper) {
|
||||
public MapperEntityFactory(Map<Class<?>, Mapper<?>> realTypeMapper) {
|
||||
this.realTypeMapper.putAll(realTypeMapper);
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperEntityFactory addCopier(PropertyCopier copier) {
|
||||
Class source = ClassUtils.getGenericType(copier.getClass(), 0);
|
||||
Class target = ClassUtils.getGenericType(copier.getClass(), 1);
|
||||
public <S, T> MapperEntityFactory addCopier(PropertyCopier<S, T> copier) {
|
||||
Class<S> source = (Class<S>) ClassUtils.getGenericType(copier.getClass(), 0);
|
||||
Class<T> target = (Class<T>) ClassUtils.getGenericType(copier.getClass(), 1);
|
||||
if (source == null || source == Object.class) {
|
||||
throw new UnsupportedOperationException("generic type " + source + " not support");
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getCopierCacheKey(Class source, Class target) {
|
||||
private String getCopierCacheKey(Class<?> source, Class<?> target) {
|
||||
return source.getName().concat("->").concat(target.getName());
|
||||
}
|
||||
|
||||
@@ -122,11 +122,13 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
|
||||
}
|
||||
|
||||
if (realType == null) {
|
||||
mapper = defaultMapperFactory.apply(beanClass);
|
||||
}
|
||||
if (!Modifier.isInterface(beanClass.getModifiers()) && !Modifier.isAbstract(beanClass.getModifiers())) {
|
||||
realType = beanClass;
|
||||
if (!Modifier.isInterface(beanClass.getModifiers()) && !Modifier.isAbstract(beanClass.getModifiers())) {
|
||||
realType = beanClass;
|
||||
}else {
|
||||
mapper = defaultMapperFactory.apply(beanClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (mapper == null && realType != null) {
|
||||
if (logger.isDebugEnabled() && realType != beanClass) {
|
||||
logger.debug("use instance {} for {}", realType, beanClass);
|
||||
@@ -170,7 +172,7 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
|
||||
return (T) new HashSet<>();
|
||||
}
|
||||
|
||||
throw new NotFoundException("can't create instance for " + beanClass);
|
||||
throw new NotFoundException("error.cant_create_instance",beanClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,34 +2,36 @@ package org.hswebframework.web.crud.web;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hswebframework.web.api.crud.entity.EntityFactoryHolder;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ResponseMessage<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8992436576262574064L;
|
||||
|
||||
@Schema(description = "消息提示")
|
||||
protected String message;
|
||||
private String message;
|
||||
|
||||
@Schema(description = "数据内容")
|
||||
protected T result;
|
||||
private T result;
|
||||
|
||||
@Schema(description = "状态码")
|
||||
private int status;
|
||||
|
||||
@Schema(description = "业务码")
|
||||
protected String code;
|
||||
private String code;
|
||||
|
||||
@Schema(description = "时间戳(毫秒)")
|
||||
protected Long timestamp = System.currentTimeMillis();
|
||||
private Long timestamp = System.currentTimeMillis();
|
||||
|
||||
public ResponseMessage() {
|
||||
}
|
||||
|
||||
public static <T> ResponseMessage<T> ok() {
|
||||
return ok(null);
|
||||
@@ -37,11 +39,7 @@ public class ResponseMessage<T> implements Serializable {
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static <T> ResponseMessage<T> ok(T result) {
|
||||
return (ResponseMessage) ResponseMessage.builder()
|
||||
.result(result)
|
||||
.status(200)
|
||||
.code("success")
|
||||
.build();
|
||||
return of("success", null, 200, null, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static <T> ResponseMessage<T> error(String message) {
|
||||
@@ -53,10 +51,21 @@ public class ResponseMessage<T> implements Serializable {
|
||||
}
|
||||
|
||||
public static <T> ResponseMessage<T> error(int status, String code, String message) {
|
||||
ResponseMessage<T> msg = new ResponseMessage<>();
|
||||
msg.message = message;
|
||||
msg.code = code;
|
||||
msg.status = status;
|
||||
return of(message, null, status, code, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static <T> ResponseMessage<T> of(String message,
|
||||
T result,
|
||||
int status,
|
||||
String code,
|
||||
Long timestamp) {
|
||||
@SuppressWarnings("all")
|
||||
ResponseMessage<T> msg = EntityFactoryHolder.newInstance(ResponseMessage.class, ResponseMessage::new);
|
||||
msg.setMessage(message);
|
||||
msg.setResult(result);
|
||||
msg.setStatus(status);
|
||||
msg.setCode(code);
|
||||
msg.setTimestamp(timestamp);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.springframework.core.ReactiveAdapterRegistry;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -51,7 +52,7 @@ public class ResponseMessageWrapper extends ResponseBodyResultHandler {
|
||||
private Set<String> excludes = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public boolean supports(HandlerResult result) {
|
||||
public boolean supports(@NonNull HandlerResult result) {
|
||||
|
||||
if (!CollectionUtils.isEmpty(excludes) && result.getHandler() instanceof HandlerMethod) {
|
||||
HandlerMethod method = (HandlerMethod) result.getHandler();
|
||||
|
||||
@@ -68,5 +68,11 @@
|
||||
<artifactId>r2dbc-h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -29,14 +29,15 @@ public class CustomCodecsAutoConfiguration {
|
||||
CodecCustomizer jacksonDecoderCustomizer(EntityFactory entityFactory, ObjectMapper objectMapper) {
|
||||
// objectMapper.setTypeFactory(new CustomTypeFactory(entityFactory));
|
||||
SimpleModule module = new SimpleModule();
|
||||
JsonDeserializer deserializer = new EnumDict.EnumDictJSONDeserializer();
|
||||
@SuppressWarnings("all")
|
||||
JsonDeserializer<Enum<?>> deserializer = new EnumDict.EnumDictJSONDeserializer();
|
||||
module.addDeserializer(Enum.class, deserializer);
|
||||
objectMapper.registerModule(module);
|
||||
|
||||
|
||||
return (configurer) -> {
|
||||
CodecConfigurer.DefaultCodecs defaults = configurer.defaultCodecs();
|
||||
defaults.jackson2JsonDecoder(new CustomJackson2JsonDecoder(objectMapper));
|
||||
defaults.jackson2JsonDecoder(new CustomJackson2JsonDecoder(entityFactory,objectMapper));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
|
||||
import com.fasterxml.jackson.databind.util.TokenBuffer;
|
||||
import org.hswebframework.web.api.crud.entity.EntityFactory;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
@@ -19,12 +20,14 @@ import org.springframework.http.codec.HttpMessageDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2CodecSupport;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -33,11 +36,14 @@ import java.util.Map;
|
||||
|
||||
public class CustomJackson2JsonDecoder extends Jackson2CodecSupport implements HttpMessageDecoder<Object> {
|
||||
|
||||
private final EntityFactory entityFactory;
|
||||
|
||||
/**
|
||||
* Constructor with a Jackson {@link ObjectMapper} to use.
|
||||
*/
|
||||
public CustomJackson2JsonDecoder(ObjectMapper mapper, MimeType... mimeTypes) {
|
||||
public CustomJackson2JsonDecoder(EntityFactory entityFactory, ObjectMapper mapper, MimeType... mimeTypes) {
|
||||
super(mapper, mimeTypes);
|
||||
this.entityFactory = entityFactory;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +57,8 @@ public class CustomJackson2JsonDecoder extends Jackson2CodecSupport implements H
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Object> decode(Publisher<DataBuffer> input, ResolvableType elementType,
|
||||
@NonNull
|
||||
public Flux<Object> decode(@NonNull Publisher<DataBuffer> input, @NonNull ResolvableType elementType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
ObjectMapper mapper = getObjectMapper();
|
||||
@@ -74,15 +81,17 @@ public class CustomJackson2JsonDecoder extends Jackson2CodecSupport implements H
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Object> decodeToMono(Publisher<DataBuffer> input, ResolvableType elementType,
|
||||
@NonNull
|
||||
public Mono<Object> decodeToMono(@NonNull Publisher<DataBuffer> input, @NonNull ResolvableType elementType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
return DataBufferUtils.join(input)
|
||||
.map(dataBuffer -> decode(dataBuffer, elementType, mimeType, hints));
|
||||
.map(dataBuffer -> decode(dataBuffer, elementType, mimeType, hints));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
|
||||
@NonNull
|
||||
public Object decode(@NonNull DataBuffer dataBuffer, @NonNull ResolvableType targetType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) throws DecodingException {
|
||||
|
||||
try {
|
||||
@@ -101,8 +110,13 @@ public class CustomJackson2JsonDecoder extends Jackson2CodecSupport implements H
|
||||
Assert.notNull(elementType, "'elementType' must not be null");
|
||||
MethodParameter param = getParameter(elementType);
|
||||
Class<?> contextClass = (param != null ? param.getContainingClass() : null);
|
||||
Type type = elementType.resolve() == null ? elementType.getType() : elementType.resolve();
|
||||
|
||||
Type type = elementType.resolve() == null ? elementType.getType() : elementType.toClass();
|
||||
if (type instanceof Class) {
|
||||
Class<?> realType = entityFactory.getInstanceType(((Class<?>) type), false);
|
||||
if (realType != null) {
|
||||
type = realType;
|
||||
}
|
||||
}
|
||||
JavaType javaType = getJavaType(type, contextClass);
|
||||
Class<?> jsonView = (hints != null ? (Class<?>) hints.get(Jackson2CodecSupport.JSON_VIEW_HINT) : null);
|
||||
return jsonView != null ?
|
||||
@@ -135,13 +149,15 @@ public class CustomJackson2JsonDecoder extends Jackson2CodecSupport implements H
|
||||
// HttpMessageDecoder...
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getDecodeHints(ResolvableType actualType, ResolvableType elementType,
|
||||
ServerHttpRequest request, ServerHttpResponse response) {
|
||||
@NonNull
|
||||
public Map<String, Object> getDecodeHints(@NonNull ResolvableType actualType, @NonNull ResolvableType elementType,
|
||||
@NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
|
||||
|
||||
return getHints(actualType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public List<MimeType> getDecodableMimeTypes() {
|
||||
return getMimeTypes();
|
||||
}
|
||||
@@ -149,7 +165,7 @@ public class CustomJackson2JsonDecoder extends Jackson2CodecSupport implements H
|
||||
// Jackson2CodecSupport ...
|
||||
|
||||
@Override
|
||||
protected <A extends Annotation> A getAnnotation(MethodParameter parameter, Class<A> annotType) {
|
||||
protected <A extends Annotation> A getAnnotation(MethodParameter parameter, @NonNull Class<A> annotType) {
|
||||
return parameter.getParameterAnnotation(annotType);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.hswebframework.web.starter.jackson;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.SneakyThrows;
|
||||
import org.hswebframework.web.api.crud.entity.EntityFactory;
|
||||
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
|
||||
import org.hswebframework.web.crud.entity.factory.MapperEntityFactory;
|
||||
import org.hswebframework.web.crud.web.reactive.ReactiveQueryController;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DefaultDataBuffer;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MimeType;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class CustomJackson2JsonDecoderTest {
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDecodeCustomType() {
|
||||
|
||||
MapperEntityFactory entityFactory = new MapperEntityFactory();
|
||||
|
||||
entityFactory.addMapping(QueryParamEntity.class,MapperEntityFactory.defaultMapper(CustomQueryParamEntity.class));
|
||||
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
CustomJackson2JsonDecoder decoder = new CustomJackson2JsonDecoder(entityFactory, mapper);
|
||||
|
||||
ResolvableType type = ResolvableType.forMethodParameter(
|
||||
ReactiveQueryController.class.getMethod("query", QueryParamEntity.class), 0
|
||||
);
|
||||
|
||||
DataBuffer buffer = new DefaultDataBufferFactory().wrap("{}".getBytes());
|
||||
|
||||
Object object = decoder.decode(buffer, type, MediaType.APPLICATION_JSON, Collections.emptyMap());
|
||||
|
||||
assertTrue(object instanceof CustomQueryParamEntity);
|
||||
|
||||
}
|
||||
|
||||
public static class CustomQueryParamEntity extends QueryParamEntity {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user