Spring-ws javaconfig位置转换

时间:2016-09-20 18:43:51

标签: java spring spring-ws

我尝试使用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

1 个答案:

答案 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的关键。当然其他豆类是必需的,但这是原始问题的要点。