向SOAP端点注入HttpRequest



我正在寻找一种将http头信息与SOAP消息一起转发到Spring端点的方法,以便访问IP地址等详细信息。

有关web . xml:

<servlet>
    <servlet-name>SoapHost</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
        <param-name>transformWsdlLocations</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SoapHost</servlet-name>
    <url-pattern>/ws/*</url-pattern>
</servlet-mapping>

SoapHost-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:sws="http://www.springframework.org/schema/web-services"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/web-services                       
       http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
    <!-- To detect @Endpoint -->
    <sws:annotation-driven />
    <!-- To detect @Service, @Component etc -->
    <context:component-scan base-package="za.co.mycee.soaphost" />
    <!-- To generate dynamic wsdl for SoapHost Services -->
    <sws:dynamic-wsdl 
        id="SoapHost"
        portTypeName="SoapHost" 
        locationUri="/ws/SoapHost"
        targetNamespace="http://www.mycee.co.za/SoapHost"> 
        <sws:xsd location="/WEB-INF/SoapHost.xsd" />
    </sws:dynamic-wsdl>
    <!-- Validate Request and Response -->
    <sws:interceptors>
        <bean id="MyCeeSoapHost" class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
            <property name="schema" value="/WEB-INF/SoapHost.xsd" />
            <property name="validateRequest" value="true" />
            <property name="validateResponse" value="true" />
        </bean>
    </sws:interceptors> 
</beans>
端点:

@Endpoint
public class ...Endpoint {
    @Autowired
    ...Service ...Service;
    @Autowired
    ...Service ...Service;
    @Autowired
    ...Service ...Service;
    @ResponsePayload
    @PayloadRoot(localPart = "...Request", namespace = "http://www.mycee.co.za/SoapHost")
    public ...Response do...(@RequestPayload ...Request request) {
        ...
        // get IP address here
            // get some other info from headers here
        ...

    }
}

我已经尝试添加它作为参数之一:

    @ResponsePayload
    @PayloadRoot(localPart = "...Request", namespace = "http://www.mycee.co.za/SoapHost")
public ...Response do...(
        @RequestPayload ...Request request,  
        HttpServletRequest httpServletRequest) {

,但是在XML响应中返回一个错误:"没有适配器的端点"one_answers"你的端点是用@Endpoint注释的,还是它实现了一个受支持的接口,如MessageHandler或PayloadEndpoint"

很抱歉没有直接回答您的问题,但是为什么不把过滤器放在servlet前面呢?在这个过滤器中,你可以在一些上下文对象中存储IP或任何其他信息,如ThreadLocal或类似的。

我相信SOAP不应该知道IP地址。这些是不同的抽象层。按照设计,如果需要一些元信息,SOAP将对SOAP报头进行操作。

回复topic-starter:

不,它不会破坏Spring-WS流,因为把servlet放在过滤器后面是绝对正常的。过滤器为纯javax.servlet.Filter

示例:

端点是Spring示例的稍微修改版本

@Endpoint
public class FilteredEndpoint {
    @ResponsePayload
    @PayloadRoot(localPart = "HolidayRequest", namespace = "http://mycompany.com/hr/schemas")
    public void doRespose(@RequestPayload Element request) {
        System.out.println(Context.ip.get());
    }
}

信息存储在Context对象中。Context使用ThreadLocal来保存数据。它工作是因为每个请求都由单独的线程处理

public class Context {
    public static ThreadLocal<String> ip = new ThreadLocal<String>();
}

最后过滤器

public class MyHttpFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Context.ip.set(request.getRemoteAddr());
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {}
}
web . xml和

<filter>
    <filter-name>httpfilter</filter-name>
    <filter-class>so.example.MyHttpFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>httpfilter</filter-name>
    <url-pattern>/ws/*</url-pattern>
</filter-mapping>
<servlet>
    <servlet-name>SoapHost</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
        <param-name>transformWsdlLocations</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SoapHost</servlet-name>
    <url-pattern>/ws/*</url-pattern>
</servlet-mapping>

最新更新