开发者

Howto: Configure Spring-WS to publish WSDL files with a '?WSDL' style URL?

I am trying to configure web service proxying using Mule ESB.

I am attempting to do this using Mule's WSProxyService, but after stepping through the corresponding code (with the debugger), it is clear that this class replaces endpoint addresses.

The problem is Spring-WS WSDL addresse开发者_StackOverflows are of the style http://xxxx/xxxx.wsdl, but WSProxyService expects http://xxxx/xxxx?wsdl or http://xxxx/xxxx&wsdl. It replaces the remote endpoint addresses with the local WSDL address; it cuts the remote WSDL address at the question mark i.e. '?WSDL' is intended to be chopped off, so to create the search term. But because of Spring-WS, this does not work.

To break it down:

WSProxyService ends up trying to use

http://xxxx/xxxx.wsdl

to replace

http://xxxx/xxxx

with

http://yyyy/yyyy

which fails... leading to actual web service call going direct and not through the proxy.

Has anyone ever noticed/solved this problem??

Cheers, Darren


How about a servlet filter in front of the Spring WS servlet that checks the url and the params?

In case of a match, you return the WSDL, otherwise you let the request through as if nothing happened.

This should be trivial to implement and will fill your need, if you absolutely must have the url of the WS + ?WSDL appended to it.

Here is the code:

public class WsdlQueryCompatibilityFilter implements Filter {
    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        // do nothing
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        if ("GET".equals(httpServletRequest.getMethod())
                && "wsdl".equalsIgnoreCase(httpServletRequest.getQueryString())) {
            httpServletRequest.getSession().getServletContext().getRequestDispatcher("/ws.wsdl")
                    .forward(request, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        // do nothing
    }
}


You can also use a HttpServletRequestWrapper to handle the ?wsdl extension and let the server handle the request:

@Component
public class WsdlQuestionMarkSuffixFilter implements javax.servlet.Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if ("wsdl".equalsIgnoreCase(httpRequest.getQueryString())) {
            HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest) {
                @Override
                public String getQueryString() {
                    return null;
                }

                @Override
                public String getRequestURI() {
                    return super.getRequestURI() + ".wsdl";
                }
            };
            chain.doFilter(requestWrapper, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {

    }
}


This may be applicable:

http://forum.springsource.org/showpost.php?p=101967&postcount=4

No, the ?WSDL is a way to get a WSDL of a class. In SWS, a service is not implemented as a class.


You could create a class that implements Filter, create doFilter method that intercept the request and get the URL if it ends with "wsdl", then forward the request to Spring default URL ".wsdl" cleaning up the query string. Something like this:

@Component
public class QuestionMarkFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;

        if (request.getQueryString() != null && request.getQueryString().toLowerCase().endsWith("wsdl")) {
            request.getRequestDispatcher("/your/service/here.wsdl?").forward(request, servletResponse);
        } else {
            chain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) { }

    @Override
    public void destroy() { }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