类org.springframework.core.codec.Encoder源码实例Demo

下面列出了怎么用org.springframework.core.codec.Encoder的API类实例代码及写法,或者点击链接到github查看源代码。


private MessageMappingMessageHandler initMesssageHandler() {

		List<Decoder<?>> decoders = Collections.singletonList(StringDecoder.allMimeTypes());
		List<Encoder<?>> encoders = Collections.singletonList(CharSequenceEncoder.allMimeTypes());

		ReactiveAdapterRegistry registry = ReactiveAdapterRegistry.getSharedInstance();
		this.returnValueHandler = new TestEncoderMethodReturnValueHandler(encoders, registry);

		PropertySource<?> source = new MapPropertySource("test", Collections.singletonMap("path", "path123"));

		StaticApplicationContext context = new StaticApplicationContext();
		context.getEnvironment().getPropertySources().addFirst(source);
		context.registerSingleton("testController", TestController.class);
		context.refresh();

		MessageMappingMessageHandler messageHandler = new MessageMappingMessageHandler();
		messageHandler.getReturnValueHandlerConfigurer().addCustomHandler(this.returnValueHandler);
		messageHandler.setApplicationContext(context);
		messageHandler.setEmbeddedValueResolver(new EmbeddedValueResolver(context.getBeanFactory()));
		messageHandler.setDecoders(decoders);
		messageHandler.afterPropertiesSet();

		return messageHandler;
	}
 

@SuppressWarnings("unchecked")
private <T> List<DataBuffer> encodeEvent(CharSequence markup, @Nullable T data, ResolvableType dataType,
		MediaType mediaType, DataBufferFactory factory, Map<String, Object> hints) {

	List<DataBuffer> result = new ArrayList<>(4);
	result.add(encodeText(markup, mediaType, factory));
	if (data != null) {
		if (data instanceof String) {
			String dataLine = StringUtils.replace((String) data, "\n", "\ndata:") + "\n";
			result.add(encodeText(dataLine, mediaType, factory));
		}
		else if (this.encoder == null) {
			throw new CodecException("No SSE encoder configured and the data is not String.");
		}
		else {
			result.add(((Encoder<T>) this.encoder).encodeValue(data, factory, dataType, mediaType, hints));
			result.add(encodeText("\n", mediaType, factory));
		}
	}
	result.add(encodeText("\n", mediaType, factory));
	return result;
}
 

/**
 * Return writers that support specific types.
 * @param forMultipart whether to returns writers for general use ("false"),
 * or for multipart requests only ("true"). Generally the two sets are the
 * same except for the multipart writer itself.
 */
