Skip to content

Commit b0a3a6f

Browse files
committed
Merge branch '5.1.x'
2 parents f9ba069 + e373b46 commit b0a3a6f

File tree

7 files changed

+89
-22
lines changed

7 files changed

+89
-22
lines changed

spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -119,21 +119,21 @@ private Mono<?> buildEvent(List<String> lines, ResolvableType valueType, boolean
119119
for (String line : lines) {
120120
if (line.startsWith("data:")) {
121121
data = (data != null ? data : new StringBuilder());
122-
data.append(line.substring(5)).append("\n");
122+
data.append(line.substring(5).trim()).append("\n");
123123
}
124124
if (shouldWrap) {
125125
if (line.startsWith("id:")) {
126-
sseBuilder.id(line.substring(3));
126+
sseBuilder.id(line.substring(3).trim());
127127
}
128128
else if (line.startsWith("event:")) {
129-
sseBuilder.event(line.substring(6));
129+
sseBuilder.event(line.substring(6).trim());
130130
}
131131
else if (line.startsWith("retry:")) {
132-
sseBuilder.retry(Duration.ofMillis(Long.valueOf(line.substring(6))));
132+
sseBuilder.retry(Duration.ofMillis(Long.valueOf(line.substring(6).trim())));
133133
}
134134
else if (line.startsWith(":")) {
135135
comment = (comment != null ? comment : new StringBuilder());
136-
comment.append(line.substring(1)).append("\n");
136+
comment.append(line.substring(1).trim()).append("\n");
137137
}
138138
}
139139
}

spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -113,7 +113,7 @@ private Flux<Object> decodeInternal(Flux<TokenBuffer> tokens, ResolvableType ele
113113
getObjectMapper().readerWithView(jsonView).forType(javaType) :
114114
getObjectMapper().readerFor(javaType));
115115

116-
return tokens.map(tokenBuffer -> {
116+
return tokens.flatMap(tokenBuffer -> {
117117
try {
118118
Object value = reader.readValue(tokenBuffer.asParser(getObjectMapper()));
119119
if (!Hints.isLoggingSuppressed(hints)) {
@@ -122,16 +122,16 @@ private Flux<Object> decodeInternal(Flux<TokenBuffer> tokens, ResolvableType ele
122122
return Hints.getLogPrefix(hints) + "Decoded [" + formatted + "]";
123123
});
124124
}
125-
return value;
125+
return Mono.justOrEmpty(value);
126126
}
127127
catch (InvalidDefinitionException ex) {
128-
throw new CodecException("Type definition error: " + ex.getType(), ex);
128+
return Mono.error(new CodecException("Type definition error: " + ex.getType(), ex));
129129
}
130130
catch (JsonProcessingException ex) {
131-
throw new DecodingException("JSON decoding error: " + ex.getOriginalMessage(), ex);
131+
return Mono.error(new DecodingException("JSON decoding error: " + ex.getOriginalMessage(), ex));
132132
}
133133
catch (IOException ex) {
134-
throw new DecodingException("I/O error while parsing input stream", ex);
134+
return Mono.error(new DecodingException("I/O error while parsing input stream", ex));
135135
}
136136
});
137137
}

spring-web/src/main/java/org/springframework/web/client/RestTemplate.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -77,7 +77,8 @@
7777
* modern alternative to the {@code RestTemplate} with efficient support for
7878
* both sync and async, as well as streaming scenarios. The {@code RestTemplate}
7979
* will be deprecated in a future version and will not have major new features
80-
* added going forward.
80+
* added going forward. See the WebClient section of the Spring Framework reference
81+
* documentation for more details and example code.
8182
*
8283
* @author Arjen Poutsma
8384
* @author Brian Clozel

spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -38,6 +38,7 @@
3838
import org.springframework.core.codec.CodecException;
3939
import org.springframework.core.codec.DecodingException;
4040
import org.springframework.core.io.buffer.DataBuffer;
41+
import org.springframework.http.MediaType;
4142
import org.springframework.http.codec.Pojo;
4243
import org.springframework.util.MimeType;
4344

@@ -174,6 +175,14 @@ public void invalidData() {
174175
.verifyError(DecodingException.class));
175176
}
176177

