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

♀尐吖头ヾ 提交于 2021-02-18 12:18:05

问题


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 addresses 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


回答1:


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
    }
}



回答2:


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.




回答3:


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() { }
}



回答4:


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() {

    }
}


来源:https://stackoverflow.com/questions/1644225/howto-configure-spring-ws-to-publish-wsdl-files-with-a-wsdl-style-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!