-
Notifications
You must be signed in to change notification settings - Fork 188
/
RestConfig.java
121 lines (107 loc) · 4.61 KB
/
RestConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* Copyright (C) 2010-2020 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
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;
import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.prism.PrismContext;
/**
* Spring configuration for MVC-based REST service. TODO: experimental as of early 2020
* This prepares needed XML/JSON/YAML message converters.
* It also drives the package scan for REST controllers under this package.
*/
@Configuration
@ComponentScan
public class RestConfig
implements WebMvcConfigurer {
/**
* 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(@NotNull ContentNegotiationConfigurer configurer) {
for (MediaType mediaType : MidpointYamlHttpMessageConverter.MEDIA_TYPES) {
configurer.mediaType(mediaType.getSubtype(), mediaType);
}
configurer.defaultContentType(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML);
}
@Bean
public MidpointYamlHttpMessageConverter yamlConverter(
PrismContext prismContext, LocalizationService localizationService) {
return new MidpointYamlHttpMessageConverter(prismContext, localizationService);
}
@Bean
public MidpointXmlHttpMessageConverter xmlConverter(
PrismContext prismContext, LocalizationService localizationService) {
return new MidpointXmlHttpMessageConverter(prismContext, localizationService);
}
@Bean
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));
}
}
}