178+
@Test // #22042
179+
public void decodeWithNullLiteral() {
180+
Flux<Object> result = this.decoder.decode(Flux.concat(stringBuffer("null")),
181+
ResolvableType.forType(Pojo.class), MediaType.APPLICATION_JSON, Collections.emptyMap());
182+
183+
StepVerifier.create(result).expectComplete().verify();
184+
}
185+
177186
@Test
178187
public void noDefaultConstructor() {
179188
Flux<DataBuffer> input =

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -25,6 +25,7 @@
2525

2626
import org.springframework.core.Ordered;
2727
import org.springframework.lang.Nullable;
28+
import org.springframework.util.StringUtils;
2829
import org.springframework.web.servlet.HandlerExceptionResolver;
2930
import org.springframework.web.servlet.ModelAndView;
3031

@@ -99,14 +100,16 @@ public void setMappedHandlerClasses(Class<?>... mappedHandlerClasses) {
99100
/**
100101
* Set the log category for warn logging. The name will be passed to the underlying logger
101102
* implementation through Commons Logging, getting interpreted as a log category according
102-
* to the logger's configuration.
103-
* <p>Default is no warn logging. Specify this setting to activate warn logging into a specific
103+
* to the logger's configuration. If {@code null} is passed, warn logging is turned off.
104+
* <p>By default there is no warn logging although sub-classes like
105+
* {@link org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver}
106+
* can change that default. Specify this setting to activate warn logging into a specific
104107
* category. Alternatively, override the {@link #logException} method for custom logging.
105108
* @see org.apache.commons.logging.LogFactory#getLog(String)
106109
* @see java.util.logging.Logger#getLogger(String)
107110
*/
108111
public void setWarnLogCategory(String loggerName) {
109-
this.warnLogger = LogFactory.getLog(loggerName);
112+
this.warnLogger = !StringUtils.isEmpty(loggerName) ? LogFactory.getLog(loggerName) : null;
110113
}
111114

112115
/**

src/docs/asciidoc/web/webflux-webclient.adoc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,58 @@ WebClient client = webClient.mutate()
541541

542542

543543

544+
[[webflux-client-synchronous]]
545+
== Synchronous Use
546+
547+
`WebClient` can be used in synchronous style by blocking at the end for the result:
548+
549+
[source,java,intent=0]
550+
[subs="verbatim,quotes"]
551+
----
552+
Person person = client.get().uri("/person/{id}", i).retrieve()
553+
.bodyToMono(Person.class)
554+
.block();
555+
556+
List<Person> persons = client.get().uri("/persons").retrieve()
557+
.bodyToFlux(Person.class)
558+
.collectList()
559+
.block();
560+
----
561+
562+
However if multiple calls need to be made, it's more efficient to avoid blocking on each
563+
response individually, and instead wait for the combined result:
564+
565+
[source,java,intent=0]
566+
[subs="verbatim,quotes"]
567+
----
568+
Mono<Person> personMono = client.get().uri("/person/{id}", personId)
569+
.retrieve().bodyToMono(Person.class);
570+
571+
Mono<List<Hobby>> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId)
572+
.retrieve().bodyToFlux(Hobby.class).collectList();
573+
574+
Map<String, Object> data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> {
575+
Map<String, String> map = new LinkedHashMap<>();
576+
map.put("person", personName);
577+
map.put("hobbies", hobbies);
578+
return map;
579+
})
580+
.block();
581+
----
582+
583+
The above is merely one example. There are lots of other patterns and operators for putting
584+
together a reactive pipeline that makes many remote calls, potentially some nested,
585+
inter-dependent, without ever blocking until the end.
586+
587+
[NOTE]
588+
====
589+
You should never have to block in a Spring MVC controller. Simply return the resulting
590+
`Flux` or `Mono` from the controller method.
591+
====
592+
593+
594+
595+
544596
[[webflux-client-testing]]
545597
== Testing
546598

src/docs/asciidoc/web/webmvc-client.adoc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ Spring REST client and exposes a simple, template-method API over underlying HTT
1414
libraries.
1515

1616
NOTE: As of 5.0, the non-blocking, reactive `WebClient` offers a modern alternative to the
17-
`RestTemplate`, with efficient support for both synchronous and asynchronous, as well as streaming
18-
scenarios. The `RestTemplate` will be deprecated in a future version and will not have
19-
major new features added going forward.
17+
`RestTemplate`, with efficient support for both
18+
<<web-reactive.adoc#webflux-client-synchronous,synchronous and asynchronous>>, as well as
19+
streaming scenarios. The `RestTemplate` will be deprecated in a future version and will
20+
not have major new features added going forward.
21+
2022

2123
See <<integration.adoc#rest-client-access,REST Endpoints>> for details.
2224

0 commit comments

Comments
 (0)