`
Dead_knight
  • 浏览: 1202288 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
752c8642-b795-3fe6-946e-a4e845bffdec
Spring Securi...
浏览量:240617
33caa84e-18a6-3036-a82b-6e2106a4de63
clojure专题
浏览量:49056
E17ca077-44df-3816-a3fe-471c43f6e1e5
WebLogic11g
浏览量:237060
社区版块
存档分类
最新评论

Axis源码分析-Web服务部署(二)

    博客分类:
  • J2EE
阅读更多
1.服务部署:
1)即时发布
编写java类,去掉包名称,将.java文件类型改成jws。
通过浏览器打开url如:http://localhost:8888/axis/EchoHeaders.jws
点击“Click to see the WSDL”,即可查看所部署服务的WSDL描述文件

2)定制发布
通过deploy.wsdd部署,如:
  <service name="AxisService" provider="java:RPC">
  <parameter name="allowedMethods" value="*"/>
  <parameter name="className" value="com.axis.service.AxisService"/>
</service>

2.源码解读:
1)初始化AxisEngine:
  <servlet>
    <servlet-name>AxisServlet</servlet-name>
    <display-name>Apache-Axis Servlet</display-name>
    <servlet-class>
        org.apache.axis.transport.http.AxisServlet
    </servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>*.jws</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

即所有以jws结尾或者services路径的的URL均由AxisServlet进行处理。
AxisServlet的init方法:
public void init() throws javax.servlet.ServletException {
        //super.init()即执行父类AxisServletBase的init方法,完成AxisServer初始化工作
        super.init();
        ServletContext context = getServletConfig().getServletContext();
        isDebug = log.isDebugEnabled();
        if (isDebug) {
            log.debug("In servlet init");
        }
        transportName = getOption(context,
                                  INIT_PROPERTY_TRANSPORT_NAME,
HTTPTransport.DEFAULT_TRANSPORT_NAME);
        if (JavaUtils.isTrueExplicitly(getOption(context,
INIT_PROPERTY_USE_SECURITY, null))) {
            securityProvider = new ServletSecurityProvider();
        }

        enableList =
                JavaUtils.isTrueExplicitly(getOption(context,
                INIT_PROPERTY_ENABLE_LIST, null));

        jwsClassDir = getOption(context, INIT_PROPERTY_JWS_CLASS_DIR, null);

        disableServicesList = JavaUtils.isTrue(getOption(context,
                INIT_PROPERTY_DISABLE_SERVICES_LIST, "false"));

        servicesPath = getOption(context, INIT_PROPERTY_SERVICES_PATH,
                                 "/services/");

        if (jwsClassDir != null) {
            if (getHomeDir() != null) {
                jwsClassDir = getHomeDir() + jwsClassDir;
            }
        } else {
            jwsClassDir = getDefaultJWSClassDir();
        }
        //初始化查询Handler,即wsdl对应的handler,用于wsdl文件生成
        initQueryStringHandlers();

        // Setup the service admin
        try {
            ServiceAdmin.setEngine(this.getEngine(), context.getServerInfo());
        } catch (AxisFault af) {
            exceptionLog.info("Exception setting AxisEngine on ServiceAdmin " +
                              af);
        }
    }

AxisServletBase.init():
    public void init() throws javax.servlet.ServletException {
        ServletContext context = getServletConfig().getServletContext();
        webInfPath = context.getRealPath("/WEB-INF");
        homeDir = context.getRealPath("/");
        isDebug = log.isDebugEnabled();
        if(log.isDebugEnabled()) log.debug("In AxisServletBase init");
        //触发AxisServer的初始化
        isDevelopment= JavaUtils.isTrueExplicitly(getOption(context,
                        INIT_PROPERTY_DEVELOPMENT_SYSTEM, null));
    }

AxisServer初始化工作由getOption触发
    protected String getOption(ServletContext context,
                             String param,
                             String dephault)
    {
        String value = AxisProperties.getProperty(param);
        if (value == null)
            value = getInitParameter(param);

        if (value == null)
            value = context.getInitParameter(param);
        try {
            //初始化AxisServer
            AxisServer engine = getEngine(this);
            if (value == null && engine != null)
                value = (String) engine.getOption(param);
        } catch (AxisFault axisFault) {
        }
        return (value != null) ? value : dephault;
    }

初始化AxisServer:
    public static AxisServer getEngine(HttpServlet servlet) throws AxisFault
    {
        AxisServer engine = null;
        if (isDebug)
            log.debug("Enter: getEngine()");
        ServletContext context = servlet.getServletContext();
        synchronized (context) {
            engine = retrieveEngine(servlet);
            if (engine == null) {
                //配置Engine环境
                Map environment = getEngineEnvironment(servlet);
                //初始化AxisServer Engine
                engine = AxisServer.getServer(environment);
                engine.setName(servlet.getServletName());
                //存储AxisServer Engine至上下文
                storeEngine(servlet, engine);
            }
        }
        if (isDebug)
            log.debug("Exit: getEngine()");
        return engine;
    }

首先从当前上下文中获取AxisServer Engine,如果返回为null,则进行初始化并存储至上下文中。
    protected static Map getEngineEnvironment(HttpServlet servlet) {
        Map environment = new HashMap();

        String attdir= servlet.getInitParameter(AxisEngine.ENV_ATTACHMENT_DIR);
        if (attdir != null)
            environment.put(AxisEngine.ENV_ATTACHMENT_DIR, attdir);

        ServletContext context = servlet.getServletContext();
        environment.put(AxisEngine.ENV_SERVLET_CONTEXT, context);

        String webInfPath = context.getRealPath("/WEB-INF");
        if (webInfPath != null)
            environment.put(AxisEngine.ENV_SERVLET_REALPATH,
                            webInfPath + File.separator + "attachments");

        EngineConfiguration config =
            EngineConfigurationFactoryFinder.newFactory(servlet)
                    .getServerEngineConfig();

        if (config != null) {
            environment.put(EngineConfiguration.PROPERTY_NAME, config);
        }

        return environment;
    }

EngineConfigurationFactoryFinder.newFactory(servlet)返回org.apache.axis.configuration.EngineConfigurationFactoryServlet工厂实例,并通过private static EngineConfiguration getServerEngineConfig(ServletConfig cfg)新建EngineConfiguration实现类:FileProvider对象(即server-config.wsdd的文件操作类)

AxisServer类getServer方法充当工厂方法,返回自身对象。但实际新建AxisServer Engine任务是委托AxisServerFactory工厂实例完成。
    public static AxisServer getServer(Map environment) throws AxisFault
    {
        if (factory == null) {
            String factoryClassName = AxisProperties.getProperty("axis.ServerFactory");
            if (factoryClassName != null) {
                try {
                    Class factoryClass = ClassUtils.forName(factoryClassName);
                    if (AxisServerFactory.class.isAssignableFrom(factoryClass))
                        factory = (AxisServerFactory)factoryClass.newInstance();
                } catch (Exception e) {
                    // If something goes wrong here, should we just fall
                    // through and use the default one?
                    log.error(Messages.getMessage("exception00"), e);
                }
            }
            
            if (factory == null) {
                //通过默认工厂新建Server Engine
                factory = new DefaultAxisServerFactory();
            }
        }
        return factory.getServer(environment);                
    }

DefaultAxisServerFactory类getServer方法:
    public AxisServer getServer(Map environment) throws AxisFault {
        log.debug("Enter: DefaultAxisServerFactory::getServer");

        AxisServer ret = createServer(environment);

        if (ret != null) {
            if (environment != null) {
                ret.setOptionDefault(AxisEngine.PROP_ATTACHMENT_DIR,
                    (String)environment.get(AxisEngine.ENV_ATTACHMENT_DIR));

                ret.setOptionDefault(AxisEngine.PROP_ATTACHMENT_DIR,
                    (String)environment.get(AxisEngine.ENV_SERVLET_REALPATH));
            }

            String attachmentsdir = (String)ret.getOption(AxisEngine.PROP_ATTACHMENT_DIR);

            if (attachmentsdir != null) {
                File attdirFile = new File(attachmentsdir);
                if (!attdirFile.isDirectory()) {
                    attdirFile.mkdirs();
                }
            }
        }

        log.debug("Exit: DefaultAxisServerFactory::getServer");

        return ret;
    }

    private static AxisServer createServer(Map environment) {
        //从Map环境中取出FileProvider对象
        EngineConfiguration config = getEngineConfiguration(environment);
        //通过AxisServer(EngineConfiguration config)构造函数新建对象
        return (config == null) ? new AxisServer() : new AxisServer(config);
    }


    public AxisServer(EngineConfiguration config)
    {
        //Engine的初始化由父类AxisEngine完成
        super(config);
        // 服务端默认是保存配置
        setShouldSaveConfig(true);
    }


public void init() {
        if (log.isDebugEnabled()) {
            log.debug("Enter: AxisEngine::init");
        }
        try {
            //通过FileProvider类配置Engine
            config.configureEngine(this);
        } catch (Exception e) {
            throw new InternalException(e);
        }
        setOptionDefault(PROP_ATTACHMENT_IMPLEMENTATION,
                         AxisProperties.getProperty("axis." + PROP_ATTACHMENT_IMPLEMENTATION  ));

        setOptionDefault(PROP_ATTACHMENT_IMPLEMENTATION, DEFAULT_ATTACHMENT_IMPL);
        final Object dotnet = getOption(PROP_DOTNET_SOAPENC_FIX);
        if (JavaUtils.isTrue(dotnet)) {
            TypeMappingImpl.dotnet_soapenc_bugfix = true;
        }

        if (log.isDebugEnabled()) {
            log.debug("Exit: AxisEngine::init");
        }

    }

public void configureEngine(AxisEngine engine)
        throws ConfigurationException {
        try {
            if (getInputStream() == null) {
                try {
                    setInputStream(new FileInputStream(configFile));
                } catch (Exception e) {
                    if (searchClasspath)
                        setInputStream(ClassUtils.getResourceAsStream(engine.getClass(), filename, true));
                }
            }

            if (getInputStream() == null) {
                throw new ConfigurationException(
                        Messages.getMessage("noConfigFile"));
            }
            //初始化deployment
            WSDDDocument doc = new WSDDDocument(XMLUtils.
                                                newDocument(getInputStream()));
            deployment = doc.getDeployment();
            //deployment持有Engine引用
            deployment.configureEngine(engine);
            //刷新global配置选项
            engine.refreshGlobalOptions();

            setInputStream(null);
        } catch (Exception e) {
            throw new ConfigurationException(e);
        }
    }

configureEngine完成的任务主要是解析server-config.wsdd服务配置。将配置文件中的各种属性(handler、globalConfiguration、service、transport……)缓存至WSDDDeployment类中。刷新global配置选项即将server-config.wsdd配置文件中globalConfiguration节点中的parameter属性集合由AxisEngine持有。

以上完成了所有初始化工作。

2)通过url打开服务:
在浏览器中打开
http://localhost:8888/axis/EchoHeaders.jws
AxisServlet的doGet方法:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (isDebug) {
            log.debug("Enter: doGet()");
        }
        PrintWriter writer = new FilterPrintWriter(response);

        try {
            AxisEngine engine = getEngine();
            ServletContext servletContext =
                    getServletConfig().getServletContext();

            String pathInfo = request.getPathInfo();
            String realpath = servletContext.getRealPath(request.getServletPath());
            if (realpath == null) {
                realpath = request.getServletPath();
            }
            boolean isJWSPage = request.getRequestURI().endsWith(".jws");
            if (isJWSPage) {
                pathInfo = request.getServletPath();
            }
            //判断是否存在查询。即server-config.wsdd的transport节点
              //配置的parameter查询条件(list/method/wsdl)
            //如url:http://localhost:8888/axis/EchoHeaders.jws?wsdl
            //如url:http://localhost:8888/services/AxisService?wsdl
            //这样doGet直接生成wsdl描述信息至浏览器端
            if (processQuery(request, response, writer) == true) {
                return;
            }
            boolean hasNoPath = (pathInfo == null || pathInfo.equals(""));
            if (!disableServicesList) {
                if(hasNoPath) {
                    reportAvailableServices(response, writer, request);
                } else if (realpath != null) {
                    MessageContext msgContext = createMessageContext(engine,request, response);
                    String url = HttpUtils.getRequestURL(request).toString();

                    msgContext.setProperty(MessageContext.TRANS_URL, url);
                    String serviceName;
                    if (pathInfo.startsWith("/")) {
                        serviceName = pathInfo.substring(1);
                    } else {
                        serviceName = pathInfo;
                    }
                    //从WSDDDeployment的services缓存中取service
                    SOAPService s = engine.getService(serviceName);
                    if (s == null) {
                        if (isJWSPage) {
                            //生成Click to see the WSDL连接的页面
                                reportCantGetJWSService(request, response, writer);
                        } else {
                            reportCantGetAxisService(request, response, writer);
                        }

                    } else {
                        reportServiceInfo(response, writer, s, serviceName);
                    }
                }
            } else {
                response.setContentType("text/html; charset=utf-8");
                writer.println("<html><h1>Axis HTTP Servlet</h1>");
                writer.println(Messages.getMessage("reachedServlet00"));
                writer.println("<p>" +
                               Messages.getMessage("transportName00",
                        "<b>" + transportName + "</b>"));
                writer.println("</html>");
            }
        } catch (AxisFault fault) {
            reportTroubleInGet(fault, response, writer);
        } catch (Exception e) {
            reportTroubleInGet(e, response, writer);
        } finally {
            writer.close();
            if (isDebug) {
                log.debug("Exit: doGet()");
            }
        }
    }


如果是JWS服务,在返回的页面中,点击“Click to see the WSDL”,则产生服务描述XML信息。
该链接对应的url为:http://localhost:8888/axis/EchoHeaders.jws?wsdl
即带有查询条件的url。
上面代码注释中已说明此类url由processQuery(request, response, writer)处理
private boolean processQuery(HttpServletRequest request,
                                 HttpServletResponse response,
                                 PrintWriter writer) throws AxisFault {
        String path = request.getServletPath();
        String queryString = request.getQueryString();
        String serviceName;
        AxisEngine engine = getEngine();
        Iterator i = this.transport.getOptions().keySet().iterator();

        if (queryString == null) {
            return false;
        }

        String servletURI = request.getContextPath() + path;
        String reqURI = request.getRequestURI();
        // chop off '/'.
        if (servletURI.length() + 1 < reqURI.length()) {
            serviceName = reqURI.substring(servletURI.length() + 1);
        } else {
            serviceName = "";
        } while (i.hasNext() == true) {
            String queryHandler = (String) i.next();
            if (queryHandler.startsWith("qs.") == true) {
                String handlerName = queryHandler.substring
                                     (queryHandler.indexOf(".") + 1).
                                     toLowerCase();
                int length = 0;
                boolean firstParamFound = false;

                while (firstParamFound == false && length < queryString.length()) {
                    char ch = queryString.charAt(length++);

                    if (ch == '&' || ch == '=') {
                        firstParamFound = true;

                        --length;
                    }
                }
                if (length < queryString.length()) {
                    queryString = queryString.substring(0, length);
                }
                if (queryString.toLowerCase().equals(handlerName) == true) {
                    if (this.transport.getOption(queryHandler).equals("")) {
                        return false;
                    }

                    try {
                        MessageContext msgContext = createMessageContext(engine,request, response);
                        Class plugin = Class.forName((String)this.transport.getOption(queryHandler));
                        Method pluginMethod = plugin.getDeclaredMethod("invoke",new Class[] {msgContext.getClass()});
                        String url = HttpUtils.getRequestURL(request).toString();
                        msgContext.setProperty(MessageContext.TRANS_URL, url);
                        msgContext.setProperty(HTTPConstants.
                               PLUGIN_SERVICE_NAME, serviceName);
                        msgContext.setProperty(HTTPConstants.PLUGIN_NAME,handlerName);
                        msgContext.setProperty(HTTPConstants.
                            PLUGIN_IS_DEVELOPMENT,
                            new Boolean(isDevelopment()));
                        msgContext.setProperty(HTTPConstants.PLUGIN_ENABLE_LIST,new Boolean(enableList));
                        msgContext.setProperty(HTTPConstants.PLUGIN_ENGINE,engine);
                        msgContext.setProperty(HTTPConstants.PLUGIN_WRITER,writer);
                        msgContext.setProperty(HTTPConstants.PLUGIN_LOG, log);
                        msgContext.setProperty(HTTPConstants.
                         PLUGIN_EXCEPTION_LOG,exceptionLog);
                        pluginMethod.invoke(plugin.newInstance(),
                         new Object[] {msgContext});
                        writer.close();
                        return true;
                    } catch (InvocationTargetException ie) {
                        reportTroubleInGet(ie.getTargetException(), response,writer);
                        return true;
                    } catch (Exception e) {
                        reportTroubleInGet(e, response, writer);
                        return true;
                    }
                }
            }
        }

        return false;
    }

以上代码主要任务是根据查询条件字符串(即wsdl),通过与server-config.wsdd中transport节点parameter属性匹配,查找对应的handler(即:org.apache.axis.transport.http.QSWSDLHandler)。并通过反射执行QSWSDLHandler的invoke方法
QSWSDLHandler:
    public void invoke(MessageContext msgContext) throws AxisFault {
        // Obtain objects relevant to the task at hand from the provided
        // MessageContext's bag.
        configureFromContext(msgContext);
        AxisServer engine = (AxisServer) msgContext.getProperty
                (HTTPConstants.PLUGIN_ENGINE);
        PrintWriter writer = (PrintWriter) msgContext.getProperty
                (HTTPConstants.PLUGIN_WRITER);
        HttpServletResponse response = (HttpServletResponse)
                msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE);
        try {
            //生成WSDL服务描述信息
            engine.generateWSDL(msgContext);
            Document wsdlDoc = (Document) msgContext.getProperty("WSDL");
            if (wsdlDoc != null) {
                try {
                    updateSoapAddressLocationURLs(wsdlDoc, msgContext);
                } catch (RuntimeException re) {
                    log.warn(
                            "Failed to update soap:address location URL(s) in WSDL.",
                            re);
                }
                response.setContentType(
                        "text/xml; charset=" +
                        XMLUtils.getEncoding().toLowerCase());
                //将描述信息XML通过writer输出至浏览器端
                reportWSDL(wsdlDoc, writer);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("processWsdlRequest: failed to create WSDL");
                }
                reportNoWSDL(response, writer, "noWSDL02", null);
            }
        } catch (AxisFault axisFault) {
            //the no-service fault is mapped to a no-wsdl error
            if (axisFault.getFaultCode().equals
                    (Constants.QNAME_NO_SERVICE_FAULT_CODE)) {
                //which we log
                processAxisFault(axisFault);

                //then report under a 404 error
                response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
                reportNoWSDL(response, writer, "noWSDL01", axisFault);
            } else {
                //all other faults get thrown
                throw axisFault;
            }
        }
    }

AxisEngine的generateWSDL方法:
    public void generateWSDL(MessageContext msgContext) throws AxisFault {
        if (log.isDebugEnabled()) {
            log.debug("Enter: AxisServer::generateWSDL");
        }

        if (!isRunning()) {
            throw new AxisFault("Server.disabled",
                                Messages.getMessage("serverDisabled00"),
                                null, null);
        }

        String  hName = null ;
        Handler h     = null ;

        // save previous context
        MessageContext previousContext = getCurrentMessageContext();

        try {
            // set active context
            setCurrentMessageContext(msgContext);

            hName = msgContext.getStrProp( MessageContext.ENGINE_HANDLER );
            if ( hName != null ) {
                if ( (h = getHandler(hName)) == null ) {
                    ClassLoader cl = msgContext.getClassLoader();
                    try {
                        log.debug( Messages.getMessage("tryingLoad00", hName) );
                        Class cls = ClassUtils.forName(hName, true, cl);
                        h = (Handler) cls.newInstance();
                    }
                    catch( Exception e ) {
                        throw new AxisFault(
                                "Server.error",
                                Messages.getMessage("noHandler00", hName),
                                null, null );
                    }
                }
                h.generateWSDL(msgContext);
            }
            else {
                hName = msgContext.getStrProp(MessageContext.TRANSPORT);
                if ( hName != null ) {
                if ((h = hr.find( hName )) != null ) {
                h.generateWSDL(msgContext);
                } else {
                log.error(Messages.getMessage("noTransport02", hName));
                }
                } else {
                defaultTransport.generateWSDL(msgContext);
                }
                hName = msgContext.getTransportName();
                SimpleTargetedChain transportChain = null;
                if ( hName != null && (h = getTransport( hName )) != null ) {
                    if (h instanceof SimpleTargetedChain) {
                        transportChain = (SimpleTargetedChain)h;
                        h = transportChain.getRequestHandler();
                        if (h != null) {
                            h.generateWSDL(msgContext);
                        }
                    }
                }

                if ((h = getGlobalRequest()) != null )
                    h.generateWSDL(msgContext);

                h = msgContext.getService();
                if (h == null) {
                    Message rm = msgContext.getRequestMessage();
                    if (rm != null) {
                        rm.getSOAPEnvelope().getFirstBody();
                        h = msgContext.getService();
                    }
                    if (h == null) {
                    ……
                    }
                }

                h.generateWSDL(msgContext);
                if ((h = getGlobalResponse()) != null )
                    h.generateWSDL(msgContext);
                if (transportChain != null) {
                    h = transportChain.getResponseHandler();
                    if (h != null) {
                        h.generateWSDL(msgContext);
                    }
                }
            }
        } catch (AxisFault e) {
            throw e;
        } catch(Exception e) {
            throw AxisFault.makeFault(e);
        } finally {
            setCurrentMessageContext(previousContext);
        }
    }

以上代码主要将生成wsdl任务交给server-config.wsdd所配置的一系列Handler,其执行顺序为
transport【requestFlow】---->globalConfiguration【requestFlow】---->service【requestFlow】---->service【responseFlow】---->globalConfiguration【responseFlow】---->transport【responseFlow】
针对jws的服务通过JWSHandler处理
org.apache.axis.handlers.JWSHandler:
    public void generateWSDL(MessageContext msgContext) throws AxisFault {
        try {
            setupService(msgContext);
        } catch (Exception e) {
            log.error( Messages.getMessage("exception00"), e );
            throw AxisFault.makeFault(e);
        }
    }

    protected void setupService(MessageContext msgContext) throws Exception {
        // FORCE the targetService to be JWS if the URL is right.
        String realpath = msgContext.getStrProp(Constants.MC_REALPATH);
        String extension = (String)getOption(OPTION_JWS_FILE_EXTENSION);
        if (extension == null) extension = DEFAULT_JWS_FILE_EXTENSION;
        
        if ((realpath!=null) && (realpath.endsWith(extension))) {
            /* Grab the *.jws filename from the context - should have been */
            /* placed there by another handler (ie. HTTPActionHandler)     */
            /***************************************************************/
            String   jwsFile = realpath;
            String rel = msgContext.getStrProp(Constants.MC_RELATIVE_PATH);

            // Check for file existance, report error with
            // relative path to avoid giving out directory info.
            File  f2 = new File( jwsFile );
            if (!f2.exists()) {
                throw new FileNotFoundException(rel);
            }

            if (rel.charAt(0) == '/') {
                rel = rel.substring(1);
            }

            int lastSlash = rel.lastIndexOf('/');
            String dir = null;
            
            if (lastSlash > 0) {
                dir = rel.substring(0, lastSlash);
            }
            
            String file = rel.substring(lastSlash + 1);
            
            String outdir = msgContext.getStrProp( Constants.MC_JWS_CLASSDIR );
            if ( outdir == null ) outdir = "." ;
            
            // Build matching directory structure under the output
            // directory.  In other words, if we have:
            //    /webroot/jws1/Foo.jws
            //
            // That will be compiled to:
            //    .../jwsOutputDirectory/jws1/Foo.class
            if (dir != null) {
                outdir = outdir + File.separator + dir;
            }
            
            // Confirm output directory exists.  If not, create it IF we're
            // allowed to.
            // !!! TODO: add a switch to control this.
            File outDirectory = new File(outdir);
            if (!outDirectory.exists()) {
                outDirectory.mkdirs();
            }
            
            if (log.isDebugEnabled())
                log.debug("jwsFile: " + jwsFile );
            
            String   jFile   = outdir + File.separator + file.substring(0, file.length()-extension.length()+1) +
                    "java" ;
            String   cFile   = outdir + File.separator + file.substring(0, file.length()-extension.length()+1) +
                    "class" ;
            
            if (log.isDebugEnabled()) {
                log.debug("jFile: " + jFile );
                log.debug("cFile: " + cFile );
                log.debug("outdir: " + outdir);
            }
            
            File  f1 = new File( cFile );

            /* Get the class */
            /*****************/
            String clsName = null ;
            //clsName = msgContext.getStrProp(Constants.MC_RELATIVE_PATH);
            if ( clsName == null ) clsName = f2.getName();
            if ( clsName != null && clsName.charAt(0) == '/' )
                clsName = clsName.substring(1);
            
            clsName = clsName.substring( 0, clsName.length()-extension.length() );
            clsName = clsName.replace('/', '.');
            
            if (log.isDebugEnabled())
                log.debug("ClsName: " + clsName );
            
            /* Check to see if we need to recompile */
            /****************************************/
            if ( !f1.exists() || f2.lastModified() > f1.lastModified() ) {
                /* If the class file doesn't exist, or it's older than the */
                /* java file then recompile the java file.                 */
                /* Start by copying the *.jws file to *.java               */
                /***********************************************************/
                log.debug(Messages.getMessage("compiling00", jwsFile) );
                log.debug(Messages.getMessage("copy00", jwsFile, jFile) );
                FileReader fr = new FileReader( jwsFile );
                FileWriter fw = new FileWriter( jFile );
                char[] buf = new char[4096];
                int    rc ;
                while ( (rc = fr.read( buf, 0, 4095)) >= 0 )
                    fw.write( buf, 0, rc );
                fw.close();
                fr.close();
                
                /* Now run javac on the *.java file */
                /************************************/
                log.debug("javac " + jFile );
                // Process proc = rt.exec( "javac " + jFile );
                // proc.waitFor();
                //获取编译器(默认:sun.tools.javac.Main,com.sun.tools.javac.main.Main)
                Compiler          compiler = CompilerFactory.getCompiler();
                
                compiler.setClasspath(ClasspathUtils.getDefaultClasspath(msgContext));
                compiler.setDestination(outdir);
                compiler.addFile(jFile);
                
                boolean result   = compiler.compile();
                
                /* Delete the temporary *.java file and check return code */
                /**********************************************************/
                (new File(jFile)).delete();
                
                if ( !result ) {
                    /* Delete the *class file - sometimes it gets created even */
                    /* when there are errors - so erase it so it doesn't       */
                    /* confuse us.                                             */
                    /***********************************************************/
                    (new File(cFile)).delete();
                    
                    Document doc = XMLUtils.newDocument();
                    
                    Element         root = doc.createElementNS("", "Errors");
                    StringBuffer message = new StringBuffer("Error compiling ");
                    message.append(jFile);
                    message.append(":\n");
                    
                    List errors = compiler.getErrors();
                    int count = errors.size();
                    for (int i = 0; i < count; i++) {
                        CompilerError error = (CompilerError) errors.get(i);
                        if (i > 0) message.append("\n");
                        message.append("Line ");
                        message.append(error.getStartLine());
                        message.append(", column ");
                        message.append(error.getStartColumn());
                        message.append(": ");
                        message.append(error.getMessage());
                    }
                    root.appendChild( doc.createTextNode( message.toString() ) );
                    throw new AxisFault( "Server.compileError",
                                         Messages.getMessage("badCompile00", jFile),
                                         null, new Element[] { root } );
                }
                ClassUtils.removeClassLoader( clsName );
                // And clean out the cached service.
                soapServices.remove(clsName);
            }
            
            ClassLoader cl = ClassUtils.getClassLoader(clsName);
            if (cl == null) {
                cl = new JWSClassLoader(clsName,
                                        msgContext.getClassLoader(),
                                        cFile);
            }
            
            msgContext.setClassLoader(cl);
            
            /* Create a new RPCProvider - this will be the "service"   */
            /* that we invoke.                                                */
            /******************************************************************/
            // Cache the rpc service created to handle the class.  The cache
            // is based on class name, so only one .jws/.jwr class can be active
            // in the system at a time.
            SOAPService rpc = (SOAPService)soapServices.get(clsName);
            if (rpc == null) {
                rpc = new SOAPService(new RPCProvider());
                rpc.setName(clsName);
                rpc.setOption(RPCProvider.OPTION_CLASSNAME, clsName );
                rpc.setEngine(msgContext.getAxisEngine());
                
                // Support specification of "allowedMethods" as a parameter.
                String allowed = (String)getOption(RPCProvider.OPTION_ALLOWEDMETHODS);
                if (allowed == null) allowed = "*";
                rpc.setOption(RPCProvider.OPTION_ALLOWEDMETHODS, allowed);
                // Take the setting for the scope option from the handler
                // parameter named "scope"
                String scope = (String)getOption(RPCProvider.OPTION_SCOPE);
                if (scope == null) scope = Scope.DEFAULT.getName();
                rpc.setOption(RPCProvider.OPTION_SCOPE, scope);
                
                rpc.getInitializedServiceDesc(msgContext);
                
                soapServices.put(clsName, rpc);                
            }
            
            // Set engine, which hooks up type mappings.
            rpc.setEngine(msgContext.getAxisEngine());
            
            rpc.init();   // ??

            // OK, this is now the destination service!
            msgContext.setService( rpc );
        }

        if (log.isDebugEnabled()) {
            log.debug("Exit: JWSHandler::invoke");
        }
    }

以上代码主要完成将jws转换成java文件,并临时存放至jwsClasses目录中,再通过jdk中的编译器sun.tools.javac.Main、com.sun.tools.javac.main.Main对java文件进行编译,将编译后的class文件存放至jwsClasses目录中,删除临时java文件,并将生成的class二进制文件加载至类加载器中。
rpc = new SOAPService(new RPCProvider());
增加Handler实例RPCProvider(继承BasicProvider)到当前handler链中
BasicProvider generateWSDL:
public void generateWSDL(MessageContext msgContext) throws AxisFault {
        if (log.isDebugEnabled())
            log.debug("Enter: BasicProvider::generateWSDL (" + this +")");

        SOAPService service = msgContext.getService();
        
        ServiceDesc serviceDesc = service.getInitializedServiceDesc(msgContext);

        try {
            // Location URL is whatever is explicitly set in the MC
            String locationUrl = msgContext.getStrProp(MessageContext.WSDLGEN_SERV_LOC_URL);

            if (locationUrl == null) {
                // If nothing, try what's explicitly set in the ServiceDesc
                locationUrl = serviceDesc.getEndpointURL();
            }

            if (locationUrl == null) {
                // If nothing, use the actual transport URL
                locationUrl = msgContext.getStrProp(MessageContext.TRANS_URL);
            }

            // Interface namespace is whatever is explicitly set
            String interfaceNamespace = msgContext.getStrProp(MessageContext.WSDLGEN_INTFNAMESPACE);

            if (interfaceNamespace == null) {
                // If nothing, use the default namespace of the ServiceDesc
                interfaceNamespace = serviceDesc.getDefaultNamespace();
            }

            if (interfaceNamespace == null) {
                // If nothing still, use the location URL determined above
                interfaceNamespace = locationUrl;
            }

            Emitter emitter = new Emitter();

            String alias = (String) service.getOption("alias");
            if (alias != null)
                emitter.setServiceElementName(alias);

            // Set style/use
            emitter.setStyle(serviceDesc.getStyle());
            emitter.setUse(serviceDesc.getUse());

            if (serviceDesc instanceof JavaServiceDesc) {
                emitter.setClsSmart(((JavaServiceDesc)serviceDesc).getImplClass(),
                                    locationUrl);
            }

            // If a wsdl target namespace was provided, use the targetNamespace.
            // Otherwise use the interfaceNamespace constructed above.
            String targetNamespace = (String) service.getOption(OPTION_WSDL_TARGETNAMESPACE);
            if (targetNamespace == null || targetNamespace.length() == 0) {
                targetNamespace = interfaceNamespace;
            }
            emitter.setIntfNamespace(targetNamespace);

            emitter.setLocationUrl(locationUrl);
            emitter.setServiceDesc(serviceDesc);
            emitter.setTypeMappingRegistry(msgContext.getTypeMappingRegistry());

            String wsdlPortType = (String) service.getOption(OPTION_WSDL_PORTTYPE);
            String wsdlServiceElement = (String) service.getOption(OPTION_WSDL_SERVICEELEMENT);
            String wsdlServicePort = (String) service.getOption(OPTION_WSDL_SERVICEPORT);
            String wsdlInputSchema = (String) service.getOption(OPTION_WSDL_INPUTSCHEMA);
            String wsdlSoapActinMode = (String) service.getOption(OPTION_WSDL_SOAPACTION_MODE);
            String extraClasses = (String) service.getOption(OPTION_EXTRACLASSES);

            if (wsdlPortType != null && wsdlPortType.length() > 0) {
                emitter.setPortTypeName(wsdlPortType);
            }
            if (wsdlServiceElement != null && wsdlServiceElement.length() > 0) {
                emitter.setServiceElementName(wsdlServiceElement);
            }
            if (wsdlServicePort != null && wsdlServicePort.length() > 0) {
                emitter.setServicePortName(wsdlServicePort);
            }
            if (wsdlInputSchema != null && wsdlInputSchema.length() > 0) {
                emitter.setInputSchema(wsdlInputSchema);
            }
            if (wsdlSoapActinMode != null && wsdlSoapActinMode.length() > 0) {
                emitter.setSoapAction(wsdlSoapActinMode);
            }

            if (extraClasses != null && extraClasses.length() > 0) {
                emitter.setExtraClasses(extraClasses);
            }

            if (msgContext.isPropertyTrue(AxisEngine.PROP_EMIT_ALL_TYPES)) {
                emitter.setEmitAllTypes(true);
            }

            Document doc = emitter.emit(Emitter.MODE_ALL);

            msgContext.setProperty("WSDL", doc);
        } catch (NoClassDefFoundError e) {
            entLog.info(Messages.getMessage("toAxisFault00"), e);
            throw new AxisFault(e.toString(), e);
        } catch (Exception e) {
            entLog.info(Messages.getMessage("toAxisFault00"), e);
            throw AxisFault.makeFault(e);
        }

        if (log.isDebugEnabled())
            log.debug("Exit: BasicProvider::generateWSDL (" + this +")");
    }

由于RPCProvider添加至handler链中,故也需完成generateWSDL任务。该任务由父类
BasicProvider完成。实际生成WSDL的任务委托至Emitter类处理

至此,整个服务部署以及WSDL描述算是梳理完毕。
分享到:
评论

相关推荐

    axis-src-1_3.zip_axis_axis-src-1_3_axis1 1.3 src_axis源码

    通过对这些模块的源码分析,我们可以了解 Axis 如何处理 SOAP 消息、解析 WSDL 文件、生成 Java 代码等关键操作。 1. Core 模块:这是 Axis 的核心部分,包括了 SOAP 消息的处理、WSDL 解析、服务注册等功能。其中...

    axis2-1.6.4源码

    Axis2是Apache软件基金会开发的一个开放源码的Web服务引擎,它是基于SOAP(简单对象访问协议)和WS-*(Web服务增强规范)标准的。这个"axis2-1.6.4源码"包含了 Axis2 的完整源代码,用于帮助开发者深入理解其内部...

    axis开发JAX-RPC webservice

    7. **服务部署**:使用Axis工具生成WSDL文件,并将其部署到Web服务器,使服务可供远程调用。 8. **客户端生成**:Axis可以从WSDL生成Java客户端代码,使得调用Web服务如同调用本地方法一样简单。 9. **异常处理**...

    axis2-1.6.2-src 官方源码包

    Axis2是Apache Axis的第二代产品,它设计的目标是提供一个更轻量级、模块化且高性能的平台,用于构建和部署Web服务。与上一代相比,Axis2增强了并发处理能力,优化了消息处理流程,并引入了服务组件模型(Service ...

    axis2 包括源码 文档

    Axis2是Apache软件基金会开发的一个开源Web服务框架,主要用于构建高度可...无论是新手还是经验丰富的开发者,都可以从 Axis2 的文档中获取所需信息,通过源码了解其实现细节,并利用二进制包快速构建和部署Web服务。

    axis2-----版本为1.6.2的webservice发布总结。

    标题中的“axis2-----版本为1.6.2的webservice发布总结”指的是Apache Axis2,这是一个用Java编写的Web服务框架,用于创建和部署Web服务。版本1.6.2是该框架的一个特定发行版,它包含了修复的错误、性能优化以及可能...

    axis2-1.7.4-src.zip 源码

    通过深入学习和分析“axis2-1.7.4-src.zip”的源码,开发者可以更好地掌握Web服务的核心技术和Apache Axis2的高级特性,为构建高效、可靠的Web服务应用打下坚实基础。同时,源码学习也能帮助开发者解决实际开发中...

    axis1.4源码

    Axis1.4源码分析 Axis是Apache软件基金会的一个开源项目,它是一个基于Java的Web服务框架,专门用于实现SOAP(简单对象访问协议)和WSDL(Web服务描述语言)。Axis1.4是该框架的一个稳定版本,为开发人员提供了构建...

    axis2-1.1-docs.zip 文档

    Axis2是Apache软件基金会开发的一个开放源码的Web服务引擎,它是基于Apache Axis1的下一代版本,用于构建和部署Web服务。此“axis2-1.1-docs.zip”文档包包含了Axis2 1.1版本的详细技术文档,帮助开发者理解和使用这...

    axis2-1.5源码

    - **服务部署**:Axis2支持多种服务部署方式,包括XML配置文件、Java Archive (JAR) 文件、Web Archive (WAR) 文件以及代码直连。 - **编码与解码**:Axis2提供了SOAP消息的编码和解码机制,能够将Java对象转换为...

    axis2源码下载~

    在进行源码分析之前,首先需要从官方网站或者其他可靠的源获取Axis2的源码。下载版本为1.5.4,这个版本可能相对较为古老,但依然包含了大量Web服务实现的核心概念和技术。解压下载的压缩包,通常会包含多个目录和...

    axis-1.4_1.jar.zip

    标题 "axis-1.4_1.jar.zip" 暗示了这是一个包含Axis 1.4版本源码的压缩文件,轴(Axis)是Apache软件基金会的一个开源项目,主要用于构建Web服务。它是一个SOAP(简单对象访问协议)引擎,允许开发者在Java平台上...

    axis.jar源码

    源码的分析对于开发者来说,不仅可以帮助理解其内部工作原理,也能提升自身在Web服务开发中的技术水平。 一、 Axis.jar概览 Axis.jar作为Web服务客户端和服务器端的核心库,包含了处理SOAP消息、WSDL(Web服务描述...

    Axis2-1.6.2.war

    【标题】"Axis2-1.6.2.war" 是Apache Axis2的一个特定版本,1.6.2,以WAR(Web Application Archive)格式提供...此外,源代码分析有助于开发者提升自己的Java和Web服务开发技能,同时为自定义和扩展Axis2提供了可能。

    axis2-1.7.9-src源代码

    Apache Axis2是一个强大的Web服务引擎,用于构建和部署Web服务,它提供了高度模块化和可扩展的架构。"src"意味着这些代码是未经编译的原始源码,用户可以深入理解其内部工作原理,进行自定义修改,或者对项目进行二...

    Axis WebService 实例源码

    Apache Axis是Java平台上的一个开源工具,专门用于创建和部署Web服务。本实例将探讨如何在Tomcat服务器上使用Axis来实现一个简单的WebService,并通过具体的源码分析加深理解。 【描述】中提到的"Tomcat+Axis+...

    Web Service Axis完整的实例

    在"myaxis"这个压缩包中,可能包含了创建和运行Web服务所需的全部文件,如服务端的Java源码、WSDL文件、部署描述符(web.xml)、以及客户端的示例代码等。用户可以通过解压并分析这些文件来学习如何设置和运行一个...

    axis开发web服务的两种典型方法示例和比较分析

    Apache Axis是一个开源的Java Web服务框架,用于创建和部署Web服务。在开始开发之前,我们需要先进行Axis的安装和配置。在本文的测试环境中,使用的JDK版本是1.5,Servlet Container是Tomcat 5.5。你可以从Apache...

    axis1.1源码

    Axis1.1源码分析 Axis是一个开源的Web服务框架,它基于Java语言,由Apache软件基金会开发并维护。在电子商务、企业应用集成(EAI)以及B2B交互等场景中,Axis扮演了关键角色,因为它允许开发者轻松地创建、部署和...

Global site tag (gtag.js) - Google Analytics