Skip to content

Commit

Permalink
RestConfig: added fallback */* converter and more explanation comments
Browse files Browse the repository at this point in the history
  • Loading branch information
virgo47 committed May 28, 2020
1 parent 4a9592f commit fe2bc91
Showing 1 changed file with 68 additions and 3 deletions.
Expand Up @@ -6,10 +6,21 @@
*/
package com.evolveum.midpoint.rest.impl;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

Expand All @@ -26,10 +37,16 @@
public class RestConfig
implements WebMvcConfigurer {

// TODO probably @Override addArgumentResolvers for @Converter processing?

/**
* Registers content-types for path extension and request parameter usage.
* Not needed for header-based content negotiation and midPoint typically
* doesn't use this, but it doesn't hurt and may be handy for download URLs.
* <p>
* See <a href="https://www.baeldung.com/spring-mvc-content-negotiation-json-xml">this
* tutorial for more about content negotiation</a>.
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
public void configureContentNegotiation(@NotNull ContentNegotiationConfigurer configurer) {
for (MediaType mediaType : MidpointYamlHttpMessageConverter.MEDIA_TYPES) {
configurer.mediaType(mediaType.getSubtype(), mediaType);
}
Expand All @@ -53,4 +70,52 @@ public MidpointJsonHttpMessageConverter jsonConverter(
PrismContext prismContext, LocalizationService localizationService) {
return new MidpointJsonHttpMessageConverter(prismContext, localizationService);
}

/**
* All beans above will be first in the converter list and other Spring converters
* will be available as well.
* We want to add "catch-all" converter for cases like error output for any (even unsupported)
* content type.
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FallbackConverter());
}

private static class FallbackConverter extends AbstractHttpMessageConverter<Object> {
/**
* Supports all media types - that's the purpose of this converter.
*/
protected FallbackConverter() {
super(MediaType.ALL);
}

/**
* Supports all object types - that's the purpose of this converter.
*/
@Override
protected boolean supports(@NotNull Class<?> clazz) {
return true;
}

/**
* Only for output, this can't read anything.
*/
@Override
public boolean canRead(@NotNull Class<?> clazz, @Nullable MediaType mediaType) {
return false;
}

@Override
protected @NotNull Object readInternal(
@NotNull Class<?> clazz, @NotNull HttpInputMessage inputMessage) {
throw new UnsupportedOperationException("FallbackConverter is write-only");
}

@Override
protected void writeInternal(@NotNull Object o, @NotNull HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
outputMessage.getBody().write(o.toString().getBytes(StandardCharsets.UTF_8));
}
}
}

0 comments on commit fe2bc91

Please sign in to comment.