我正在寻找一种方法将http标头信息和SOAP消息一起转发到Spring Endpoint,以便访问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响应中返回错误:“没有端点适配器”和“你的端点是用@Endpoint注释的,还是它实现了一个支持的接口,如MessageHandler或PayloadEndpoint”
答案 0 :(得分:4)
很抱歉没有直接回复您的问题,但为什么不在servlet之前放置过滤器?在此过滤器中,您可以将IP或任何其他信息存储在某些上下文对象中,如ThreadLocal或类似的。
我相信,SOAP应该对IP地址一无所知。这些是不同的抽象层。如果需要某些元信息,SOAP可以在SOAP Headers上运行。
回复主题启动者的评论:
不,它不会破坏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>