18.17. 附加支持
POJO 模式: 支持带有 Attachment 和 MTOM 的 SOAP (请参阅启用 MTOM 的 Payload 模式)。但是,没有测试带有 Attachment 的 SOAP。由于附件被分为 marshalled 和 unmarshalled into POJO,因此用户通常不需要处理他们自己的附件。如果没有启用 MTOM,则会将附件传播到 Camel 消息的附加。因此,可以通过 Camel Message API 检索附件
DataHandler Message.getAttachment(String id)
有效负载模式: 组件支持 MTOM。附加可通过上述 Camel Message API 检索。支持具有附加(SwA)的 SOAP,并且可以检索附件。SwA 是默认值(与将 CXF 端点属性 "mtom-enabled" 设置为 false)。
要启用 MTOM,请将 CXF 端点属性 "mtom-enabled" 设置为 true。
@Bean public CxfEndpoint routerEndpoint() { CxfSpringEndpoint cxfEndpoint = new CxfSpringEndpoint(); cxfEndpoint.setServiceNameAsQName(SERVICE_QNAME); cxfEndpoint.setEndpointNameAsQName(PORT_QNAME); cxfEndpoint.setAddress("/" + getClass().getSimpleName()+ "/jaxws-mtom/hello"); cxfEndpoint.setWsdlURL("mtom.wsdl"); Map<String, Object> properties = new HashMap<String, Object>(); properties.put("dataFormat", "PAYLOAD"); properties.put("mtom-enabled", true); cxfEndpoint.setProperties(properties); return cxfEndpoint; }
您可以生成带有 attachment 的 Camel 消息,以便在 Payload 模式中发送到 CXF 端点。
Exchange exchange = context.createProducerTemplate().send("direct:testEndpoint", new Processor() { public void process(Exchange exchange) throws Exception { exchange.setPattern(ExchangePattern.InOut); List<Source> elements = new ArrayList<Source>(); elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement())); CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(), elements, null); exchange.getIn().setBody(body); exchange.getIn().addAttachment(MtomTestHelper.REQ_PHOTO_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.REQ_PHOTO_DATA, "application/octet-stream"))); exchange.getIn().addAttachment(MtomTestHelper.REQ_IMAGE_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.requestJpeg, "image/jpeg"))); } }); // process response CxfPayload<SoapHeader> out = exchange.getOut().getBody(CxfPayload.class); Assert.assertEquals(1, out.getBody().size()); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS); ns.put("xop", MtomTestHelper.XOP_NS); XPathUtils xu = new XPathUtils(ns); Element oute = new XmlConverter().toDOMElement(out.getBody().get(0)); Element ele = (Element)xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", oute, XPathConstants.NODE); String photoId = ele.getAttribute("href").substring(4); // skip "cid:" ele = (Element)xu.getValue("//ns:DetailResponse/ns:image/xop:Include", oute, XPathConstants.NODE); String imageId = ele.getAttribute("href").substring(4); // skip "cid:" DataHandler dr = exchange.getOut().getAttachment(photoId); Assert.assertEquals("application/octet-stream", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.RESP_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream())); dr = exchange.getOut().getAttachment(imageId); Assert.assertEquals("image/jpeg", dr.getContentType()); BufferedImage image = ImageIO.read(dr.getInputStream()); Assert.assertEquals(560, image.getWidth()); Assert.assertEquals(300, image.getHeight());
您还可以以 Payload 模式使用从 CXF 端点接收的 Camel 消息。CxfMtomConsumerPayloadModeTest 演示了如何工作:
public static class MyProcessor implements Processor { @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { CxfPayload<SoapHeader> in = exchange.getIn().getBody(CxfPayload.class); // verify request Assert.assertEquals(1, in.getBody().size()); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS); ns.put("xop", MtomTestHelper.XOP_NS); XPathUtils xu = new XPathUtils(ns); Element body = new XmlConverter().toDOMElement(in.getBody().get(0)); Element ele = (Element)xu.getValue("//ns:Detail/ns:photo/xop:Include", body, XPathConstants.NODE); String photoId = ele.getAttribute("href").substring(4); // skip "cid:" Assert.assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId); ele = (Element)xu.getValue("//ns:Detail/ns:image/xop:Include", body, XPathConstants.NODE); String imageId = ele.getAttribute("href").substring(4); // skip "cid:" Assert.assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId); DataHandler dr = exchange.getIn().getAttachment(photoId); Assert.assertEquals("application/octet-stream", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.REQ_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream())); dr = exchange.getIn().getAttachment(imageId); Assert.assertEquals("image/jpeg", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.requestJpeg, IOUtils.readBytesFromStream(dr.getInputStream())); // create response List<Source> elements = new ArrayList<Source>(); elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement())); CxfPayload<SoapHeader> sbody = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(), elements, null); exchange.getOut().setBody(sbody); exchange.getOut().addAttachment(MtomTestHelper.RESP_PHOTO_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.RESP_PHOTO_DATA, "application/octet-stream"))); exchange.getOut().addAttachment(MtomTestHelper.RESP_IMAGE_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.responseJpeg, "image/jpeg"))); } }
原始模式: 不支持过期,因为它根本不处理消息。
CXF_RAW Mode :支持 MTOM,并且前面提到的 Camel Message API 可以检索过期。请注意,当收到多部分(即 MTOM)消息时,默认的 SOAPMessage 到 String converter 将提供正文的完整多部分有效负载。如果您只需要 SOAP XML 作为字符串,您可以使用 message.getSOAPPart ()设置消息正文,Camel convert 可以为您执行其余工作。