messagecontextbuilder.java
来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 625 行 · 第 1/2 页
JAVA
625 行
/*
* 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.util;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPConstants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultDetail;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axiom.soap.SOAPProcessingException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.AddressingConstants.Final;
import org.apache.axis2.addressing.AddressingHelper;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.addressing.RelatesTo;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.description.WSDL2Constants;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.jms.JMSConstants;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.namespace.QName;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.List;
public class MessageContextBuilder {
protected static final Log log = LogFactory.getLog(MessageContextBuilder.class);
/**
* Creates a new 'response' message context based on a 'request' message context
* Only deals with properties/fields that are the same for both 'normal' and fault responses.
*/
private static MessageContext createResponseMessageContext(MessageContext inMessageContext)
throws AxisFault {
MessageContext newmsgCtx =
inMessageContext.getConfigurationContext().createMessageContext();
newmsgCtx.setSessionContext(inMessageContext.getSessionContext());
newmsgCtx.setTransportIn(inMessageContext.getTransportIn());
newmsgCtx.setTransportOut(inMessageContext.getTransportOut());
newmsgCtx.setServerSide(inMessageContext.isServerSide());
// TODO: Should this be specifying (or defaulting to) the "response" relationshipType??
newmsgCtx.addRelatesTo(new RelatesTo(inMessageContext.getOptions().getMessageId()));
newmsgCtx.setProperty(AddressingConstants.WS_ADDRESSING_VERSION,
inMessageContext.getProperty(
AddressingConstants.WS_ADDRESSING_VERSION));
newmsgCtx.setProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES,
inMessageContext.getProperty(
AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES));
newmsgCtx.setProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME,
inMessageContext.getProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME));
newmsgCtx.setProperty(Constants.AXIS_BINDING_OPERATION,
inMessageContext.getProperty(Constants.AXIS_BINDING_OPERATION));
// Setting the charater set encoding
newmsgCtx.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING,
inMessageContext.getProperty(
Constants.Configuration.CHARACTER_SET_ENCODING));
//Setting the message type property
newmsgCtx.setProperty(Constants.Configuration.MESSAGE_TYPE,
inMessageContext.getProperty(Constants.Configuration.MESSAGE_TYPE));
newmsgCtx.setDoingREST(inMessageContext.isDoingREST());
newmsgCtx.setOperationContext(inMessageContext.getOperationContext());
newmsgCtx.setProperty(MessageContext.TRANSPORT_OUT,
inMessageContext.getProperty(MessageContext.TRANSPORT_OUT));
newmsgCtx.setProperty(Constants.OUT_TRANSPORT_INFO,
inMessageContext.getProperty(Constants.OUT_TRANSPORT_INFO));
handleCorrelationID(inMessageContext,newmsgCtx);
return newmsgCtx;
}
/**
* Creates a MessageContext for use with a non-fault response based on an request MessageContext
*/
public static MessageContext createOutMessageContext(MessageContext inMessageContext)
throws AxisFault {
// Create a basic response MessageContext with basic fields copied
MessageContext newmsgCtx = createResponseMessageContext(inMessageContext);
// Simple response so set To to value of inbound ReplyTo
newmsgCtx.setTo(inMessageContext.getReplyTo());
if (newmsgCtx.getTo() == null) {
newmsgCtx.setTo(new EndpointReference(AddressingConstants.Final.WSA_ANONYMOUS_URL));
}
// do Target Resolution
TargetResolver targetResolver =
newmsgCtx.getConfigurationContext().getAxisConfiguration().getTargetResolverChain();
if (targetResolver != null) {
targetResolver.resolveTarget(newmsgCtx);
}
// Determine ReplyTo for response message.
AxisService axisService = inMessageContext.getAxisService();
if (axisService != null && Constants.SCOPE_SOAP_SESSION.equals(axisService.getScope())) {
//If the wsa 2004/08 (submission) spec is in effect use the wsa anonymous URI as the default replyTo value.
//This is necessary because the wsa none URI is not available in that spec.
Object version = inMessageContext.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
if (AddressingConstants.Submission.WSA_NAMESPACE.equals(version)) {
newmsgCtx.setReplyTo(
new EndpointReference(AddressingConstants.Submission.WSA_ANONYMOUS_URL));
} else {
newmsgCtx.setReplyTo(new EndpointReference(AddressingConstants.Final.WSA_NONE_URI));
}
newmsgCtx.setMessageID(UUIDGenerator.getUUID());
// add the service group id as a reference parameter
String serviceGroupContextId = inMessageContext.getServiceGroupContextId();
if (serviceGroupContextId != null && !"".equals(serviceGroupContextId)) {
EndpointReference replyToEPR = newmsgCtx.getReplyTo();
replyToEPR.addReferenceParameter(new QName(Constants.AXIS2_NAMESPACE_URI,
Constants.SERVICE_GROUP_ID,
Constants.AXIS2_NAMESPACE_PREFIX),
serviceGroupContextId);
}
} else {
EndpointReference outboundToEPR = newmsgCtx.getTo();
Object version = newmsgCtx.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
if (AddressingConstants.Submission.WSA_NAMESPACE.equals(version) ||
(outboundToEPR != null && !outboundToEPR.hasAnonymousAddress())) {
newmsgCtx.setMessageID(UUIDGenerator.getUUID());
newmsgCtx.setReplyTo(new EndpointReference(AddressingConstants.Final.WSA_NONE_URI));
}
}
// Set wsa:Action for response message
// Use specified value if available
AxisOperation ao = inMessageContext.getAxisOperation();
if ((ao != null) && (ao.getOutputAction() != null)) {
newmsgCtx.setWSAAction(ao.getOutputAction());
} else { // If not, simply copy the request value. Almost always invalid.
newmsgCtx.setWSAAction(inMessageContext.getWSAAction());
}
if (ao != null)
newmsgCtx.setAxisMessage(ao.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE));
newmsgCtx.setDoingMTOM(inMessageContext.isDoingMTOM());
newmsgCtx.setDoingSwA(inMessageContext.isDoingSwA());
newmsgCtx.setServiceGroupContextId(inMessageContext.getServiceGroupContextId());
// Ensure transport settings match the scheme for the To EPR
setupCorrectTransportOut(newmsgCtx);
return newmsgCtx;
}
/**
* Copies the correlation id (jms) from the in message ctx
* to the out message ctx. Currently this check is for jms
* only, but can be expanded to other transports if the need
* arises.
*/
private static void handleCorrelationID(MessageContext inMessageContext,MessageContext outMessageContext)
{
if (inMessageContext.getIncomingTransportName()!= null &&
inMessageContext.getIncomingTransportName().equals(Constants.TRANSPORT_JMS))
{
log.debug("Incoming Transport is JMS, lets check for JMS correlation id");
String correlationId =
(String) inMessageContext.getProperty(JMSConstants.JMS_COORELATION_ID);
log.debug("Correlation id is " + correlationId);
if (correlationId != null && correlationId.length() > 0) {
outMessageContext.setProperty(JMSConstants.JMS_COORELATION_ID, correlationId);
}
}
}
/**
* This method is called to handle any error that occurs at inflow or outflow. But if the
* method is called twice, it implies that sending the error handling has failed, in which case
* the method logs the error and exits.
*/
public static MessageContext createFaultMessageContext(MessageContext processingContext,
Throwable e)
throws AxisFault {
if (processingContext.isProcessingFault()) {
// We get the error file processing the fault. nothing we can do
throw new AxisFault(Messages.getMessage("errorwhileProcessingFault"));
}
// See if the throwable is an AxisFault and if it already contains the
// fault MessageContext
if (e instanceof AxisFault) {
MessageContext faultMessageContext = ((AxisFault) e).getFaultMessageContext();
if (faultMessageContext != null) {
// These may not have been set correctly when the original context
// was created -- an example of this is with the SimpleHTTPServer.
// I'm not sure if this is the correct thing to do, or if the
// code that created this context in the first place should
// expect that the transport out info was set correctly, as
// it may need to use that info at some point before we get to
// this code.
faultMessageContext.setProperty(MessageContext.TRANSPORT_OUT,
processingContext.getProperty(
MessageContext.TRANSPORT_OUT));
faultMessageContext.setProperty(Constants.OUT_TRANSPORT_INFO,
processingContext.getProperty(
Constants.OUT_TRANSPORT_INFO));
faultMessageContext.setProcessingFault(true);
return faultMessageContext;
}
}
// Create a basic response MessageContext with basic fields copied
MessageContext faultContext = createResponseMessageContext(processingContext);
// Register the fault message context
OperationContext operationContext = processingContext.getOperationContext();
if (operationContext != null) {
processingContext.getAxisOperation().addFaultMessageContext(faultContext,
operationContext);
}
faultContext.setProcessingFault(true);
// Set wsa:Action for response message
// Use specified value if available
String faultAction = (e instanceof AxisFault) ? ((AxisFault)e).getFaultAction() : null;
if (faultAction == null) {
AxisOperation op = processingContext.getAxisOperation();
if (op != null && op.getFaultAction() != null) {
// TODO: Should the op be able to pick a fault action based on the fault?
faultAction = op.getFaultAction();
} else { //If, for some reason there is no value set, should use a sensible action.
faultAction = Final.WSA_SOAP_FAULT_ACTION;
}
}
faultContext.setWSAAction(faultAction);
// there are some information that the fault thrower wants to pass to the fault path.
// Means that the fault is a ws-addressing one hence use the ws-addressing fault action.
Object faultInfoForHeaders =
processingContext.getProperty(Constants.FAULT_INFORMATION_FOR_HEADERS);
if (faultInfoForHeaders != null) {
faultContext.setProperty(Constants.FAULT_INFORMATION_FOR_HEADERS, faultInfoForHeaders);
// Note that this overrides any action set above
faultContext.setWSAAction(Final.WSA_FAULT_ACTION);
}
// if the exception is due to a problem in the faultTo header itself, we can not use that
// fault information to send the error. Try to send using replyTo, else leave it to transport
boolean shouldSendFaultToFaultTo =
AddressingHelper.shouldSendFaultToFaultTo(processingContext);
EndpointReference faultTo = processingContext.getFaultTo();
if (faultTo != null && shouldSendFaultToFaultTo) {
faultContext.setTo(faultTo);
} else {
faultContext.setTo(processingContext.getReplyTo());
}
if (faultContext.getTo() == null) {
faultContext.setTo(new EndpointReference(AddressingConstants.Final.WSA_ANONYMOUS_URL));
}
// Not worth setting up the session information on a fault flow
EndpointReference outboundToEPR = faultContext.getTo();
Object version = faultContext.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
if (AddressingConstants.Submission.WSA_NAMESPACE.equals(version) ||
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?