Spring boot version 2.4.4
Java version 15
@Bean
public WebClient webClient() {
return WebClient.builder().baseUrl(BASE_URL)
.defaultHeaders(header -> header.setBasicAuth("test",
"testpwd"))
.clientConnector(new ReactorClientHttpConnector(HttpClient.newConnection()))
.exchangeStrategies(ExchangeStrategies.builder().codecs(configurer -> {
configurer.defaultCodecs().jaxb2Encoder(new Jaxb2XmlEncoder());
configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder());
}).build()).build();
}
Using Spring boot 2.4.4 webclient and trying to consume the service with XML reponse.
public Mono<ServerResponse> retrieveServices() {
// Headers can be passed here or while building the client
Mono<DirectoryOfService> serviceMono = webClient
.get().uri("/api/v1/test/services")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
.retrieve().bodyToMono(DirectoryOfService.class);
}
Error:-
org.springframework.core.codec.CodecException: Could not create JAXBContext for class [class com.test.model.DirectoryOfService]: Implementation of JAXB-API has not been found on module path or classpath.; nested exception is javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory]
at org.springframework.http.codec.xml.JaxbContextContainer.lambda$getJaxbContext$0(JaxbContextContainer.java:58) ~[spring-web-5.3.5.jar:5.3.5]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ Body from GET https://test.com/api/v1/services [DefaultClientResponse]
|_ checkpoint ⇢ HTTP GET "/api/v1/services" [ExceptionHandlingWebHandler]
Stack trace:
at org.springframework.http.codec.xml.JaxbContextContainer.lambda$getJaxbContext$0(JaxbContextContainer.java:58) ~[spring-web-5.3.5.jar:5.3.5]
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
at org.springframework.http.codec.xml.JaxbContextContainer.getJaxbContext(JaxbContextContainer.java:52) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.JaxbContextContainer.createUnmarshaller(JaxbContextContainer.java:47) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.initUnmarshaller(Jaxb2XmlDecoder.java:235) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.unmarshal(Jaxb2XmlDecoder.java:216) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.decode(Jaxb2XmlDecoder.java:195) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.lambda$decodeToMono$2(Jaxb2XmlDecoder.java:183) ~[spring-web-5.3.5.jar:5.3.5]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:113) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:295) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:159) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:259) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:401) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:416) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:470) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:685) ~[reactor-netty-http-1.0.5.jar:1.0.5]
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1534) ~[netty-handler-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1283) ~[netty-handler-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1330) ~[netty-handler-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.60.Final.jar:4.1.60.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.60.Final.jar:4.1.60.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.60.Final.jar:4.1.60.Final]
at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278) ~[jaxb-api-2.3.1.jar:2.3.0]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[jaxb-api-2.3.1.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.1.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.1.jar:2.3.0]
at org.springframework.http.codec.xml.JaxbContextContainer.lambda$getJaxbContext$0(JaxbContextContainer.java:54) ~[spring-web-5.3.5.jar:5.3.5]
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
at org.springframework.http.codec.xml.JaxbContextContainer.getJaxbContext(JaxbContextContainer.java:52) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.JaxbContextContainer.createUnmarshaller(JaxbContextContainer.java:47) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.initUnmarshaller(Jaxb2XmlDecoder.java:235) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.unmarshal(Jaxb2XmlDecoder.java:216) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.decode(Jaxb2XmlDecoder.java:195) ~[spring-web-5.3.5.jar:5.3.5]
at org.springframework.http.codec.xml.Jaxb2XmlDecoder.lambda$decodeToMono$2(Jaxb2XmlDecoder.java:183) ~[spring-web-5.3.5.jar:5.3.5]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:113) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:295) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:159) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:259) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.4.jar:3.4.4]
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:401) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:416) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:470) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:685) ~[reactor-netty-http-1.0.5.jar:1.0.5]
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94) ~[reactor-netty-core-1.0.5.jar:1.0.5]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) ~[netty-codec-4.1.60.Final.jar:4.1.60.Final]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.60.Final.jar:4.1.60.Final]
build.gradle,
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '3.0.0'
implementation group: 'com.sun.xml.bind', name: 'jaxb-core', version: '3.0.0'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
}
After removing com.sun.xml.bind and adding glassfish, getting the error below.
implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.1'
Error :
org.springframework.core.codec.CodecException: Could not create JAXBContext for class [class com.test.model.DirectoryOfService]: 10 counts of IllegalAnnotationExceptions; nested exception is com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 10 counts of IllegalAnnotationExceptions
Class has two properties of the same name "section"
this problem is related to the following location:
at public com.test.model.Section com.test.model.DirectoryOfService.getSection()
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "name"
this problem is related to the following location:
at public java.lang.String com.test.model.Section.getName()
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.lang.String com.test.model.Section.name
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "test"
this problem is related to the following location:
at public java.util.List com.test.model.Section.getTest()
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "code"
this problem is related to the following location:
at public java.lang.String com.test.model.Test.getCode()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.lang.String com.test.model.Test.code
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "currency"
this problem is related to the following location:
at public java.lang.String com.test.model.Test.getCurrency()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.lang.String com.test.model.Test.currency
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "includes"
this problem is related to the following location:
at public java.lang.String com.test.model.Test.getIncludes()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.lang.String com.test.model.Test.includes
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "name"
this problem is related to the following location:
at public java.lang.String com.test.model.Test.getName()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.lang.String com.test.model.Test.name
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "nonDiscountable"
this problem is related to the following location:
at public boolean com.test.model.Test.isNonDiscountable()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private boolean com.test.model.Test.nonDiscountable
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "replicate"
this problem is related to the following location:
at public int com.test.model.Test.getReplicate()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private int com.test.model.Test.replicate
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Class has two properties of the same name "validFrom"
this problem is related to the following location:
at public java.util.Date com.test.model.Test.getValidFrom()
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
this problem is related to the following location:
at private java.util.Date com.test.model.Test.validFrom
at com.test.model.Test
at private java.util.List com.test.model.Section.test
at com.test.model.Section
at private com.test.model.Section com.test.model.DirectoryOfService.section
at com.test.model.DirectoryOfService
Sample response file,
<?xml version='1.0' encoding='UTF-8'?>
<DirectoryOfService>
<Section Name="Directory">
<Test>
<Name>Mike</Name>
<Code>USA</Code>
<Replicate>0</Replicate>
<ValidFrom>2016-06-30</ValidFrom>
<Includes>Test Includes</Includes>
<Currency>None</Currency>
<NonDiscountable>false</NonDiscountable>
</Test>
<Test>
<Name>Bingo</Name>
<Code>USA</Code>
<Replicate>0</Replicate>
<ValidFrom>2016-06-30</ValidFrom>
<Includes>Test Includes</Includes>
<Currency>None</Currency>
<NonDiscountable>false</NonDiscountable>
</Test>
</Section>
</DirectoryOfService>
Model classes,
DirectoryOfService class,
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="DirectoryOfService")
public class DirectoryOfService {
@XmlElementRef(name = "Section")
private Section section;
public Section getSection() {
return section;
}
public void setSection(Section section) {
this.section = section;
}
}
Section calss,
@XmlRootElement(name="Section")
public class Section {
@XmlElementRef(name = "Test")
private List<Test> test;
@XmlAttribute(name = "Name")
private String name;
//public String text;
public List<Test> getTest() {
return test;
}
public void setTest(List<Test> test) {
this.test = test;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Test class,
@XmlRootElement(name = "Test")
public class Test {
@XmlElement(name = "Name")
private String name;
@XmlElement(name = "Code")
private String code;
@XmlElement(name = "Replicate")
private int replicate;
@XmlElement(name = "ValidFrom")
private Date validFrom;
@XmlElement(name = "Includes")
private String includes;
@XmlElement(name = "Currency")
private String currency;
@XmlElement(name = "NonDiscountable")
private boolean nonDiscountable;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public int getReplicate() {
return replicate;
}
public void setReplicate(int replicate) {
this.replicate = replicate;
}
public Date getValidFrom() {
return validFrom;
}
public void setValidFrom(Date validFrom) {
this.validFrom = validFrom;
}
public String getIncludes() {
return includes;
}
public void setIncludes(String includes) {
this.includes = includes;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public boolean isNonDiscountable() {
return nonDiscountable;
}
public void setNonDiscountable(boolean nonDiscountable) {
this.nonDiscountable = nonDiscountable;
}
}
Although you tested similar approaches, please, consider review this Github issue, especially the last comment, I think it can be helpful.
Be sure to have an appropriate version of the JAXB runtime as well. In your previous issues it looks like Spring was unable to find a suitable JAXB implementation in your classpath. For the version of the jaxb-api
that you indicated in your dependencies, 2.3.1
, please, remove the dependencies related with com.sun.xml.bind
and include the following one:
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.1'
The recent org.glassfish.jaxb
jaxb-runtime
versions, say 3.0.0
, depends on org.glassfish.jaxb
jaxb-core
which in turn depends on jakarta.xml.bind
jakarta.xml.bind-api
, the Eclipse Foundation based JAXB implementation for Java EE. If you want to use org.glassfish.jaxb:jaxb-runtime:3.0.0
include the following dependency:
implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.0'
instead of the previous JAXB API one you defined:
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
Please, change your imports in consequence and test it carefully, I never tested it with Spring WebClient
and the related JAXB codecs.
Regarding the problem with the section
repetition, it seems that JAXB is trying to serialize both field and methods defined properties of your POJOs. To avoid the problem, explicitly define the access type using the @XmlAccessorType
annotation. For example:
@XmlRootElement(name="DirectoryOfService")
@XmlAccessorType(XmlAccessType.FIELD)
public class DirectoryOfService {
@XmlElementRef(name = "Section")
private Section section;
public Section getSection() {
return section;
}
public void setSection(Section section) {
this.section = section;
}
}
@XmlRootElement(name="Section")
@XmlAccessorType(XmlAccessType.FIELD)
public class Section {
@XmlElementRef(name = "Test")
private List<Test> test;
@XmlAttribute(name = "Name")
private String name;
//public String text;
public List<Test> getTest() {
return test;
}
public void setTest(List<Test> test) {
this.test = test;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@XmlRootElement(name = "Test")
@XmlAccessorType(XmlAccessType.FIELD)
public class Test {
@XmlElement(name = "Name")
private String name;
@XmlElement(name = "Code")
private String code;
@XmlElement(name = "Replicate")
private int replicate;
@XmlElement(name = "ValidFrom")
private Date validFrom;
@XmlElement(name = "Includes")
private String includes;
@XmlElement(name = "Currency")
private String currency;
@XmlElement(name = "NonDiscountable")
private boolean nonDiscountable;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public int getReplicate() {
return replicate;
}
public void setReplicate(int replicate) {
this.replicate = replicate;
}
public Date getValidFrom() {
return validFrom;
}
public void setValidFrom(Date validFrom) {
this.validFrom = validFrom;
}
public String getIncludes() {
return includes;
}
public void setIncludes(String includes) {
this.includes = includes;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public boolean isNonDiscountable() {
return nonDiscountable;
}
public void setNonDiscountable(boolean nonDiscountable) {
this.nonDiscountable = nonDiscountable;
}
}