Criando um serviço da Web SOAP com Spring
1. Visão geral
Neste tutorial, veremos como criar umSOAP-based web service com Spring Boot Starter Web Services.
2. Serviços da Web SOAP
Um serviço da Web é, em suma, um serviço independente de plataforma máquina a máquina que permite a comunicação através de uma rede.
SOAP é um protocolo de mensagens. Mensagens (solicitações e respostas) sãoXML documents over HTTP. The XML contract is defined by the WSDL (linguagem de descrição de serviços da Web). Ele fornece um conjunto de regras para definir as mensagens, ligações, operações e local do serviço.
O XML usado no SOAP pode se tornar extremamente complexo. Por esse motivo, é melhor usar SOAP com uma estrutura comoJAX-WS ou Spring, como veremos neste tutorial.
3. Estilo de desenvolvimento de contrato primeiro
Existem duas abordagens possíveis ao criar um serviço da web:Contract-LasteContract-First. Quando usamos uma abordagem de último contrato, começamos com o código Java e geramos o contrato de serviço da web (WSDL) a partir das classes. Ao usar o contrato primeiro,we start with the WSDL contract, from which we generate the Java classes.
O Spring-WS suporta apenas o estilo de desenvolvimento do contrato primeiro.
4. Configurando o Projeto Spring Boot
Vamos criar um projetoSpring Boot onde definiremos nosso servidor SOAP WS.
4.1. Dependências do Maven
Vamos começar adicionandospring-boot-starter-parent ao nosso projeto:
org.springframework.boot
spring-boot-starter-parent
2.1.2.RELEASE
A seguir, vamos adicionar as dependênciasspring-boot-starter-web-servicesewsdl4j:
org.springframework.boot
spring-boot-starter-web-services
wsdl4j
wsdl4j
4.2. O arquivo XSD
A abordagem do contrato primeiro exige que primeiro criemos o domínio (métodos e parâmetros) para o nosso serviço. Vamos usar um arquivo de esquema XML (XSD) que Spring-WS exportará automaticamente como um WSDL:
In this file, we see the format of the getCountryRequest web service request. Nós o definimos para aceitar um parâmetro do tipostring.
A seguir, definimos o formato da resposta, que contém um objeto do tipocountry.
Por fim, vemos o objetocurrency, usado dentro do objetocountry.
4.3. Gere as classes Java do domínio
Agora vamos gerar as classes Java do arquivo XSD definido na seção anterior. Ojaxb2-maven-plugin fará isso automaticamente durante o tempo de construção. O plug-in usa a ferramenta XJC como mecanismo de geração de código. O XJC compila o arquivo de esquema XSD em classes Java totalmente anotadas.
Vamos adicionar e configurar o plugin em nosso pom.xml:
org.codehaus.mojo
jaxb2-maven-plugin
1.6
xjc
xjc
${project.basedir}/src/main/resources/
${project.basedir}/src/main/java
false
Aqui observamos duas configurações importantes:
-
<schemaDirectory>$\{project.basedir}/src/main/resources</schemaDirectory> - A localização do arquivo XSD
-
<outputDirectory>$\{project.basedir}/src/main/java</outputDirectory> - Onde queremos que nosso código Java seja gerado para
Para gerar as classes Java, poderíamos simplesmente usar a ferramenta xjc em nossa instalação Java. Embora em nosso projeto Maven as coisas sejam ainda mais simples, comothe classes will be automatically generated durante a construção usual do Maven:
mvn compile
4.4. Adicione o ponto de extremidade do serviço da Web SOAP
A classe do ponto de extremidade do serviço da web SOAP tratará de todas as solicitações recebidas pelo serviço. Ele iniciará o processamento e enviará a resposta de volta.
Antes de definir isso, criamos um repositórioCountry para fornecer dados ao serviço web.
@Component
public class CountryRepository {
private static final Map countries = new HashMap<>();
@PostConstruct
public void initData() {
// initialize countries map
}
public Country findCountry(String name) {
return countries.get(name);
}
}
A seguir, vamos configurar o endpoint:
@Endpoint
public class CountryEndpoint {
private static final String NAMESPACE_URI = "http://www.example.com/springsoap/gen";
private CountryRepository countryRepository;
@Autowired
public CountryEndpoint(CountryRepository countryRepository) {
this.countryRepository = countryRepository;
}
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
@ResponsePayload
public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) {
GetCountryResponse response = new GetCountryResponse();
response.setCountry(countryRepository.findCountry(request.getName()));
return response;
}
}
Aqui estão alguns detalhes a serem observados:
-
@Endpoint - registra a classe com Spring WS como um Web Service Endpoint
-
@PayloadRoot -defines the handler method according to the namespace and localPart attributes
-
@ResponsePayload - indica que este método retorna um valor a ser mapeado para a carga de resposta
-
@RequestPayload - indica que este método aceita um parâmetro a ser mapeado a partir da solicitação de entrada
4.5. Os feijões de configuração do serviço da Web SOAP
Vamos agora criar uma classe para configurar o servlet do distribuidor de mensagem Spring para receber a solicitação:
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
// bean definitions
}
@EnableWs ativa os recursos do SOAP Web Service neste aplicativo Spring Boot. A classeWebServiceConfig estende a classe baseWsConfigurerAdapter, que configura o modelo de programação Spring-WS orientado por anotações.
Vamos criar umMessageDispatcherServlet que é usado para lidar com solicitações SOAP:
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
Definimos o objetoApplicationContext injetado deservlet para que Spring-WS possa encontrar outros beans Spring.
Também habilitamos a transformação do servlet de localização WSDL. Isso transforma o atributo de localização desoap:address no WSDL para que reflita a URL da solicitação de entrada.
Finalmente, vamos criar um objetoDefaultWsdl11Definition. Isso expõe um WSDL 1.1 padrão usando um XsdSchema. O nome do WSDL será o mesmo que o nome do bean.
@Bean(name = "countries")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("CountriesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.example.com/springsoap/gen");
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource("countries.xsd"));
}
5. Testando o projeto SOAP
Assim que a configuração do projeto for concluída, estamos prontos para testá-lo.
5.1. Compilar e executar o projeto
Seria possível criar um arquivo WAR e implementá-lo em um servidor de aplicativos externo. Em vez disso, usaremos Spring Boot, que é uma maneira mais rápida e fácil de colocar o aplicativo em funcionamento.
Primeiro, adicionamos a seguinte classe para tornar o aplicativo executável:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Observe que não estamos usando nenhum arquivo XML (como web.xml) para criar este aplicativo. É tudo puro Java.
Agora estamos prontos para construir e executar o aplicativo:
mvn spring-boot:run
Para verificar se o aplicativo está funcionando corretamente, podemos abrir o WSDL por meio da URL:http://localhost:8080/ws/countries.wsdl
5.2. Testar uma solicitação SOAP
Para testar uma solicitação, criamos o seguinte arquivo e denominamos request.xml:
Spain
Para enviar a solicitação ao nosso servidor de teste, poderíamos usar ferramentas externas como o SoapUI ou a extensão do Google Chrome Wizdler. Outra maneira é executar o seguinte comando em nosso shell:
curl --header "content-type: text/xml" -d @request.xml http://localhost:8080/ws
A resposta resultante pode não ser fácil de ler sem indentação ou quebras de linha.
Para vê-lo formatado, podemos copiar e colar no nosso IDE ou em outra ferramenta. Se tivermos instalado o xmllib2, podemos canalizar a saída do nosso comando curl paraxmllint:
curl [command-line-options] | xmllint --format -
A resposta deve conter informações sobre a Espanha:
Spain
46704314
Madrid
EUR
6. Conclusão
Neste artigo, aprendemos como criar um serviço da Web SOAP usando o Spring Boot. Também aprendemos como gerar código Java a partir de um arquivo XSD e vimos como configurar os beans Spring necessários para processar as solicitações SOAP.
O código-fonte completo está disponível emGitHub.