Quando eu gero um cliente de serviço da web usando wsdl2java do CXF (que gera algo semelhante ao wsimport), via maven, meus serviços começam com códigos como este:
@WebServiceClient(name = "StatusManagement",
wsdlLocation = "c:/some_absolute_path_to_a_wsdl_file.wsdl",
targetNamespace = "http://tempuri.org/")
public class StatusManagement extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
static {
URL url = null;
try {
url = new URL("c:/some_absolute_path_to_a_wsdl_file.wsdl");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from c:/some_absolute_path_to_a_wsdl_file.wsdl");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
O caminho absoluto codificado realmente é péssimo. A classe gerada não funcionará em nenhum outro computador além do meu.
A primeira idéia é colocar o arquivo WSDL (mais tudo o que ele importa, outros WSDLs e XSDs) em algum lugar do arquivo jar e classpath. Mas queremos evitar isso. Como tudo isso foi gerado pelo CXF e JAXB com base nos WSDLs e XSDs, não vemos sentido em precisar conhecer o WSDL em tempo de execução.
O atributo wsdlLocation destina-se a substituir o local WSDL (pelo menos é o que eu li em algum lugar) e seu valor padrão é "". Como estamos usando o maven, tentamos incluir <wsdlLocation></wsdlLocation>
dentro da configuração do CXF para tentar forçar o gerador de origem a deixar o wsdlLocation em branco. No entanto, isso simplesmente ignora a tag XML porque está vazia. Nós fizemos um truque vergonhoso, realmente feio, usando <wsdlLocation>" + "</wsdlLocation>
.
Isso muda outros lugares também:
@WebServiceClient(name = "StatusManagement",
wsdlLocation = "" + "",
targetNamespace = "http://tempuri.org/")
public class StatusManagement extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
static {
URL url = null;
try {
url = new URL("" + "");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from " + "");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
Então, minhas perguntas são:
Realmente precisamos de um local WSDL, mesmo que todas as classes tenham sido geradas por CXF e JAXB? Se sim, por que?
Se realmente não precisamos da localização do WSDL, qual é a maneira correta e limpa de fazer com que o CXF não a gere e evite totalmente?
Que efeitos colaterais ruins podemos obter com esse hack? Ainda não podemos testar isso para ver o que acontece, por isso, se alguém pudesse dizer com antecedência, seria bom.
classpath:
na<wsdlLocation...
linha.Nós usamos
Em outras palavras, use um caminho relativo ao caminho de classe.
Acredito que o WSDL pode ser necessário em tempo de execução para validação de mensagens durante o empate / desempacote.
fonte
Para aqueles que usam
org.jvnet.jax-ws-commons:jaxws-maven-plugin
para gerar um cliente a partir do WSDL no momento da construção:src/main/resources
wsdlLocation
comclasspath:
wsdlLocation
com/
Exemplo:
/src/main/resources/foo/bar.wsdl
jaxws-maven-plugin
com<wsdlDirectory>${basedir}/src/main/resources/foo</wsdlDirectory>
e<wsdlLocation>/foo/bar.wsdl</wsdlLocation>
fonte
1) Em alguns casos, sim. Se o WSDL contiver itens como Políticas e direcionar o comportamento do tempo de execução, o WSDL poderá ser necessário no tempo de execução. Os artefatos não são gerados para itens relacionados à política e afins. Além disso, em alguns casos obscuros de RPC / Literal, nem todos os namespaces necessários são impressos no código gerado (por especificação). Assim, o wsdl seria necessário para eles. Casos obscuros.
2) Eu pensei que algo assim iria funcionar. Qual versão do CXF? Isso soa como um bug. Você pode tentar uma string vazia (apenas espaços). Não tenho certeza se isso funciona ou não. Dito isto, em seu código, você pode usar o construtor que pega a URL do WSDL e apenas passa nulo. O wsdl não seria usado.
3) Apenas as limitações acima.
fonte
Eu fui capaz de gerar
configurando o arquivo pom para ter um nulo para wsdlurl:
fonte
É possível que você evite usar o wsdl2java? Você pode usar imediatamente as APIs do CXF FrontEnd para chamar seu serviço da Web SOAP. O único problema é que você precisa criar seu SEI e VOs no seu cliente. Aqui está um código de exemplo.
Você pode ver o tutorial completo aqui http://weblog4j.com/2012/05/01/developing-soap-web-service-using-apache-cxf/
fonte
Atualização para CXF 3.1.7
No meu caso, eu coloquei os arquivos WSDL
src/main/resources
e adicionei esse caminho aos meus Srouces no Eclipse (clique com o botão direito do mouse em Projeto-> Caminho da construção -> Configurar caminho da construção ...-> [Guia] -> Adicionar pasta da fonte).Aqui está a aparência do meu
pom
arquivo e, como pode ser visto, NÃO háwsdlLocation
necessidade de opção:E aqui está o serviço gerado. Como pode ser visto, o URL é obtido do ClassLoader e não do caminho absoluto do arquivo
fonte
<configuration> <sourceRoot>${basedir}/src/main/java/</sourceRoot> <wsdlRoot>${basedir}/src/main/resources/</wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration>
Eu incluo todos os arquivos .wsdl no caminho da classe. Como posso especificar o local wsdl para que todos os arquivos .java gerados contenham o respectivo caminho .wsdl? Desde já, obrigado. @MazySério, a melhor resposta não está funcionando para mim. tentei cxf.version 2.4.1 e 3.0.10. e gere um caminho absoluto com wsdlLocation todas as vezes.
Minha solução é usar o
wsdl2java
comando noapache-cxf-3.0.10\bin\
com-wsdlLocation classpath:wsdl/QueryService.wsdl
.Detalhe:
fonte
A solução @Martin Devillers funciona bem. Para garantir a integridade, forneça as etapas abaixo:
src/main/resource
No arquivo pom, adicione wsdlDirectory e wsdlLocation (não perca / no início de wsdlLocation), como abaixo. Enquanto wsdlDirectory é usado para gerar código e wsdlLocation é usado em tempo de execução para criar proxy dinâmico.
Em seguida, no seu código java (com construtor no-arg):
Aqui está a parte completa da geração de código no arquivo pom, com API fluente no código gerado.
fonte