Skip to content

Commit f814fb4

Browse files
committed
Merge branch '5.3.x'
2 parents 7a04206 + e50131d commit f814fb4

File tree

8 files changed

+82
-37
lines changed

8 files changed

+82
-37
lines changed

spring-core/src/main/java/org/springframework/util/AntPathMatcher.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -705,8 +705,8 @@ else if (match.startsWith("{") && match.endsWith("}")) {
705705
else {
706706
this.exactMatch = false;
707707
patternBuilder.append(quote(pattern, end, pattern.length()));
708-
this.pattern = (this.caseSensitive ? Pattern.compile(patternBuilder.toString()) :
709-
Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE));
708+
this.pattern = Pattern.compile(patternBuilder.toString(),
709+
Pattern.DOTALL | (this.caseSensitive ? 0 : Pattern.CASE_INSENSITIVE));
710710
}
711711
}
712712

spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -131,6 +131,7 @@ void match() {
131131

132132
assertThat(pathMatcher.match("/{bla}.*", "/testing.html")).isTrue();
133133
assertThat(pathMatcher.match("/{bla}", "//x\ny")).isTrue();
134+
assertThat(pathMatcher.match("/{var:.*}", "/x\ny")).isTrue();
134135
}
135136

136137
@Test

spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ public Jackson2ObjectMapperBuilder featuresToDisable(Object... featuresToDisable
520520
}
521521

522522
/**
523-
* Specify one or more modules to be registered with the {@link ObjectMapper}.
523+
* Specify the modules to be registered with the {@link ObjectMapper}.
524524
* <p>Multiple invocations are not additive, the last one defines the modules to
525525
* register.
526526
* <p>Note: If this is set, no finding of modules is going to happen - not by
@@ -537,15 +537,9 @@ public Jackson2ObjectMapperBuilder modules(Module... modules) {
537537
}
538538

539539
/**
540-
* Set a complete list of modules to be registered with the {@link ObjectMapper}.
541-
* <p>Multiple invocations are not additive, the last one defines the modules to
542-
* register.
543-
* <p>Note: If this is set, no finding of modules is going to happen - not by
544-
* Jackson, and not by Spring either (see {@link #findModulesViaServiceLoader}).
545-
* As a consequence, specifying an empty list here will suppress any kind of
546-
* module detection.
547-
* <p>Specify either this or {@link #modulesToInstall}, not both.
540+
* Variant of {@link #modules(Module...)} with a {@link List}.
548541
* @see #modules(Module...)
542+
* @see #modules(Consumer)
549543
* @see com.fasterxml.jackson.databind.Module
550544
*/
551545
public Jackson2ObjectMapperBuilder modules(List<Module> modules) {
@@ -555,6 +549,22 @@ public Jackson2ObjectMapperBuilder modules(List<Module> modules) {
555549
return this;
556550
}
557551

552+
/**
553+
* Variant of {@link #modules(Module...)} with a {@link Consumer} for full
554+
* control over the underlying list of modules.
555+
* @since 6.0
556+
* @see #modules(Module...)
557+
* @see #modules(List)
558+
* @see com.fasterxml.jackson.databind.Module
559+
*/
560+
public Jackson2ObjectMapperBuilder modules(Consumer<List<Module>> consumer) {
561+
this.modules = (this.modules != null ? this.modules : new ArrayList<>());
562+
this.findModulesViaServiceLoader = false;
563+
this.findWellKnownModules = false;
564+
consumer.accept(this.modules);
565+
return this;
566+
}
567+
558568
/**
559569
* Specify one or more modules to be registered with the {@link ObjectMapper}.
560570
* <p>Multiple invocations are not additive, the last one defines the modules
@@ -565,6 +575,7 @@ public Jackson2ObjectMapperBuilder modules(List<Module> modules) {
565575
* allowing to eventually override their configuration.
566576
* <p>Specify either this or {@link #modules(Module...)}, not both.
567577
* @since 4.1.5
578+
* @see #modulesToInstall(Consumer)
568579
* @see #modulesToInstall(Class...)
569580
* @see com.fasterxml.jackson.databind.Module
570581
*/
@@ -574,6 +585,21 @@ public Jackson2ObjectMapperBuilder modulesToInstall(Module... modules) {
574585
return this;
575586
}
576587

588+
/**
589+
* Variant of {@link #modulesToInstall(Module...)} with a {@link Consumer}
590+
* for full control over the underlying list of modules.
591+
* @since 6.0
592+
* @see #modulesToInstall(Module...)
593+
* @see #modulesToInstall(Class...)
594+
* @see com.fasterxml.jackson.databind.Module
595+
*/
596+
public Jackson2ObjectMapperBuilder modulesToInstall(Consumer<List<Module>> consumer) {
597+
this.modules = (this.modules != null ? this.modules : new ArrayList<>());
598+
this.findWellKnownModules = true;
599+
consumer.accept(this.modules);
600+
return this;
601+
}
602+
577603
/**
578604
* Specify one or more modules by class to be registered with
579605
* the {@link ObjectMapper}.
@@ -585,6 +611,7 @@ public Jackson2ObjectMapperBuilder modulesToInstall(Module... modules) {
585611
* allowing to eventually override their configuration.
586612
* <p>Specify either this or {@link #modules(Module...)}, not both.
587613
* @see #modulesToInstall(Module...)
614+
* @see #modulesToInstall(Consumer)
588615
* @see com.fasterxml.jackson.databind.Module
589616
*/
590617
@SafeVarargs

spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -59,15 +59,9 @@ class CaptureVariablePathElement extends PathElement {
5959
}
6060
else {
6161
this.variableName = new String(captureDescriptor, 1, colon - 1);
62-
if (caseSensitive) {
63-
this.constraintPattern = Pattern.compile(
64-
new String(captureDescriptor, colon + 1, captureDescriptor.length - colon - 2));
65-
}
66-
else {
67-
this.constraintPattern = Pattern.compile(
68-
new String(captureDescriptor, colon + 1, captureDescriptor.length - colon - 2),
69-
Pattern.CASE_INSENSITIVE);
70-
}
62+
this.constraintPattern = Pattern.compile(
63+
new String(captureDescriptor, colon + 1, captureDescriptor.length - colon - 2),
64+
Pattern.DOTALL | (caseSensitive ? 0 : Pattern.CASE_INSENSITIVE));
7165
}
7266
}
7367

spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -108,12 +108,8 @@ else if (match.startsWith("{") && match.endsWith("}")) {
108108
}
109109

110110
patternBuilder.append(quote(text, end, text.length()));
111-
if (this.caseSensitive) {
112-
return Pattern.compile(patternBuilder.toString());
113-
}
114-
else {
115-
return Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE);
116-
}
111+
return Pattern.compile(patternBuilder.toString(),
112+
Pattern.DOTALL | (this.caseSensitive ? 0 : Pattern.CASE_INSENSITIVE));
117113
}
118114

119115
public List<String> getVariableNames() {

spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,16 @@ void modules() {
240240
assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1);
241241
}
242242

243+
@Test
244+
void modulesWithConsumer() {
245+
NumberSerializer serializer1 = new NumberSerializer(Integer.class);
246+
SimpleModule module = new SimpleModule();
247+
module.addSerializer(Integer.class, serializer1);
248+
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(list -> list.add(module) ).build();
249+
Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next();
250+
assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1);
251+
}
252+
243253
@Test
244254
void modulesToInstallByClass() {
245255
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
@@ -258,6 +268,15 @@ void modulesToInstallByInstance() {
258268
assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null).getClass()).isSameAs(CustomIntegerSerializer.class);
259269
}
260270

271+
@Test
272+
void modulesToInstallWithConsumer() {
273+
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
274+
.modulesToInstall(list -> list.add(new CustomIntegerModule()))
275+
.build();
276+
Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next();
277+
assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null).getClass()).isSameAs(CustomIntegerSerializer.class);
278+
}
279+
261280
@Test
262281
void wellKnownModules() throws JsonProcessingException, UnsupportedEncodingException {
263282
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();

spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ public void encodingAndBoundVariablesCapturePathElement() {
301301
checkCapture("{var:f o}","f%20o","var","f o"); // constraint is expressed in non encoded form
302302
checkCapture("{var:f.o}","f%20o","var","f o");
303303
checkCapture("{var:f\\|o}","f%7co","var","f|o");
304+
checkCapture("{var:.*}","x\ny","var","x\ny");
304305
}
305306

306307
@Test
@@ -320,6 +321,8 @@ public void encodingAndBoundVariablesRegexPathElement() {
320321
checkCapture("/{var1}_ _{var2}","/f%20o_%20_f%7co","var1","f o","var2","f|o");
321322
checkCapture("/{var1}_ _{var2:f\\|o}","/f%20o_%20_f%7co","var1","f o","var2","f|o");
322323
checkCapture("/{var1:f o}_ _{var2:f\\|o}","/f%20o_%20_f%7co","var1","f o","var2","f|o");
324+
checkCapture("/{var1:f o}_ _{var2:f\\|o}","/f%20o_%20_f%7co","var1","f o","var2","f|o");
325+
checkCapture("/{var1}_{var2}","/f\noo_foo","var1","f\noo","var2","foo");
323326
}
324327

325328
@Test

src/docs/asciidoc/web/webmvc.adoc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ See <<mvc-config-interceptors>> in the section on MVC configuration for examples
650650
configure interceptors. You can also register them directly by using setters on individual
651651
`HandlerMapping` implementations.
652652

653-
Note that `postHandle` is less useful with `@ResponseBody` and `ResponseEntity` methods for
653+
`postHandle` method is less useful with `@ResponseBody` and `ResponseEntity` methods for
654654
which the response is written and committed within the `HandlerAdapter` and before
655655
`postHandle`. That means it is too late to make any changes to the response, such as adding
656656
an extra header. For such scenarios, you can implement `ResponseBodyAdvice` and either
@@ -659,6 +659,7 @@ declare it as an <<mvc-ann-controller-advice>> bean or configure it directly on
659659

660660

661661

662+
662663
[[mvc-exceptionhandlers]]
663664
=== Exceptions
664665
[.small]#<<web-reactive.adoc#webflux-dispatcher-exceptions, WebFlux>>#
@@ -5397,7 +5398,6 @@ the following example shows:
53975398
public void addInterceptors(InterceptorRegistry registry) {
53985399
registry.addInterceptor(new LocaleChangeInterceptor());
53995400
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
5400-
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
54015401
}
54025402
}
54035403
----
@@ -5411,7 +5411,6 @@ the following example shows:
54115411
override fun addInterceptors(registry: InterceptorRegistry) {
54125412
registry.addInterceptor(LocaleChangeInterceptor())
54135413
registry.addInterceptor(ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**")
5414-
registry.addInterceptor(SecurityInterceptor()).addPathPatterns("/secure/*")
54155414
}
54165415
}
54175416
----
@@ -5427,13 +5426,19 @@ The following example shows how to achieve the same configuration in XML:
54275426
<mvc:exclude-mapping path="/admin/**"/>
54285427
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
54295428
</mvc:interceptor>
5430-
<mvc:interceptor>
5431-
<mvc:mapping path="/secure/*"/>
5432-
<bean class="org.example.SecurityInterceptor"/>
5433-
</mvc:interceptor>
54345429
</mvc:interceptors>
54355430
----
54365431

5432+
NOTE: Mapped interceptors are not ideally suited as a security layer due to the potential
5433+
for a mismatch with annotated controller path matching, which can also match trailing
5434+
slashes and path extensions transparently, along with other path matching options. Many
5435+
of these options have been deprecated but the potential for a mismatch remains.
5436+
Generally, we recommend using Spring Security which includes a dedicated
5437+
https://docs.spring.io/spring-security/reference/servlet/integrations/mvc.html#mvc-requestmatcher[MvcRequestMatcher]
5438+
to align with Spring MVC path matching and also has a security firewall that blocks many
5439+
unwanted characters in URL paths.
5440+
5441+
54375442

54385443

54395444
[[mvc-config-content-negotiation]]

0 commit comments

Comments
 (0)