providerdispatcher.java
来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 425 行 · 第 1/2 页
JAVA
425 行
/*
* 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.server.dispatcher;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.core.util.MessageContextUtils;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.marshaller.impl.alt.MethodMarshallerUtils;
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.factory.BlockFactory;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.message.factory.SOAPEnvelopeBlockFactory;
import org.apache.axis2.jaxws.message.factory.SourceBlockFactory;
import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.server.EndpointController;
import org.apache.axis2.jaxws.utility.ClassUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.activation.DataSource;
import javax.xml.bind.JAXBContext;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.security.PrivilegedExceptionAction;
/**
* The ProviderDispatcher is used to invoke instances of a target endpoint that implement the {@link
* javax.xml.ws.Provider} interface.
* <p/>
* The Provider<T> is a generic class, with certain restrictions on the parameterized type T. This
* implementation supports the following types:
* <p/>
* java.lang.String javax.activation.DataSource javax.xml.soap.SOAPMessage
* javax.xml.transform.Source
*/
public class ProviderDispatcher extends JavaDispatcher {
private static Log log = LogFactory.getLog(ProviderDispatcher.class);
private BlockFactory blockFactory = null;
private Class providerType = null;
private Provider providerInstance = null;
private Service.Mode providerServiceMode = null;
private Message message = null;
private Protocol messageProtocol;
/**
* Constructor
*
* @param _class
* @param serviceInstance
*/
public ProviderDispatcher(Class _class, Object serviceInstance) {
super(_class, serviceInstance);
}
/* (non-Javadoc)
* @see org.apache.axis2.jaxws.server.EndpointDispatcher#execute()
*/
public MessageContext invoke(final MessageContext mc) throws Exception {
if (log.isDebugEnabled()) {
log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
}
providerInstance = getProviderInstance();
// First we need to know what kind of Provider instance we're going
// to be invoking against
providerType = getProviderType();
// REVIEW: This assumes there is only one endpoint description on the service. Is that always the case?
EndpointDescription endpointDesc = mc.getEndpointDescription();
// Now that we know what kind of Provider we have, we can create the
// right type of Block for the request parameter data
Object requestParamValue = null;
Message message = mc.getMessage();
if (message != null) {
// Enable MTOM if indicated by the binding
String bindingType = endpointDesc.getBindingType();
if (bindingType != null) {
if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
message.setMTOMEnabled(true);
}
}
// Save off the protocol info so we can use it when creating the response message.
messageProtocol = message.getProtocol();
// Determine what type blocks we want to create (String, Source, etc) based on Provider Type
BlockFactory factory = createBlockFactory(providerType);
providerServiceMode = endpointDesc.getServiceMode();
if (providerServiceMode != null && providerServiceMode == Service.Mode.MESSAGE) {
if (providerType.equals(SOAPMessage.class)) {
// We can get the SOAPMessage directly from the message itself
if (log.isDebugEnabled()) {
log.debug("Provider Type is SOAPMessage.");
log.debug("Number Message attachments=" + message.getAttachmentIDs().size());
}
}
requestParamValue = message.getValue(null, factory);
if (requestParamValue == null) {
if (log.isDebugEnabled()) {
log.debug(
"There are no elements to unmarshal. ProviderDispatch will pass a null as input");
}
}
} else {
// If it is not MESSAGE, then it is PAYLOAD (which is the default); only work with the body
Block block = message.getBodyBlock(null, factory);
if (block != null) {
requestParamValue = block.getBusinessObject(true);
} else {
if (log.isDebugEnabled()) {
log.debug(
"No body blocks in SOAPMessage, Calling provider method with null input parameters");
}
requestParamValue = null;
}
}
}
if (log.isDebugEnabled())
log.debug(
"Provider Type = " + providerType + "; parameter type = " + requestParamValue);
final Object input = providerType.cast(requestParamValue);
if (input != null && log.isDebugEnabled()) {
log.debug("Invoking Provider<" + providerType.getName() + "> with " +
"parameter of type " + input.getClass().getName());
}
if (input == null && log.isDebugEnabled()) {
log.debug("Invoking Provider<" + providerType.getName() + "> with " +
"NULL input parameter");
}
// Invoke the actual Provider.invoke() method
boolean faultThrown = false;
XMLFault fault = null;
Object responseParamValue = null;
Throwable t = null;
try {
responseParamValue = (Object)org.apache.axis2.java.security.AccessController
.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
return invokeProvider(mc, providerInstance, input);
}
});
} catch (Exception e) {
t = ClassUtils.getRootCause(e);
faultThrown = true;
fault = MethodMarshallerUtils.createXMLFaultFromSystemException(t);
if (log.isDebugEnabled()) {
log.debug("Marshal Throwable =" + e.getClass().getName());
log.debug(" rootCause =" + t.getClass().getName());
log.debug(" exception=" + t.toString());
}
}
// Create the response MessageContext
MessageContext responseMsgCtx = null;
if (!EndpointController.isOneWay(mc.getAxisMessageContext())) {
if (faultThrown) {
// If a fault was thrown, we need to create a slightly different
// MessageContext, than in the response path.
Message responseMsg = createMessageFromValue(fault);
responseMsgCtx = MessageContextUtils.createFaultMessageContext(mc);
responseMsgCtx.setMessage(responseMsg);
} else {
Message responseMsg = createMessageFromValue(responseParamValue);
// Enable MTOM if indicated by the binding
String bindingType = endpointDesc.getBindingType();
if (bindingType != null) {
if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
responseMsg.setMTOMEnabled(true);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?