Browse Source

Unwrap XMLStreamException from cause

Closes: gh-24622
pull/24766/head
Rossen Stoyanchev 5 years ago
parent
commit
e11373fe69
  1. 6
      spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java
  2. 61
      spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java

6
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -197,6 +197,10 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> { @@ -197,6 +197,10 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
catch (XMLStreamException ex) {
throw Exceptions.propagate(ex);
}
catch (Throwable ex) {
ex = (ex.getCause() instanceof XMLStreamException ? ex.getCause() : ex);
throw Exceptions.propagate(ex);
}
finally {
DataBufferUtils.release(dataBuffer);
}

61
spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,11 +19,14 @@ package org.springframework.http.codec.xml; @@ -19,11 +19,14 @@ package org.springframework.http.codec.xml;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import org.junit.jupiter.api.Test;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@ -66,6 +69,8 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -66,6 +69,8 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
"</pojo>" +
"<root/>";
private static final Map<String, Object> HINTS = Collections.emptyMap();
private final Jaxb2XmlDecoder decoder = new Jaxb2XmlDecoder();
@ -88,8 +93,7 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -88,8 +93,7 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
@Test
public void splitOneBranches() {
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder
.decode(stringBuffer(POJO_ROOT), null, null, Collections.emptyMap());
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder.decode(toDataBufferMono(POJO_ROOT), null, null, HINTS);
Flux<List<XMLEvent>> result = this.decoder.split(xmlEvents, new QName("pojo"));
StepVerifier.create(result)
@ -109,9 +113,8 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -109,9 +113,8 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
@Test
public void splitMultipleBranches() throws Exception {
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder
.decode(stringBuffer(POJO_CHILD), null, null, Collections.emptyMap());
public void splitMultipleBranches() {
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder.decode(toDataBufferMono(POJO_CHILD), null, null, HINTS);
Flux<List<XMLEvent>> result = this.decoder.split(xmlEvents, new QName("pojo"));
@ -158,10 +161,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -158,10 +161,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
@Test
public void decodeSingleXmlRootElement() throws Exception {
Mono<DataBuffer> source = stringBuffer(POJO_ROOT);
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class),
null, Collections.emptyMap());
public void decodeSingleXmlRootElement() {
Mono<DataBuffer> source = toDataBufferMono(POJO_ROOT);
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class), null, HINTS);
StepVerifier.create(output)
.expectNext(new Pojo("foofoo", "barbar"))
@ -170,10 +172,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -170,10 +172,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
@Test
public void decodeSingleXmlTypeElement() throws Exception {
Mono<DataBuffer> source = stringBuffer(POJO_ROOT);
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(TypePojo.class),
null, Collections.emptyMap());
public void decodeSingleXmlTypeElement() {
Mono<DataBuffer> source = toDataBufferMono(POJO_ROOT);
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(TypePojo.class), null, HINTS);
StepVerifier.create(output)
.expectNext(new TypePojo("foofoo", "barbar"))
@ -182,10 +183,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -182,10 +183,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
@Test
public void decodeMultipleXmlRootElement() throws Exception {
Mono<DataBuffer> source = stringBuffer(POJO_CHILD);
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(Pojo.class),
null, Collections.emptyMap());
public void decodeMultipleXmlRootElement() {
Mono<DataBuffer> source = toDataBufferMono(POJO_CHILD);
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(Pojo.class), null, HINTS);
StepVerifier.create(output)
.expectNext(new Pojo("foo", "bar"))
@ -195,10 +195,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -195,10 +195,9 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
@Test
public void decodeMultipleXmlTypeElement() throws Exception {
Mono<DataBuffer> source = stringBuffer(POJO_CHILD);
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(TypePojo.class),
null, Collections.emptyMap());
public void decodeMultipleXmlTypeElement() {
Mono<DataBuffer> source = toDataBufferMono(POJO_CHILD);
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(TypePojo.class), null, HINTS);
StepVerifier.create(output)
.expectNext(new TypePojo("foo", "bar"))
@ -208,19 +207,27 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -208,19 +207,27 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
@Test
public void decodeError() throws Exception {
public void decodeError() {
Flux<DataBuffer> source = Flux.concat(
stringBuffer("<pojo>"),
toDataBufferMono("<pojo>"),
Flux.error(new RuntimeException()));
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class),
null, Collections.emptyMap());
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class), null, HINTS);
StepVerifier.create(output)
.expectError(RuntimeException.class)
.verify();
}
@Test // gh-24622
public void decodeErrorWithXmlNotWellFormed() {
Mono<DataBuffer> source = toDataBufferMono("<Response><tag>something</tag</Response>");
Mono<Object> result = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class), null, HINTS);
StepVerifier.create(result).verifyErrorSatisfies(ex ->
assertThat(Exceptions.unwrap(ex)).isInstanceOf(XMLStreamException.class));
}
@Test
public void toExpectedQName() {
assertThat(this.decoder.toQName(Pojo.class)).isEqualTo(new QName("pojo"));
@ -236,7 +243,7 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests { @@ -236,7 +243,7 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
}
private Mono<DataBuffer> stringBuffer(String value) {
private Mono<DataBuffer> toDataBufferMono(String value) {
return Mono.defer(() -> {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);

Loading…
Cancel
Save