messageimpl.java
来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 627 行 · 第 1/2 页
JAVA
627 行
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.axis2.jaxws.message.impl;
import org.apache.axiom.attachments.Attachments;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.Constants.Configuration;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.message.Block;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.XMLFault;
import org.apache.axis2.jaxws.message.XMLPart;
import org.apache.axis2.jaxws.message.attachments.AttachmentUtils;
import org.apache.axis2.jaxws.message.factory.BlockFactory;
import org.apache.axis2.jaxws.message.factory.SAAJConverterFactory;
import org.apache.axis2.jaxws.message.factory.SOAPEnvelopeBlockFactory;
import org.apache.axis2.jaxws.message.factory.XMLPartFactory;
import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
import org.apache.axis2.jaxws.message.util.MessageUtils;
import org.apache.axis2.jaxws.message.util.SAAJConverter;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.activation.DataHandler;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.ws.WebServiceException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* MessageImpl
* A Message is an XML part + Attachments.
* Most of the implementation delegates to the XMLPart implementation.
*
* NOTE: For XML/HTTP (REST), a SOAP 1.1. Envelope is built and the rest payload is placed
* in the body. This purposely mimics the Axis2 implementation.
*/
public class MessageImpl implements Message {
private static final Log log = LogFactory.getLog(MessageImpl.class);
Protocol protocol = Protocol.unknown; // the protocol, defaults to unknown
XMLPart xmlPart = null; // the representation of the xmlpart
boolean mtomEnabled;
// The transport headers are stored in a Map, which is the
// same data representation used by the Axis2 MessageContext (TRANSPORT_HEADERS).
private Map transportHeaders = null;
// The Message is connected to a MessageContext.
// Prior to that connection, attachments are stored locally
// After the connection, attachments are obtained from the MessageContext
Attachments attachments = new Attachments(); // Local Attachments
private MessageContext messageContext;
// Set after we have past the pivot point when the message is consumed
private boolean postPivot = false;
private boolean doingSWA = false;
/**
* MessageImpl should be constructed via the MessageFactory.
* This constructor constructs an empty message with the specified protocol
* @param protocol
*/
MessageImpl(Protocol protocol) throws WebServiceException, XMLStreamException {
createXMLPart(protocol);
}
/**
* Message is constructed by the MessageFactory.
* This constructor creates a message from the specified root.
* @param root
* @param protocol or null
*/
MessageImpl(OMElement root, Protocol protocol)
throws WebServiceException, XMLStreamException {
createXMLPart(root, protocol);
}
/**
* Message is constructed by the MessageFactory.
* This constructor creates a message from the specified root.
* @param root
* @param protocol or null
*/
MessageImpl(SOAPEnvelope root) throws WebServiceException, XMLStreamException {
createXMLPart(root);
}
/**
* Create a new XMLPart and Protocol from the root
* @param root SOAPEnvelope
* @throws WebServiceException
* @throws XMLStreamException
*/
private void createXMLPart(SOAPEnvelope root) throws WebServiceException, XMLStreamException {
XMLPartFactory factory = (XMLPartFactory) FactoryRegistry.getFactory(XMLPartFactory.class);
xmlPart = factory.createFrom(root);
this.protocol = xmlPart.getProtocol();
xmlPart.setParent(this);
}
/**
* Create a new XMLPart and Protocol from the root
* @param root OMElement
* @throws WebServiceException
* @throws XMLStreamException
*/
private void createXMLPart(OMElement root, Protocol protocol)
throws WebServiceException, XMLStreamException {
XMLPartFactory factory = (XMLPartFactory) FactoryRegistry.getFactory(XMLPartFactory.class);
xmlPart = factory.createFrom(root, protocol);
this.protocol = xmlPart.getProtocol();
xmlPart.setParent(this);
}
/**
* Create a new empty XMLPart from the Protocol
* @param protocol
* @throws WebServiceException
* @throws XMLStreamException
*/
private void createXMLPart(Protocol protocol) throws WebServiceException, XMLStreamException {
this.protocol = protocol;
if (protocol.equals(Protocol.unknown)) {
throw ExceptionFactory.
makeWebServiceException(Messages.getMessage("ProtocolIsNotKnown"));
}
XMLPartFactory factory = (XMLPartFactory) FactoryRegistry.getFactory(XMLPartFactory.class);
xmlPart = factory.create(protocol);
xmlPart.setParent(this);
}
/* (non-Javadoc)
* @see org.apache.axis2.jaxws.message.Message#getAsSOAPMessage()
*/
public SOAPMessage getAsSOAPMessage() throws WebServiceException {
// TODO:
// This is a non performant way to create SOAPMessage. I will serialize
// the xmlpart content and then create an InputStream of byte.
// Finally create SOAPMessage using this InputStream.
// The real solution may involve using non-spec, implementation
// constructors to create a Message from an Envelope
try {
// Get OMElement from XMLPart.
OMElement element = xmlPart.getAsOMElement();
// Get the namespace so that we can determine SOAP11 or SOAP12
OMNamespace ns = element.getNamespace();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
element.serialize(outStream);
// Create InputStream
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream
.toByteArray());
// Create MessageFactory that supports the version of SOAP in the om element
MessageFactory mf = getSAAJConverter().createMessageFactory(ns.getNamespaceURI());
// Create soapMessage object from Message Factory using the input
// stream created from OM.
// Get the MimeHeaders from the transportHeaders map
MimeHeaders defaultHeaders = new MimeHeaders();
if (transportHeaders != null) {
Iterator it = transportHeaders.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
if (entry.getValue() instanceof String) {
// Normally there is one value per key
defaultHeaders.addHeader(key, (String) entry.getValue());
} else {
// There may be multiple values for each key. This code
// assumes the value is an array of String.
String values[] = (String[]) entry.getValue();
for (int i=0; i<values.length; i++) {
defaultHeaders.addHeader(key, values[i]);
}
}
}
}
// Toggle based on SOAP 1.1 or SOAP 1.2
String contentType = null;
if (ns.getNamespaceURI().equals(SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE)) {
contentType = SOAPConstants.SOAP_1_1_CONTENT_TYPE;
} else {
contentType = SOAPConstants.SOAP_1_2_CONTENT_TYPE;
}
// Override the content-type
defaultHeaders.setHeader("Content-type", contentType +"; charset=UTF-8");
SOAPMessage soapMessage = mf.createMessage(defaultHeaders, inStream);
// At this point the XMLPart is still an OMElement.
// We need to change it to the new SOAPEnvelope.
createXMLPart(soapMessage.getSOAPPart().getEnvelope());
// If axiom read the message from the input stream,
// then one of the attachments is a SOAPPart. Ignore this attachment
String soapPartContentID = getSOAPPartContentID(); // This may be null
// Add the attachments
for (String cid:getAttachmentIDs()) {
DataHandler dh = attachments.getDataHandler(cid);
boolean isSOAPPart = cid.equals(soapPartContentID);
if (!isSOAPPart) {
AttachmentPart ap = MessageUtils.createAttachmentPart(cid, dh, soapMessage);
soapMessage.addAttachmentPart(ap);
}
}
return soapMessage;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
/**
* Get the indicated (non-soap part) attachment id
* @param index
* @return CID or null if not present
*/
public String getAttachmentID(int index) {
List<String> cids = getAttachmentIDs();
String spCID = getSOAPPartContentID();
if (log.isDebugEnabled()) {
log.debug("getAttachmentID for index =" + index);
for (int i = 0; i < cids.size(); i++) {
log.debug("Attachment CID (" + i + ") = " + cids.indexOf(i));
}
log.debug("The SOAP Part CID is ignored. It's CID is (" + spCID + ")");
}
int spIndex = (spCID == null) ? -1 : cids.indexOf(spCID);
// Bump index so we don't consider the soap part
index = (spIndex != -1 && spIndex <= index) ? index + 1 : index;
// Return the content id at the calculated index
String resultCID = null;
if (index < cids.size()) {
resultCID = cids.get(index);
}
if (log.isDebugEnabled()) {
log.debug("Returning CID=" + resultCID);
}
return resultCID;
}
private String getSOAPPartContentID() {
String contentID = null;
if (messageContext == null) {
return null; // Attachments set up programmatically...so there is no SOAPPart
}
try {
contentID = attachments.getSOAPPartContentID();
} catch (RuntimeException e) {
// OM will kindly throw an OMException or NPE if the attachments is set up
// programmatically.
return null;
}
return contentID;
}
/* (non-Javadoc)
* @see org.apache.axis2.jaxws.message.Message#getValue(java.lang.Object,
* org.apache.axis2.jaxws.message.factory.BlockFactory)
*/
public Object getValue(Object context, BlockFactory blockFactory) throws WebServiceException {
try {
Object value = null;
if (protocol == Protocol.rest) {
// The implementation of rest stores the rest xml inside a dummy soap 1.1 envelope.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?