我有一个标准的jax-ws webservice设置,它使用Spring for DI和Hibernate来实现持久性。现在在Spring中,您通常会将您的请求包装在自定义过滤器中,并在Hibernate会话中执行beginTransaction()
和commit()
/ rollback()
,具体取决于执行是否顺利执行。
但是对于soap web客户端,不使用此执行链,因此不能像这样轻松地设置事务管理。当然,我也想避免在{/ p>中包装我的@WebMethod
个实现
session.beginTransaction();
try {
...
session.commit();
}
catch (RuntimeException e) {
session.rollback();
throw e;
}
所以我研究了其他可能性。显然,JSR允许配置SOAPHandler
(通过@HandlerChain
)在传入和发送传出肥皂消息之前拦截SOAP流量,但是我想知道我是否正在使用它或正在执行它错...
你们知道其他选择吗?
我走了SOAPHandler
路线,看起来效果很好:
public class SOAPServiceHandler implements SOAPHandler<SOAPMessageContext>
{
@Override
public void close(MessageContext mc)
{
}
@Override
public boolean handleFault(SOAPMessageContext smc)
{
MyHibernateUtil.rollbackTransaction();
return true;
}
@Override
public boolean handleMessage(SOAPMessageContext smc)
{
Session session = MyHibernateUtil.getCurrentSession();
Boolean outbound = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!outbound)
{
session.beginTransaction();
session.setFlushMode(FlushMode.COMMIT);
return true;
}
SOAPBody body = null;
try
{
body = smc.getMessage().getSOAPBody();
}
catch (SOAPException e)
{
}
session.flush();
session.setFlushMode(FlushMode.AUTO);
if (body == null || body.hasFault())
{
session.getTransaction().rollback();
}
else
{
session.getTransaction().commit();
}
return true;
}
@Override
public Set<QName> getHeaders()
{
return null;
}
}
这是我的applicationContext.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://jax-ws.dev.java.net/spring/core
http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.dev.java.net/spring/servlet.xsd">
<bean id="SoapServiceImpl" class="path.to.SOAPServiceImpl" />
<bean id="SoapServiceHandler" class="path.to.SOAPServiceHandler" />
<wss:binding url="/soap">
<wss:service>
<ws:service bean="#SoapServiceImpl">
<ws:handlers>
<ref bean="SoapServiceHandler" />
</ws:handlers>
</ws:service>
</wss:service>
</wss:binding>
</beans>
欢迎反馈!