Announcement Announcement Module
Collapse
No announcement yet.
Bug or feature? - Migration from legacy web service framework to Spring-ws Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bug or feature? - Migration from legacy web service framework to Spring-ws

    Hi All,

    (long post i know, but I have tried to make it as consise as I can)

    I am currently the in process of exchanging the guts of our web services from Glue, a legacy proprietary framework which is no longer in development to Spring-ws. My aim is to touch as little of the current web services as possible and to tailor spring-ws to my needs.

    Almost everything has been running smoothly apart from one thing. The publication of WSDLs... I am unsure if the problem that I am having is a required constraint or a bug.

    The publication of the WSDLs almost work as we expect them to. We have xsds and they are published within a WSDL, however our problem lies with the location under which they are published. An example:

    Say we have a WSDL/Service called HelloWorld and the servlet under which it is published has the pathname "/ws/v2". I declare the bean name as "HelloWorld" and the wsdl is found under the path

    /ws/v2/HelloWorld.wsdl

    All well and good, but say I have another Service which is within another package which I want to declare? No problem (i thought), just declare the services as having the names

    net/example/billysPackage/HelloWorld

    net/example/mandysPackage/HelloWorld

    Then nothing works!

    The problem, as I see it, lies with how the MessageDispatcherServlet#getWsdlDefinition(HttpSer vletRequest)
    method trys to locate the WSDL definitions. It uses:

    WebUtils.extractFilenameFromUrlPath(request.getReq uestURI());

    to find out which wsdl is being requested and the method returns

    HelloWorld

    which it does not find within the instance variable "wsdlDefinitions"(of type Map). Both "net/example/billysPackage/HelloWorld" and "net/example/mandysPackage/HelloWorld" do exist.

    There are 3 alternative ways that I know of to get around this problem, all of which I dont like:

    1) Change the name of the declaration of the WSDL bean to net-example-mandysPackage-HelloWorld

    Problem: Works but looks crap and isnt really want we want

    2) For each package create a new servlet
    Problem:
    This just make things complicated.

    3) Redfine MessageDispatcherServlet and reimplement #getWsdlDefinition(HttpServletRequest)
    Problem:
    I have no problem with programming to an Interface, I have programmed my own endpoint for example but I have a problem with inheriting from a class that is probably likely to change and which could then create side effects.


    I am not sure if this problem I have having is a bug or a required constraint (perhaps someone could tell me this) or perhaps there is a fourth possibility that I have not thought of??

    Cheers,

    James Hayes

  • #2
    Solution to my problem (could something like it be included in the next version?)

    Well I defined a subclass of MessageDispatcherServlet to solve my problem. I dont really like to subclass but found it to be the only way. the problem code was

    Code:
    WebUtils.extractFilenameFromUrlPath(request.getRequestURI()
    from

    Code:
        protected WsdlDefinition getWsdlDefinition(HttpServletRequest request) {
            if (HttpTransportConstants.METHOD_GET.equals(request.getMethod()) &&
                    request.getRequestURI().endsWith(WSDL_SUFFIX_NAME)) {
                String fileName = WebUtils.extractFilenameFromUrlPath(request.getRequestURI());
                return (WsdlDefinition) wsdlDefinitions.get(fileName);
            }
            else {
                return null;
            }
        }
    which I the changed to:

    Code:
        /**
         * Defines the superclass to allow the definition of wsdls within
         * paths instead of just accepting those within the servlet. The reason
         * is so we avoid requiring to have 4 different servlets for each of the
         * paths e.g. net/dsb/commons, net/dsb/vhs3 etc.
         * 
         *  @return WsdlDefinition
         * 
         */
        protected WsdlDefinition getWsdlDefinition(HttpServletRequest request) {
            String contextPath = getContextPath();
            if (HttpTransportConstants.METHOD_GET.equals(request.getMethod()) &&
                    request.getRequestURI().endsWith(WSDL_SUFFIX_NAME)) {
    
                String fileName = StringUtils.removeStart(request.getRequestURI(), contextPath);
                fileName = StringUtils.removeEnd(fileName, WSDL_SUFFIX_NAME);
                 return (WsdlDefinition) wsdlDefinitions.get(fileName);
            }
            else {
                return null;
            }
        }
    
        private String getContextPath() {
            return getWebApplicationContext().getServletContext().getContextPath();
        }
    I also had to refine the initialization of the instance variable
    Code:
    wsdlDefinitions
    so it really does feel like a HACK, but it works. Any other suggestions would be great!

    Cheers

    Comment

    Working...
    X