我尝试使用Java-Config设置webservices项目(目前是SOAP,但最终会添加REST)。不幸的是,我还没有能够自动公开WSDL(据推测,Spring可以基于XSD生成它并公开它)。
我发现的唯一文档在定义servlet(web.xml)时使用xml配置。
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
如何使用Java-config实现此目的?
WebApplicationInitializer
public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* {@inheritDoc}
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {WebSecurityConfiguration.class};
}
/**
* {@inheritDoc}
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {WebServicesConfiguration.class};
}
/**
* {@inheritDoc}
*/
@Override
protected String[] getServletMappings() {
// get all mappings
return new String[] { "/" };
}
WebServicesConfiguration
@EnableWs
@Configuration
@ComponentScan("com.questsoftware")
public class WebServicesConfiguration extends WsConfigurationSupport {
@Bean
public XsdSchema schema() {
return new SimpleXsdSchema(new ClassPathResource("lookup.xsd"));
}
@Bean
public DefaultWsdl11Definition defaultWsdl11Definition() {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setTargetNamespace("http://com/[mycompany]/Lookup");
wsdl11Definition.setPortTypeName("Lookup");
wsdl11Definition.setLocationUri("/Lookup");
wsdl11Definition.setSchema(schema());
return wsdl11Definition;
}
要清楚 - 我还有一个WebApplicationConfiguration(REST) - 但我还没有在WebApplicationInitializer中添加它(首先遇到这个问题)。
WebApplicationConfiguration
@EnableWebMvc
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Configuration
@ComponentScan("com.mycompany")
public class WebApplicationConfiguration extends WebMvcConfigurerAdapter {
/**
* Defines {@link JdbcTemplate} as a Spring managed bean.
*
* @return
*/
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
@Bean
public DataSource dataSource() {
...
return dataSource;
}
/**
* Defines a {@link ViewResolver} as a Spring managed bean.
*
* @return the viewResolver
*/
@Bean
public ViewResolver viewResolver() {
final InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages");
resolver.setSuffix(".jsp");
return resolver;
}
/**
* Registers resource handlers with Spring.
*
* @param registry the {@link ResourceHandlerRegistry}
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/view/**").addResourceLocations("/view/");
}
参考
http://docs.spring.io/spring-ws/sites/2.0/reference/html/server.html#server-automatic-wsdl-exposure
答案 0 :(得分:0)
我能够提出一个解决方案,但我不完全确定它是'正确'还是'首选'方式。
我遵循了教程并简单地在基于java-config的WebApplicationConfiguration中定义了bean,这些bean是在基于xml的教程配置中定义的。 - 我的理解是,确实没有潜在的差异,你只需要将bean添加到Spring容器中,这样Spring就可以发挥它的魔力。
我已通过以下更改更新了上述代码:
<强> WebApplicationConfiguration 强>
添加了以下bean
/**
* Defines the {@link SaajSoapMessageFactory} as a Spring managed bean.
*
* Note: we need a Soap implementation of a MessageFactory to create soap messages in Spring-WS.
*
* @return the messageFactory
*/
@Bean
public SaajSoapMessageFactory messageFactory() {
return new SaajSoapMessageFactory();
}
/**
* Defines the {@link WebServiceMessageReceiverHandlerAdapter} as a Spring managed bean.
*
* Note: We need to add this bean to the context in order for the DispatcherServlet to delegate to a MessageDispatcher
* (as opposed to Controllers). The MessageDispatcher is necessary for Spring-WS.
*
* @return the webServiceMessageReceiverHandlerAdapter
*/
@Bean
public WebServiceMessageReceiverHandlerAdapter webServiceMessageReceiverHandlerAdapter() {
WebServiceMessageReceiverHandlerAdapter adapter = new WebServiceMessageReceiverHandlerAdapter();
adapter.setMessageFactory(messageFactory());
return adapter;
}
/**
* Defines the {@link SimpleUrlHandlerMapping} as a Spring managed bean.
*
* Note: In order for the DispatcherServlet to handle SOAP message, we were forced to add the {@link WebServiceMessageReceiverHandlerAdapter}
* to the context. By explicitely adding that bean to the context, we are now forced to also add this bean to handle REST messages.
*
* @return the simpleUrlHandlerMapping
*/
@Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
simpleUrlHandlerMapping.setDefaultHandler(messageDispatcher());
Properties urlProperties = new Properties();
urlProperties.put("Lookup.wsdl", "Lookup");
simpleUrlHandlerMapping.setMappings(urlProperties);
simpleUrlHandlerMapping.setDefaultHandler(messageDispatcher());
return simpleUrlHandlerMapping;
}
/**
* Defines the {@link SoapMessageDispatcher} as a Spring managed bean.
*
* Note: Dispatches SOAP messages.
*
* @return the messageDispatcher
*/
@Bean
public SoapMessageDispatcher messageDispatcher() {
return new SoapMessageDispatcher();
}
/**
* Defines the {@link SimpleControllerHandlerAdapter} as a Spring managed bean.
*
* Note: In order for the DispatcherServlet to handle SOAP messages, we were forced to add the {@link WebServiceMessageReceiverHandlerAdapter}
* to the context. By explicitely adding that bean to the context, the default adapters were not automatically added to handle
* standard MVC Controllers. We must add this bean to do that.
*
* @return the simpleControllerHandlerAdapter
*/
@Bean
public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
return new SimpleControllerHandlerAdapter();
}
<强> WebServicesConfiguration 强>
删除了@ComponentScan(“com.mycompany”) - WebApplicationConfiguration已经为我做了这个,实际上是接收了这个配置中的所有bean。
添加了以下bean
@Bean
public WsdlDefinitionHandlerAdapter wsdlDefinitionHandlerAdapter() {
WsdlDefinitionHandlerAdapter wsdlDefinitionHandlerAdapter = new WsdlDefinitionHandlerAdapter();
wsdlDefinitionHandlerAdapter.setTransformLocations(true);
return wsdlDefinitionHandlerAdapter;
}
注意!!! - 在WsdlDefinitionHandlerAdapter的bean定义中,我为transformLocations调用setter。这与WebApplicationConfig中的urlMapping一起是公开WSDL的关键。当然其他豆类是必需的,但这是原始问题的要点。