Skip to content

Commit 9ce2d76

Browse files
authored
Merge HttpMessageConverterAuthenticationSuccessHandler Supports Jackson 3
2 parents 1575610 + fb84e24 commit 9ce2d76

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2004-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.web.authentication;
18+
19+
import java.io.IOException;
20+
import java.lang.reflect.Type;
21+
import java.util.List;
22+
23+
import org.jspecify.annotations.Nullable;
24+
25+
import org.springframework.core.ResolvableType;
26+
import org.springframework.http.HttpInputMessage;
27+
import org.springframework.http.HttpOutputMessage;
28+
import org.springframework.http.MediaType;
29+
import org.springframework.http.converter.GenericHttpMessageConverter;
30+
import org.springframework.http.converter.HttpMessageNotReadableException;
31+
import org.springframework.http.converter.HttpMessageNotWritableException;
32+
import org.springframework.http.converter.SmartHttpMessageConverter;
33+
34+
/**
35+
* {@link GenericHttpMessageConverter} implementation that delegates to a
36+
* {@link SmartHttpMessageConverter}.
37+
*
38+
* @param <T> the converted object type
39+
* @author Sebastien Deleuze
40+
* @since 7.0
41+
*/
42+
final class GenericHttpMessageConverterAdapter<T> implements GenericHttpMessageConverter<T> {
43+
44+
private final SmartHttpMessageConverter<T> smartConverter;
45+
46+
GenericHttpMessageConverterAdapter(SmartHttpMessageConverter<T> smartConverter) {
47+
this.smartConverter = smartConverter;
48+
}
49+
50+
@Override
51+
public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {
52+
return this.smartConverter.canRead(ResolvableType.forType(type), mediaType);
53+
}
54+
55+
@Override
56+
public T read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)
57+
throws IOException, HttpMessageNotReadableException {
58+
return this.smartConverter.read(ResolvableType.forType(type), inputMessage, null);
59+
}
60+
61+
@Override
62+
public boolean canWrite(@Nullable Type type, Class<?> clazz, @Nullable MediaType mediaType) {
63+
return this.smartConverter.canWrite(ResolvableType.forType(type), clazz, mediaType);
64+
}
65+
66+
@Override
67+
public void write(T t, @Nullable Type type, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
68+
throws IOException, HttpMessageNotWritableException {
69+
this.smartConverter.write(t, ResolvableType.forType(type), contentType, outputMessage, null);
70+
}
71+
72+
@Override
73+
public boolean canRead(Class<?> clazz, @Nullable MediaType mediaType) {
74+
return this.smartConverter.canRead(ResolvableType.forClass(clazz), mediaType);
75+
}
76+
77+
@Override
78+
public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) {
79+
return this.smartConverter.canWrite(clazz, mediaType);
80+
}
81+
82+
@Override
83+
public List<MediaType> getSupportedMediaTypes() {
84+
return this.smartConverter.getSupportedMediaTypes();
85+
}
86+
87+
@Override
88+
public T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
89+
throws IOException, HttpMessageNotReadableException {
90+
return this.smartConverter.read(clazz, inputMessage);
91+
}
92+
93+
@Override
94+
public void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
95+
throws IOException, HttpMessageNotWritableException {
96+
this.smartConverter.write(t, contentType, outputMessage);
97+
}
98+
99+
}

web/src/main/java/org/springframework/security/web/authentication/HttpMessageConverterAuthenticationSuccessHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
*/
5050
public final class HttpMessageConverterAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
5151

52-
private HttpMessageConverter<Object> converter = new MappingJackson2HttpMessageConverter();
52+
private HttpMessageConverter<Object> converter = HttpMessageConverters.getJsonMessageConverter();
5353

5454
private RequestCache requestCache = new HttpSessionRequestCache();
5555

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2004-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.web.authentication;
18+
19+
import org.springframework.http.converter.GenericHttpMessageConverter;
20+
import org.springframework.http.converter.HttpMessageConverter;
21+
import org.springframework.http.converter.json.GsonHttpMessageConverter;
22+
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
23+
import org.springframework.http.converter.json.JsonbHttpMessageConverter;
24+
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
25+
import org.springframework.util.ClassUtils;
26+
27+
/**
28+
* Utility methods for {@link HttpMessageConverter}'s.
29+
*
30+
* @author Rob Winch
31+
* @since 7.0.4
32+
*/
33+
final class HttpMessageConverters {
34+
35+
private static final boolean jacksonPresent;
36+
37+
private static final boolean jackson2Present;
38+
39+
private static final boolean gsonPresent;
40+
41+
private static final boolean jsonbPresent;
42+
43+
private static final String JSON_MAPPER = "tools.jackson.databind.json.JsonMapper";
44+
45+
private static final String OBJECT_MAPPER = "com.fasterxml.jackson.databind.ObjectMapper";
46+
47+
private static final String JSON_GENERATOR = "com.fasterxml.jackson.core.JsonGenerator";
48+
49+
private static final String GSON = "com.google.gson.Gson";
50+
51+
private static final String JSONB = "jakarta.json.bind.Jsonb";
52+
53+
static {
54+
ClassLoader classLoader = HttpMessageConverters.class.getClassLoader();
55+
jacksonPresent = ClassUtils.isPresent(JSON_MAPPER, classLoader);
56+
jackson2Present = ClassUtils.isPresent(OBJECT_MAPPER, classLoader)
57+
&& ClassUtils.isPresent(JSON_GENERATOR, classLoader);
58+
gsonPresent = ClassUtils.isPresent(GSON, classLoader);
59+
jsonbPresent = ClassUtils.isPresent(JSONB, classLoader);
60+
}
61+
62+
private HttpMessageConverters() {
63+
}
64+
65+
/**
66+
* Gets the {@link GenericHttpMessageConverterAdapter} to use for JSON.
67+
* @return the {@link GenericHttpMessageConverterAdapter} to use.
68+
*/
69+
@SuppressWarnings("removal")
70+
static GenericHttpMessageConverter<Object> getJsonMessageConverter() {
71+
if (jacksonPresent) {
72+
return new GenericHttpMessageConverterAdapter<>(new JacksonJsonHttpMessageConverter());
73+
}
74+
if (jackson2Present) {
75+
return new MappingJackson2HttpMessageConverter();
76+
}
77+
if (gsonPresent) {
78+
return new GsonHttpMessageConverter();
79+
}
80+
if (jsonbPresent) {
81+
return new JsonbHttpMessageConverter();
82+
}
83+
throw new IllegalStateException(
84+
"Cannot find JSON Converter on the classpath. Add one following classes to the classpath "
85+
+ String.join(", ", JSON_MAPPER, OBJECT_MAPPER, JSON_MAPPER, GSON, JSONB));
86+
}
87+
88+
}

0 commit comments

Comments
 (0)