I have an apache CXF client for a Microsoft WCF service, and I am attempting to send a file via MTOM. However, I keep getting a 400, and the error on the WCF side according to the partner is that there is an error creating the MTOM reader
I've traced the outbound message, and it looks like this:
INFO: Outbound Message --------------------------- ID: 1 Address: https://someserver.com/ImportService.svc?wsdl Encoding: UTF-8 Http-Method: POST Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f"; start="<root.message@cxf.apache.org>"; start-info="application/soap+xml; action=\"http://tempuri.org/IImportService/UploadFile\"" Headers: {Accept=[*/*], Accept-Encoding=[gzip;q=1.0, identity; q=0.5, *;q=0], Content-Encoding=[gzip]} Payload: --uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f Content-Type: application/xop+xml; charset=UTF-8; type="application/soap+xml; action=\"http://tempuri.org/IImportService/UploadFile\"" Content-Transfer-Encoding: binary Content-ID: <root.message@cxf.apache.org> <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="true"> <wsse:UsernameToken wsu:Id="UsernameToken-e51a6fdd-5053-4aae-a9fb-363dde7d9e77"> <wsse:Username>blah@test.com</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypassword</wsse:Password> </wsse:UsernameToken> </wsse:Security> <ns2:letterOptions xmlns="http://schemas.datacontract.org/2004/07/PublicServices.Import" xmlns:ns2="http://tempuri.org/"> <EnableQBPlanConsolidation>false</EnableQBPlanConsolidation> <MASKSSN>true</MASKSSN> <SRPrintedNumberofDays>2</SRPrintedNumberofDays> <SuppressAllLetters>false</SuppressAllLetters> <SuppressNewMemberLoginLetter>false</SuppressNewMemberLoginLetter> <SuppressTakeOverLetterForTermed>false</SuppressTakeOverLetterForTermed> <SuppressTerminationLetter>false</SuppressTerminationLetter> </ns2:letterOptions> <ns2:JobQueueType xmlns="http://schemas.datacontract.org/2004/07/PublicServices.Import" xmlns:ns2="http://tempuri.org/">Import</ns2:JobQueueType> <Filename xmlns="http://tempuri.org/">testImport.csv</Filename> <Action xmlns="http://www.w3.org/2005/08/addressing">http://tempuri.org/IImportService/UploadFile</Action> <MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:f380e4cc-225f-4b7d-bd46-6b5d607a59ca</MessageID> <To xmlns="http://www.w3.org/2005/08/addressing">https://someserver.com/ImportService.svc?wsdl</To> <ReplyTo xmlns="http://www.w3.org/2005/08/addressing"> <Address>http://www.w3.org/2005/08/addressing/anonymous</Address> </ReplyTo> </soap:Header> <soap:Body> <FileUploadMessage xmlns="http://tempuri.org/" xmlns:ns2="http://schemas.datacontract.org/2004/07/PublicServices.Import" xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/"> <FileByteStream> <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:68e0408d-81da-496b-a06c-24a0459207d1-1@tempuri.org"/> </FileByteStream> </FileUploadMessage> </soap:Body> </soap:Envelope> --uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f Content-Type: application/octet-stream Content-Transfer-Encoding: binary Content-ID: <68e0408d-81da-496b-a06c-24a0459207d1-1@tempuri.org> [VERSION],1.0 [NPM],552652222,1,Basic Client,Basic Client,Bob,Z,Jones,MR,bjones@test.com,402444555,,1234 Some street,,Omaha,NE,68123,,M,T,F,F --uuid:1d46d7c9-047b-440d-928b-ab8689ab5e6f--
I've found plenty of other instances where other folks had the same issue: https://coderanch.com/t/224995/java/Apache-CXF-MTOM-enabled-WCF
HTTP Bad Request error when requesting a WCF service contract
None of these were able to resolve my issue. I've tried multiple different versions of CXF and I get the same error with all of them.
This is a consolidated version of the code that is calling the service:
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean(); proxyFactory.setBindingId(SOAPBinding.SOAP12HTTP_MTOM_BINDING); proxyFactory.setServiceClass(IImportService.class); proxyFactory.setAddress(proxyEndpoint); proxyFactory.getFeatures().add(new WSAddressingFeature()); IImportService importService = (IImportService) proxyFactory.create(); Client client = (Client) importService; LetterOptions letterOptions = new LetterOptions(); letterOptions.setSRPrintedNumberofDays(2); letterOptions.setMASKSSN(true); letterOptions.setEnableQBPlanConsolidation(false); List<Object> headerList = new ArrayList<>(); headerList.add(new Header(new QName("http://tempuri.org/", "letterOptions"), letterOptions, new JAXBDataBinding(LetterOptions.class))); headerList.add(new Header(new QName("http://tempuri.org/", "JobQueueType"), JobQueueType.IMPORT, new JAXBDataBinding(JobQueueType.class))); headerList.add(new Header(new QName("http://tempuri.org/", "Filename"), "testImport.csv", new JAXBDataBinding(String.class))); client.getRequestContext().put(Header.HEADER_LIST, headerList); client.getEndpoint().getActiveFeatures().add(new LoggingFeature()); client.getInInterceptors().add(new GZIPInInterceptor()); client.getInInterceptors().add(new LogResponseInterceptor()); GZIPOutInterceptor outInterceptor = new GZIPOutInterceptor(); outInterceptor.setForce(true); client.getOutInterceptors().add(outInterceptor); Map props = new HashMap(); props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); props.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class.getName()); props.put(WSHandlerConstants.USER, "blah@test.com"); WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props); client.getOutInterceptors().add(wssOut); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = conduit.getClient(); if(policy == null) { policy = new HTTPClientPolicy(); } policy.setAllowChunking(false); FileUploadMessageReponse response = importService.uploadFile(fileUploadMessage);
One interesting tidbit is that I can copy the same request that is being logged into SoapUI, and it works fine.
0 comments:
Post a Comment