jaxwsproxyhandler.java
来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 443 行 · 第 1/2 页
JAVA
443 行
/*
* 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.client.proxy;
import javax.xml.ws.handler.HandlerResolver;
import org.apache.axis2.jaxws.BindingProvider;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.client.async.AsyncResponse;
import org.apache.axis2.jaxws.core.InvocationContext;
import org.apache.axis2.jaxws.core.InvocationContextFactory;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.core.controller.AxisInvocationController;
import org.apache.axis2.jaxws.core.controller.InvocationController;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.OperationDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.marshaller.factory.MethodMarshallerFactory;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.spi.Constants;
import org.apache.axis2.jaxws.spi.ServiceDelegate;
import org.apache.axis2.jaxws.spi.migrator.ApplicationContextMigratorUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Binding;
import javax.xml.ws.Response;
import javax.xml.ws.soap.SOAPBinding;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
* ProxyHandler is the java.lang.reflect.InvocationHandler implementation. When a JAX-WS client
* calls the method on a proxy object, created by calling the ServiceDelegate.getPort(...) method,
* the inovke method on the ProxyHandler is called.
* <p/>
* ProxyHandler uses EndpointInterfaceDescriptor and finds out if 1) The client call is Document
* Literal or Rpc Literal 2) The WSDL is wrapped or unWrapped.
* <p/>
* ProxyHandler then reads OperationDescription using Method name called by Client From
* OperationDescription it does the following 1) if the wsdl isWrapped() reads RequestWrapper Class
* and responseWrapperClass 2) then reads the webParams for the Operation.
* <p/>
* isWrapped() = true and DocLiteral then ProxyHandler then uses WrapperTool to create Request that
* is a Wrapped JAXBObject. Creates JAXBBlock using JAXBBlockFactory Creates MessageContext->Message
* and sets JAXBBlock to xmlPart as RequestMsgCtx in InvocationContext. Makes call to
* InvocationController. Reads ResponseMsgCtx ->MessageCtx->Message->XMLPart. Converts that to
* JAXBlock using JAXBBlockFactory and returns the BO from this JAXBBlock.
* <p/>
* isWrapped() != true and DocLiteral then ProxyHandler creates the JAXBBlock for the input request
* creates a MessageContext that is then used by IbvocationController to invoke. Response is read
* and return object is derived using @Webresult annotation. A JAXBBlock is created from the
* Response and the BO from JAXBBlock is returned.
*/
public class JAXWSProxyHandler extends BindingProvider implements
InvocationHandler {
private static Log log = LogFactory.getLog(JAXWSProxyHandler.class);
//Reference to ServiceDelegate instance that was used to create the Proxy
protected ServiceDescription serviceDesc = null;
private Class seiClazz = null;
private Method method = null;
public JAXWSProxyHandler(ServiceDelegate delegate, Class seiClazz, EndpointDescription epDesc) {
super(delegate, epDesc);
this.seiClazz = seiClazz;
this.serviceDesc = delegate.getServiceDescription();
}
/* (non-Javadoc)
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*
* Invokes the method that was called on the java.lang.reflect.Proxy instance.
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
boolean debug = log.isDebugEnabled();
if (debug) {
log.debug("Attemping to invoke Method: " + method.getName());
}
this.method = method;
if (!isValidMethodCall(method)) {
throw ExceptionFactory.makeWebServiceException(
Messages.getMessage("proxyErr1", method.getName(), seiClazz.getName()));
}
if (!isPublic(method)) {
throw ExceptionFactory.makeWebServiceException(
Messages.getMessage("proxyPrivateMethod", method.getName()));
}
if (isBindingProviderInvoked(method)) {
// Since the JAX-WS proxy instance must also implement the javax.xml.ws.BindingProvider
// interface, this object must handle those invocations as well. In that case, we'll
// delegate those calls to the BindingProvider object.
if (debug) {
log.debug(
"Invoking a public method on the javax.xml.ws.BindingProvider interface.");
}
try {
return method.invoke(this, args);
}
catch (Throwable e) {
if (debug) {
log.debug("An error occured while invoking the method: " + e.getMessage());
}
throw ExceptionFactory.makeWebServiceException(e);
}
} else {
OperationDescription operationDesc =
endpointDesc.getEndpointInterfaceDescription().getOperation(method);
if (isMethodExcluded(operationDesc)) {
throw ExceptionFactory.makeWebServiceException(
Messages.getMessage("proxyExcludedMethod", method.getName()));
}
return invokeSEIMethod(method, args);
}
}
/*
* Performs the invocation of the method defined on the Service Endpoint
* Interface.
*/
private Object invokeSEIMethod(Method method, Object[] args) throws Throwable {
if (log.isDebugEnabled()) {
log.debug("Attempting to invoke SEI Method " + method.getName());
}
OperationDescription operationDesc =
endpointDesc.getEndpointInterfaceDescription().getOperation(method);
// Create and configure the request MessageContext
InvocationContext requestIC = InvocationContextFactory.createInvocationContext(null);
MessageContext request = createRequest(method, args);
request.setEndpointDescription(getEndpointDescription());
request.setOperationDescription(operationDesc);
// Enable MTOM on the Message if the property was set on the SOAPBinding.
Binding bnd = getBinding();
if (bnd != null && bnd instanceof SOAPBinding) {
if (((SOAPBinding)bnd).isMTOMEnabled()) {
Message requestMsg = request.getMessage();
requestMsg.setMTOMEnabled(true);
}
}
/*
* TODO: review: make sure the handlers are set on the InvocationContext
* This implementation of the JAXWS runtime does not use Endpoint, which
* would normally be the place to initialize and store the handler list.
* In lieu of that, we will have to intialize and store them on the
* InvocationContext. also see the InvocationContextFactory. On the client
* side, the binding is not yet set when we call into that factory, so the
* handler list doesn't get set on the InvocationContext object there. Thus
* we gotta do it here.
*/
// be sure to use whatever handlerresolver is registered on the Service
requestIC.setHandlers(bnd.getHandlerChain());
requestIC.setRequestMessageContext(request);
requestIC.setServiceClient(serviceDelegate.getServiceClient(endpointDesc.getPortQName()));
// TODO: Change this to some form of factory so that we can change the IC to
// a more simple one for marshaller/unmarshaller testing.
InvocationController controller = new AxisInvocationController();
// Migrate the properties from the client request context bag to
// the request MessageContext.
ApplicationContextMigratorUtil.performMigrationToMessageContext(
Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID,
getRequestContext(), request);
// Check if the call is OneWay, Async or Sync
if (operationDesc.isOneWay()) {
if (log.isDebugEnabled()) {
log.debug("OneWay Call");
}
controller.invokeOneWay(requestIC);
// Check to see if we need to maintain session state
checkMaintainSessionState(request, requestIC);
}
if (method.getReturnType() == Future.class) {
if (log.isDebugEnabled()) {
log.debug("Async Callback");
}
//Get AsyncHandler from Objects and sent that to InvokeAsync
AsyncHandler asyncHandler = null;
for (Object obj : args) {
if (obj != null && AsyncHandler.class.isAssignableFrom(obj.getClass())) {
asyncHandler = (AsyncHandler)obj;
break;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?