gpt4 book ai didi

java - 如何从 JAX-WS 中的 Spring 切面访问 SOAPMessage?

转载 作者:行者123 更新时间:2023-11-30 09:40:32 25 4
gpt4 key购买 nike

我有一个使用 Spring 3 IOC 的 JAX-WS WebService。我编写了一个 Spring Aspect 来处理任何异常,并确保它们在完成调用之前在 WebService 类中得到正确处理。在我的方面中,我想访问用户的区域设置(在我的 SOAP header 中定义),但我不确定如何执行此操作。

我知道我可以在处理程序中获取区域设置,但这对我来说没有帮助。我尝试注入(inject) WebServiceContext,但它始终为 null。

稍微深入一下,我就找到了 https://issues.apache.org/jira/browse/CXF-2674这似乎表明:

  1. Spring 有意不注入(inject) WebServiceContext 对象
  2. WebServiceContext 是 SOAPMessageContext 的精简包装器

但是,如果我尝试改为 Autowiring SOAPMessageContext,也会失败并显示以下错误消息:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.xml.ws.handler.soap.SOAPMessageContext com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor.webServiceContext; nested exception is java.lang.IllegalArgumentException: Can not set javax.xml.ws.handler.soap.SOAPMessageContext field com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor.webServiceContext to java.util.LinkedHashMap
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502) [spring-beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) [spring-beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282) [spring-beans-3.0.5.RELEASE.jar:]
... 21 more
Caused by: java.lang.IllegalArgumentException: Can not set javax.xml.ws.handler.soap.SOAPMessageContext field com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor.webServiceContext to java.util.LinkedHashMap
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146) [:1.6.0_29]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150) [:1.6.0_29]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63) [:1.6.0_29]
at java.lang.reflect.Field.set(Field.java:657) [:1.6.0_29]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:498) [spring-beans-3.0.5.RELEASE.jar:]
... 23 more

我想一定有一种方法可以从一个方面访问这些信息,但似乎无法弄清楚如何。

如果我尝试注入(inject)一个 SOAPMessage 对象,我会得到一个 org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.xml.soap.SOAPMessage]找到依赖项 错误消息。

有人能给我指出正确的方向吗?

谢谢,

埃里克

最佳答案

我的解决方案使用处理程序和请求范围的对象。希望将来其他人会发现这很有用

处理程序:

public class ServiceContextHandler implements SOAPHandler<SOAPMessageContext>{

/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(ServiceContextHandler.class);

/**
* Request object
*/
@Autowired
private SOAPHeaderData soapHeaderData;

/**
* Ensure that the bean has its parameters injected appropriately
*/
@PostConstruct
public void init() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}

/**
* Nothing to do on end of message
*/
public void close(MessageContext context) {
}


/**
* Nothing to do for a fault
*/
public boolean handleFault(SOAPMessageContext context) {
return true;
}

/**
* Process the message
*/
public boolean handleMessage(SOAPMessageContext context) {
// no need to bother with outbound requests
if( !((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue() )
process(context);
return true;
}

/**
* Doesn't handle any specific QNames in the header
*/
public Set<QName> getHeaders() {
return null;
}


/**
* Extract the header parameters
* @param context
*/
@SuppressWarnings("unchecked")
private void process(SOAPMessageContext context) {
// Creating the XML tree
try {
JAXBContext jc = JAXBContext.newInstance( ObjectFactory.class);
Object[] headers = context.getHeaders(new ObjectFactory().createServiceContext(null).getName(), jc, true);

// find the service context element
for( Object header : headers ){
if( (header instanceof JAXBElement<?>) && ((JAXBElement<?>)header).getValue() instanceof ServiceContextType){
// found the service context element
soapHeaderData.setServiceContext(((JAXBElement<ServiceContextType>)header).getValue());
break;
}
}

} catch (JAXBException e) {
logger.error(ExceptionUtils.getStackTrace(e));
} catch (WebServiceException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
}

SOAPHeaderData 的定义:

<!-- SOAPHeaderData -->
<bean id="soapHeaderData" class="com.cws.cs.lendingsimulationservice.header.SOAPHeaderDataImpl" scope="request">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>

其中 SOAPHeaderDataImpl 是基本的 POJO(具有不需要 CGLIB 的接口(interface))。

希望对您有所帮助!如果有任何不清楚的地方,请告诉我。

谢谢,

埃里克

关于java - 如何从 JAX-WS 中的 Spring 切面访问 SOAPMessage?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9365630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com