@SuppressWarnings("unchecked")
final List<HttpMessageWriter<?>> getTypedWriters(boolean forMultipart) {
	if (!this.registerDefaults) {
		return Collections.emptyList();
	}
	List<HttpMessageWriter<?>> writers = new ArrayList<>();
	writers.add(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
	writers.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
	writers.add(new EncoderHttpMessageWriter<>(new DataBufferEncoder()));
	writers.add(new ResourceHttpMessageWriter());
	writers.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
	// No client or server specific multipart writers currently..
	if (!forMultipart) {
		extendTypedWriters(writers);
	}
	if (protobufPresent) {
		Encoder<?> encoder = this.protobufEncoder != null ? this.protobufEncoder : new ProtobufEncoder();
		writers.add(new ProtobufHttpMessageWriter((Encoder) encoder));
	}
	return writers;
}
 

/**
 * Return Object writers (JSON, XML, SSE).
 * @param forMultipart whether to returns writers for general use ("false"),
 * or for multipart requests only ("true"). Generally the two sets are the
 * same except for the multipart writer itself.
 */
final List<HttpMessageWriter<?>> getObjectWriters(boolean forMultipart) {
	if (!this.registerDefaults) {
		return Collections.emptyList();
	}
	List<HttpMessageWriter<?>> writers = new ArrayList<>();
	if (jackson2Present) {
		writers.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
	}
	if (jackson2SmilePresent) {
		writers.add(new EncoderHttpMessageWriter<>(new Jackson2SmileEncoder()));
	}
	if (jaxb2Present) {
		Encoder<?> encoder = this.jaxb2Encoder != null ? this.jaxb2Encoder : new Jaxb2XmlEncoder();
		writers.add(new EncoderHttpMessageWriter<>(encoder));
	}
	// No client or server specific multipart writers currently..
	if (!forMultipart) {
		extendObjectWriters(writers);
	}
	return writers;
}
 

@SuppressWarnings("unchecked")
private <T> Flux<DataBuffer> encodeData(@Nullable T data, ResolvableType valueType,
		MediaType mediaType, DataBufferFactory factory, Map<String, Object> hints) {

	if (data == null) {
		return Flux.empty();
	}

	if (data instanceof String) {
		String text = (String) data;
		return Flux.from(encodeText(StringUtils.replace(text, "\n", "\ndata:") + "\n", mediaType, factory));
	}

	if (this.encoder == null) {
		return Flux.error(new CodecException("No SSE encoder configured and the data is not String."));
	}

	return ((Encoder<T>) this.encoder)
			.encode(Mono.just(data), factory, valueType, mediaType, hints)
			.concatWith(encodeText("\n", mediaType, factory));
}
 

/**
 * Return writers that support specific types.
 * @param forMultipart whether to returns writers for general use ("false"),
 * or for multipart requests only ("true"). Generally the two sets are the
 * same except for the multipart writer itself.
 */
@SuppressWarnings("unchecked")
final List<HttpMessageWriter<?>> getTypedWriters(boolean forMultipart) {
	if (!this.registerDefaults) {
		return Collections.emptyList();
	}
	List<HttpMessageWriter<?>> writers = new ArrayList<>();
	writers.add(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
	writers.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
	writers.add(new EncoderHttpMessageWriter<>(new DataBufferEncoder()));
	writers.add(new ResourceHttpMessageWriter());
	writers.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
	// No client or server specific multipart writers currently..
	if (!forMultipart) {
		extendTypedWriters(writers);
	}
	if (protobufPresent) {
		Encoder<?> encoder = this.protobufEncoder != null ? this.protobufEncoder : new ProtobufEncoder();
		writers.add(new ProtobufHttpMessageWriter((Encoder) encoder));
	}
	return writers;
}
 

/**
 * Return Object writers (JSON, XML, SSE).
 * @param forMultipart whether to returns writers for general use ("false"),
 * or for multipart requests only ("true"). Generally the two sets are the
 * same except for the multipart writer itself.
 */
final List<HttpMessageWriter<?>> getObjectWriters(boolean forMultipart) {
	if (!this.registerDefaults) {
		return Collections.emptyList();
	}
	List<HttpMessageWriter<?>> writers = new ArrayList<>();
	if (jackson2Present) {
		writers.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
	}
	if (jackson2SmilePresent) {
		writers.add(new EncoderHttpMessageWriter<>(new Jackson2SmileEncoder()));
	}
	if (jaxb2Present) {
		Encoder<?> encoder = this.jaxb2Encoder != null ? this.jaxb2Encoder : new Jaxb2XmlEncoder();
		writers.add(new EncoderHttpMessageWriter<>(encoder));
	}
	// No client or server specific multipart writers currently..
	if (!forMultipart) {
		extendObjectWriters(writers);
	}
	return writers;
}
 

@SuppressWarnings("unchecked")
private Flux<DataBuffer> encodeContent(
		@Nullable Object content, MethodParameter returnType, DataBufferFactory bufferFactory,
		@Nullable MimeType mimeType, Map<String, Object> hints) {

	ResolvableType returnValueType = ResolvableType.forMethodParameter(returnType);
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnValueType.resolve(), content);

	Publisher<?> publisher;
	ResolvableType elementType;
	if (adapter != null) {
		publisher = adapter.toPublisher(content);
		boolean isUnwrapped = KotlinDetector.isKotlinReflectPresent() &&
				KotlinDetector.isKotlinType(returnType.getContainingClass()) &&
				KotlinDelegate.isSuspend(returnType.getMethod()) &&
				!COROUTINES_FLOW_CLASS_NAME.equals(returnValueType.toClass().getName());
		ResolvableType genericType = isUnwrapped ? returnValueType : returnValueType.getGeneric();
		elementType = getElementType(adapter, genericType);
	}
	else {
		publisher = Mono.justOrEmpty(content);
		elementType = (returnValueType.toClass() == Object.class && content != null ?
				ResolvableType.forInstance(content) : returnValueType);
	}

	if (elementType.resolve() == void.class || elementType.resolve() == Void.class) {
		return Flux.from(publisher).cast(DataBuffer.class);
	}

	Encoder<?> encoder = getEncoder(elementType, mimeType);
	return Flux.from((Publisher) publisher).map(value ->
			encodeValue(value, elementType, encoder, bufferFactory, mimeType, hints));
}
 

@Nullable
@SuppressWarnings("unchecked")
private <T> Encoder<T> getEncoder(ResolvableType elementType, @Nullable MimeType mimeType) {
	for (Encoder<?> encoder : getEncoders()) {
		if (encoder.canEncode(elementType, mimeType)) {
			return (Encoder<T>) encoder;
		}
	}
	return null;
}
 

@SuppressWarnings("unchecked")
private <T> DataBuffer encodeValue(
		Object element, ResolvableType elementType, @Nullable Encoder<T> encoder,
		DataBufferFactory bufferFactory, @Nullable MimeType mimeType,
		@Nullable Map<String, Object> hints) {

	if (encoder == null) {
		encoder = getEncoder(ResolvableType.forInstance(element), mimeType);
		if (encoder == null) {
			throw new MessagingException(
					"No encoder for " + elementType + ", current value type is " + element.getClass());
		}
	}
	return encoder.encodeValue((T) element, bufferFactory, elementType, mimeType, hints);
}
 

/**
 * Return the {@code RSocketStrategies} instance provided via
 * {@link #setRSocketStrategies rsocketStrategies}, or
 * otherwise initialize it with the configured {@link #setEncoders(List)
 * encoders}, {@link #setDecoders(List) decoders}, and others.
 */
public RSocketStrategies getRSocketStrategies() {
	if (this.rsocketStrategies == null) {
		this.rsocketStrategies = RSocketStrategies.builder()
				.decoder(getDecoders().toArray(new Decoder<?>[0]))
				.encoder(getEncoders().toArray(new Encoder<?>[0]))
				.reactiveAdapterStrategy(getReactiveAdapterRegistry())
				.build();
	}
	return this.rsocketStrategies;
}
 

private DefaultRSocketStrategies(List<Encoder<?>> encoders, List<Decoder<?>> decoders,
		ReactiveAdapterRegistry adapterRegistry, DataBufferFactory bufferFactory) {

	this.encoders = Collections.unmodifiableList(encoders);
	this.decoders = Collections.unmodifiableList(decoders);
	this.adapterRegistry = adapterRegistry;
	this.bufferFactory = bufferFactory;
}
 

@SuppressWarnings("unchecked")
private <T> DataBuffer encodeValue(T value, ResolvableType valueType, @Nullable Encoder<?> encoder) {
	if (encoder == null) {
		encoder = strategies.encoder(ResolvableType.forInstance(value), dataMimeType);
	}
	return ((Encoder<T>) encoder).encodeValue(
			value, strategies.dataBufferFactory(), valueType, dataMimeType, EMPTY_HINTS);
}
 

/**
 * Create an instance wrapping the given {@link Encoder}.
 */
public EncoderHttpMessageWriter(Encoder<T> encoder) {
	Assert.notNull(encoder, "Encoder is required");
	initLogger(encoder);
	this.encoder = encoder;
	this.mediaTypes = MediaType.asMediaTypes(encoder.getEncodableMimeTypes());
	this.defaultMediaType = initDefaultMediaType(this.mediaTypes);
}
 

private static void initLogger(Encoder<?> encoder) {
	if (encoder instanceof AbstractEncoder &&
			encoder.getClass().getName().startsWith("org.springframework.core.codec")) {
		Log logger = HttpLogging.forLog(((AbstractEncoder) encoder).getLogger());
		((AbstractEncoder) encoder).setLogger(logger);
	}
}
 

private void assertSseWriter(List<HttpMessageWriter<?>> writers) {
	HttpMessageWriter<?> writer = writers.get(this.index.getAndIncrement());
	assertEquals(ServerSentEventHttpMessageWriter.class, writer.getClass());
	Encoder<?> encoder = ((ServerSentEventHttpMessageWriter) writer).getEncoder();
	assertNotNull(encoder);
	assertEquals(Jackson2JsonEncoder.class, encoder.getClass());
}
 

@Test
public void defaultAndCustomWriters() {
	Encoder<?> customEncoder1 = mock(Encoder.class);
	Encoder<?> customEncoder2 = mock(Encoder.class);

	given(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).willReturn(false);
	given(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).willReturn(true);

	HttpMessageWriter<?> customWriter1 = mock(HttpMessageWriter.class);
	HttpMessageWriter<?> customWriter2 = mock(HttpMessageWriter.class);

	given(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).willReturn(false);
	given(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).willReturn(true);

	this.configurer.customCodecs().encoder(customEncoder1);
	this.configurer.customCodecs().encoder(customEncoder2);

	this.configurer.customCodecs().writer(customWriter1);
	this.configurer.customCodecs().writer(customWriter2);

	List<HttpMessageWriter<?>> writers = this.configurer.getWriters();

	assertEquals(14, writers.size());
	assertSame(customEncoder1, getNextEncoder(writers));
	assertSame(customWriter1, writers.get(this.index.getAndIncrement()));
	assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(ByteBufferEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(DataBufferEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(ResourceHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass());
	assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(ProtobufHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass());
	assertSame(customEncoder2, getNextEncoder(writers));
	assertSame(customWriter2, writers.get(this.index.getAndIncrement()));
	assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(Jackson2SmileEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass());
}
 

@Test
public void defaultsOffWithCustomWriters() {
	Encoder<?> customEncoder1 = mock(Encoder.class);
	Encoder<?> customEncoder2 = mock(Encoder.class);

	given(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).willReturn(false);
	given(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).willReturn(true);

	HttpMessageWriter<?> customWriter1 = mock(HttpMessageWriter.class);
	HttpMessageWriter<?> customWriter2 = mock(HttpMessageWriter.class);

	given(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).willReturn(false);
	given(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).willReturn(true);

	this.configurer.customCodecs().encoder(customEncoder1);
	this.configurer.customCodecs().encoder(customEncoder2);

	this.configurer.customCodecs().writer(customWriter1);
	this.configurer.customCodecs().writer(customWriter2);

	this.configurer.registerDefaults(false);

	List<HttpMessageWriter<?>> writers = this.configurer.getWriters();

	assertEquals(4, writers.size());
	assertSame(customEncoder1, getNextEncoder(writers));
	assertSame(customWriter1, writers.get(this.index.getAndIncrement()));
	assertSame(customEncoder2, getNextEncoder(writers));
	assertSame(customWriter2, writers.get(this.index.getAndIncrement()));
}
 

private void assertEncoderInstance(Encoder<?> encoder) {
	assertSame(encoder, this.configurer.getWriters().stream()
			.filter(writer -> writer instanceof EncoderHttpMessageWriter)
			.map(writer -> ((EncoderHttpMessageWriter<?>) writer).getEncoder())
			.filter(e -> encoder.getClass().equals(e.getClass()))
			.findFirst()
			.filter(e -> e == encoder).orElse(null));
}
 

/**
 * Create an instance wrapping the given {@link Encoder}.
 */
public EncoderHttpMessageWriter(Encoder<T> encoder) {
	Assert.notNull(encoder, "Encoder is required");
	initLogger(encoder);
	this.encoder = encoder;
	this.mediaTypes = MediaType.asMediaTypes(encoder.getEncodableMimeTypes());
	this.defaultMediaType = initDefaultMediaType(this.mediaTypes);
}
 

private static void initLogger(Encoder<?> encoder) {
	if (encoder instanceof AbstractEncoder &&
			encoder.getClass().getName().startsWith("org.springframework.core.codec")) {
		Log logger = HttpLogging.forLog(((AbstractEncoder) encoder).getLogger());
		((AbstractEncoder) encoder).setLogger(logger);
	}
}
 

private void assertSseWriter(List<HttpMessageWriter<?>> writers) {
	HttpMessageWriter<?> writer = writers.get(this.index.getAndIncrement());
	assertEquals(ServerSentEventHttpMessageWriter.class, writer.getClass());
	Encoder<?> encoder = ((ServerSentEventHttpMessageWriter) writer).getEncoder();
	assertNotNull(encoder);
	assertEquals(Jackson2JsonEncoder.class, encoder.getClass());
}
 

@Test
public void defaultAndCustomWriters() {
	Encoder<?> customEncoder1 = mock(Encoder.class);
	Encoder<?> customEncoder2 = mock(Encoder.class);

	when(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(false);
	when(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(true);

	HttpMessageWriter<?> customWriter1 = mock(HttpMessageWriter.class);
	HttpMessageWriter<?> customWriter2 = mock(HttpMessageWriter.class);

	when(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(false);
	when(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(true);

	this.configurer.customCodecs().encoder(customEncoder1);
	this.configurer.customCodecs().encoder(customEncoder2);

	this.configurer.customCodecs().writer(customWriter1);
	this.configurer.customCodecs().writer(customWriter2);

	List<HttpMessageWriter<?>> writers = this.configurer.getWriters();

	assertEquals(14, writers.size());
	assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(ByteBufferEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(DataBufferEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(ResourceHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass());
	assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(ProtobufHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass());
	assertSame(customEncoder1, getNextEncoder(writers));
	assertSame(customWriter1, writers.get(this.index.getAndIncrement()));
	assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(Jackson2SmileEncoder.class, getNextEncoder(writers).getClass());
	assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass());
	assertSame(customEncoder2, getNextEncoder(writers));
	assertSame(customWriter2, writers.get(this.index.getAndIncrement()));
	assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass());
}
 

@Test
public void defaultsOffWithCustomWriters() {
	Encoder<?> customEncoder1 = mock(Encoder.class);
	Encoder<?> customEncoder2 = mock(Encoder.class);

	when(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(false);
	when(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(true);

	HttpMessageWriter<?> customWriter1 = mock(HttpMessageWriter.class);
	HttpMessageWriter<?> customWriter2 = mock(HttpMessageWriter.class);

	when(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(false);
	when(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(true);

	this.configurer.customCodecs().encoder(customEncoder1);
	this.configurer.customCodecs().encoder(customEncoder2);

	this.configurer.customCodecs().writer(customWriter1);
	this.configurer.customCodecs().writer(customWriter2);

	this.configurer.registerDefaults(false);

	List<HttpMessageWriter<?>> writers = this.configurer.getWriters();

	assertEquals(4, writers.size());
	assertSame(customEncoder1, getNextEncoder(writers));
	assertSame(customWriter1, writers.get(this.index.getAndIncrement()));
	assertSame(customEncoder2, getNextEncoder(writers));
	assertSame(customWriter2, writers.get(this.index.getAndIncrement()));
}
 

private void assertEncoderInstance(Encoder<?> encoder) {
	assertSame(encoder, this.configurer.getWriters().stream()
			.filter(writer -> writer instanceof EncoderHttpMessageWriter)
			.map(writer -> ((EncoderHttpMessageWriter<?>) writer).getEncoder())
			.filter(e -> encoder.getClass().equals(e.getClass()))
			.findFirst()
			.filter(e -> e == encoder).orElse(null));
}
 

@SuppressWarnings("unchecked")
private <T> DataBuffer encodeEntry(Object metadata, MimeType mimeType) {
	if (metadata instanceof ByteBuf) {
		return asDataBuffer((ByteBuf) metadata);
	}
	ResolvableType type = ResolvableType.forInstance(metadata);
	Encoder<T> encoder = this.strategies.encoder(type, mimeType);
	Assert.notNull(encoder, () -> "No encoder for metadata " + metadata
			+ ", mimeType '" + mimeType + "'");
	return encoder.encodeValue((T) metadata, bufferFactory(), type, mimeType,
			Collections.emptyMap());
}
 

protected AbstractEncoderMethodReturnValueHandler(List<Encoder<?>> encoders, ReactiveAdapterRegistry registry) {
	Assert.notEmpty(encoders, "At least one Encoder is required");
	Assert.notNull(registry, "ReactiveAdapterRegistry is required");
	this.encoders = Collections.unmodifiableList(encoders);
	this.adapterRegistry = registry;
}
 

/**
 * The configured encoders.
 */
public List<Encoder<?>> getEncoders() {
	return this.encoders;
}
 

/**
 * Configure the encoders to use for encoding handler method return values.
 */
public void setEncoders(List<? extends Encoder<?>> encoders) {
	this.encoders.addAll(encoders);
}
 

/**
 * Return the configured {@link #setEncoders(List) encoders}.
 */
public List<? extends Encoder<?>> getEncoders() {
	return this.encoders;
}
 
 类所在包
 类方法
 同包方法