[ https://issues.apache.org/jira/browse/CXF-7669?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Daniel Kulp reopened CXF-7669: ------------------------------ Assignee: Daniel Kulp (was: Freeman Fang) I'm able to reproduce this with some of my tests. This is due to the changes from CXF-7520 and actually one of the tests in that commit shows the issue. The javascript test that was changed in that commit should NOT have been changed as the output shows the double escape. In CXF, we have 3 main ways we write XML out: direct to OutputStream, to Node, and to XMLStreamWriter. The escape handler should only be set for the first case. In the other two, it should not be escaping anything as the Node should have the unescaped value or the XMLStreamWriter will escape things. Anyway, I'm testing some fixes now. > Cxf encodes escape caracters twice in JDK9.0.5 and JDK8_161 > ----------------------------------------------------------- > > Key: CXF-7669 > URL: https://issues.apache.org/jira/browse/CXF-7669 > Project: CXF > Issue Type: Bug > Affects Versions: 3.2.2 > Reporter: Mark Czubin > Assignee: Daniel Kulp > Priority: Critical > Fix For: NeedMoreInfo > > Attachments: ExampleService.wsdl > > > When our response text contains escape characters then those will be encoded > twice. > For example when I return "hello > world". Cxf will encode this as "hello &> > world" > {code:java} > hello &> world{code} > > Below a test with all the interceptors used in our setup on production: > {code:java} > package be.vlaanderen.omgeving.rest.controller.parameter.v1; > import org.apache.cxf.Bus; > import org.apache.cxf.BusFactory; > import org.apache.cxf.binding.Binding; > import org.apache.cxf.binding.BindingFactory; > import org.apache.cxf.binding.BindingFactoryManager; > import org.apache.cxf.binding.soap.SoapMessage; > import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; > import org.apache.cxf.endpoint.Endpoint; > import org.apache.cxf.endpoint.EndpointException; > import org.apache.cxf.endpoint.EndpointImpl; > import org.apache.cxf.jaxb.JAXBDataBinding; > import org.apache.cxf.message.Exchange; > import org.apache.cxf.message.ExchangeImpl; > import org.apache.cxf.message.MessageImpl; > import org.apache.cxf.phase.PhaseInterceptorChain; > import org.apache.cxf.service.Service; > import org.apache.cxf.service.model.BindingOperationInfo; > import org.apache.cxf.service.model.EndpointInfo; > import org.apache.cxf.staxutils.StaxUtils; > import org.apache.cxf.wsdl.interceptors.BareOutInterceptor; > import org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor; > import org.apache.cxf.wsdl11.WSDLServiceFactory; > import org.junit.Test; > import javax.xml.bind.JAXBContext; > import javax.xml.bind.JAXBException; > import javax.xml.namespace.QName; > import javax.xml.stream.XMLInputFactory; > import javax.xml.stream.XMLOutputFactory; > import javax.xml.stream.XMLStreamException; > import javax.xml.stream.XMLStreamReader; > import javax.xml.stream.XMLStreamWriter; > import java.io.ByteArrayInputStream; > import java.io.ByteArrayOutputStream; > import java.util.List; > import java.util.TreeSet; > import static java.util.Collections.emptyList; > import static > org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.OUT_BUFFERING; > import static org.assertj.core.api.Assertions.assertThat; > import static org.mockito.BDDMockito.given; > import static org.mockito.Mockito.mock; > public class CxfIsUnstable { > CxfFacade cxf = new CxfFacade(); > @Test > public void > givenAResponseWithAmpersans_whenMarshallingToXml_theAmpersandAreEncoded_onlyOnce() > throws Exception { > cxf.setupExampleService(); > String request = cxf.demarshallRequest("<request>hello & > world</request>"); > assertThat(request).isEqualTo("hello & world"); > String responseXml = cxf.marshallResponse("hello & world"); > assertThat(responseXml).isEqualTo("<response>hello & > world<</response>"); > } > static class CxfFacade { > private final SAAJOutInterceptor saajOutInterceptor = new > SAAJOutInterceptor(); > private final BareOutInterceptor outInterceptor = new > BareOutInterceptor(); > private final DocLiteralInInterceptor inInterceptor = new > DocLiteralInInterceptor(); > private SoapMessage message; > private List<Object> messageContents; > public String demarshallRequest(String input) throws > XMLStreamException { > message.setContent(XMLStreamReader.class, > XMLInputFactory.newInstance().createXMLStreamReader(new > ByteArrayInputStream(input.getBytes()))); > > StaxUtils.skipToStartOfElement(message.getContent(XMLStreamReader.class)); > inInterceptor.handleMessage(message); > assertThat(message.getContent(Exception.class)).isNull(); > messageContents = message.getContent(List.class); > String requestContent = (String) messageContents.get(0); > saajOutInterceptor.handleMessage(message); > return requestContent; > } > public String marshallResponse(String responseBody) throws Exception { > messageContents.set(0, responseBody); > ByteArrayOutputStream boas = new ByteArrayOutputStream(); > XMLOutputFactory xmlOutputFactory = > XMLOutputFactory.newInstance(); > XMLStreamWriter output = > xmlOutputFactory.createXMLStreamWriter(boas); > message.setContent(XMLStreamWriter.class, output); > message.put(OUT_BUFFERING, "true"); > outInterceptor.handleMessage(message); > output.flush(); > boas.flush(); > return boas.toString(); > } > public void setupExampleService() throws JAXBException, > EndpointException { > Bus bus = BusFactory.newInstance().createBus(); > BindingFactoryManager bfm = > bus.getExtension(BindingFactoryManager.class); > BindingFactory bf = mock(BindingFactory.class); > Binding binding = mock(Binding.class); > given(bf.createBinding(null)).willReturn(binding); > given(binding.getInFaultInterceptors()).willReturn(emptyList()); > given(binding.getOutFaultInterceptors()).willReturn(emptyList()); > > bfm.registerBindingFactory("http://schemas.xmlsoap.org/wsdl/soap/", bf); > String ns = "http://webservice.example-V1.vlaanderen.be"; > WSDLServiceFactory factory = new WSDLServiceFactory(bus, > "classpath:/files/ExampleService.wsdl"); > Service service = factory.create(); > service.setDataBinding(new > JAXBDataBinding(JAXBContext.newInstance())); > EndpointInfo endpointInfo = service.getEndpointInfo(new QName(ns, > "exampleServicePort")); > EndpointImpl endpoint = new EndpointImpl(bus, service, > endpointInfo); > BindingOperationInfo operation = > endpointInfo.getBinding().getOperation(new QName(ns, "example")); > > operation.getOperationInfo().getInput().getMessagePartByIndex(0).setTypeClass(String.class); > message = new SoapMessage(new MessageImpl()); > Exchange exchange = new ExchangeImpl(); > message.setExchange(exchange); > message.setInterceptorChain(new PhaseInterceptorChain(new > TreeSet<>())); > exchange.put(Service.class, service); > exchange.put(Endpoint.class, endpoint); > exchange.put(Binding.class, endpoint.getBinding()); > } > } > } > {code} -- This message was sent by Atlassian JIRA (v7.6.3#76005)