Como alterar o ponto de extremidade do URL do serviço da web?

101

Eu gerei um cliente de serviço da web usando utils JBoss (compatível com JAX-WS) usando Eclipse 'cliente de serviço da web de um wsdl'.

Portanto, a única coisa que forneci foi um url para um WSDL de serviço da web.

Agora, o provedor de serviço da web me diz para alterar o "url de acesso ao aplicativo do terminal do cliente" do serviço da web.

O que é e como mudar?

EugeneP
fonte
Você pode simplesmente recriar a coisa usando o mesmo assistente Eclipse com a nova URL?
Thilo
Diga ao provedor de serviços da web que você precisa do novo url para wsdl e, em seguida, use-o com o assistente do Eclipse para gerar novamente o cliente.
systempuntoout
@Thilo @systemputoout Gente, o problema é que eles têm A MESMA URL WSDL !! Não tenho certeza, mas me parece que no Axis você pode fornecer um URL ao invocar o serviço da web. No JAX-WS você não pode alterar o "terminal do cliente durante o tempo de execução". Alguma ideia, pessoal?
EugeneP
1
@ Pascal Thivent, @systempuntoout Cite: "URL ou endpoint para acesso ao aplicativo cliente"
EugeneP
1
Bem, meu entendimento desta frase é "os clientes acessam um terminal de serviço; a localização do terminal mudou". E isso faz sentido.
Pascal Thivent,

Respostas:

174

IMO, o provedor está dizendo para você alterar o ponto de extremidade do serviço (ou seja, onde acessar o serviço da web), não o ponto de extremidade do cliente (não entendo o que poderia ser). Para alterar o terminal de serviço, você basicamente tem duas opções.

Use o provedor de vinculação para definir o URL do endpoint

A primeira opção é alterar o BindingProvider.ENDPOINT_ADDRESS_PROPERTYvalor da propriedade de BindingProvider(todo proxy implementa javax.xml.ws.BindingProviderinterface):

...
EchoService service = new EchoService();
Echo port = service.getEchoPort();

/* Set NEW Endpoint Location */
String endpointURL = "http://NEW_ENDPOINT_URL";
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);

System.out.println("Server said: " + echo.echo(args[0]));
...

A desvantagem é que isso só funciona quando o WSDL original ainda está acessível. Não recomendado.

Use o WSDL para obter o URL do endpoint

A segunda opção é obter a URL do terminal do WSDL.

...
URL newEndpoint = new URL("NEW_ENDPOINT_URL");
QName qname = new QName("http://ws.mycompany.tld","EchoService"); 

EchoService service = new EchoService(newEndpoint, qname);
Echo port = service.getEchoPort();

System.out.println("Server said: " + echo.echo(args[0]));
...
Pascal Thivent
fonte
7
Acho que há um erro no segundo bloco de código, não deveria ser URL newEndpoint = new URL ("WSDL_URL"); na primeira linha ??
Jaime Hablutzel
3
aqui está um link para um tutorial tugdualgrall.blogspot.com/2009/02/…
shareef
12
Vale ressaltar que as wsimportferramentas modernas não geram mais código com um get[Service]Portmétodo. Em vez disso, chame get[Service]e converta o objeto resultante em a BindingProviderpara definir esses tipos de propriedades.
Christopher Schultz
Obrigado @ChristopherSchultz pela dica do wsimport! Essa def. trabalhou para nós
Cuga
1
Pelo que entendi do código stub gerado pelo cxf, a segunda opção acima altera o url wsdl, não o url do serviço. Estou esquecendo de algo?
cacert
16

Para adicionar algum esclarecimento aqui, quando você cria seu serviço, a classe de serviço usa o padrão 'wsdlLocation', que foi inserido nele quando a classe foi construída a partir do wsdl. Portanto, se você tiver uma classe de serviço chamada SomeService e criar uma instância como esta:

SomeService someService = new SomeService();

Se você olhar dentro de SomeService, verá que o construtor se parece com isto:

public SomeService() {
        super(__getWsdlLocation(), SOMESERVICE_QNAME);
}

Portanto, se você quiser que ele aponte para outra URL, basta usar o construtor que recebe um argumento de URL (há 6 construtores para definir qname e recursos também). Por exemplo, se você configurou um monitor TCP / IP local que está escutando na porta 9999 e deseja redirecionar para esse URL:

URL newWsdlLocation = new URL("http://theServerName:9999/somePath");
SomeService someService = new SomeService(newWsdlLocation);

e isso chamará este construtor dentro do serviço:

public SomeService(URL wsdlLocation) {
    super(wsdlLocation, SOMESERVICE_QNAME);
}
MattC
fonte
2
Não necessariamente. Eu tenho serviços gerados com wsdl2java do Apache CXF, e mesmo quando passamos o novo local wsdl para o construtor, suas portas ainda tentam se vincular ao local definido no tempo de compilação / geração (não deixando nenhuma escolha a não ser fazer o typecast da porta para BindingProvider e defina o novo endereço em seu mapa de contexto de solicitação.)
luis.espinal
1
@Luis - É difícil saber exatamente o que você está vendo, mas se você depurar, deverá ver a chamada na classe de provedor javax e, em seguida, vê-la tentar criar o endpoint com seu novo local wsdl (assumindo que você está usando JAX-WS 2.0 +). Então, dentro do seu serviço, a chamada getPort deve chamar super.getPort, que usa tem sua nova porta configurada em um objeto serviceDelegate. É assim que deve funcionar com javax.xml.ws.Service em JAX-WS 2.0. Eu colocaria um ponto de interrupção na super chamada e investigaria a partir daí.
MattC
0

Eu não iria tão longe quanto @Femi para alterar a propriedade de endereço existente. Você pode adicionar novos serviços à seção de definições facilmente.

<wsdl:service name="serviceMethodName_2">
  <wsdl:port binding="tns:serviceMethodNameSoapBinding" name="serviceMethodName">
    <soap:address location="http://new_end_point_adress"/>
  </wsdl:port>
</wsdl:service>

Isso não requer uma recompilação do WSDL para Java e fazer atualizações não é mais difícil do que se você usasse a opção BindingProvider (que não funcionou para mim btw).

TastyWheat
fonte
-6

Para alterar a propriedade do endereço final, edite seu arquivo wsdl

<wsdl:definitions.......
  <wsdl:service name="serviceMethodName">
    <wsdl:port binding="tns:serviceMethodNameSoapBinding" name="serviceMethodName">
      <soap:address location="http://service_end_point_adress"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
Femi
fonte
11
Em muitos casos, o WSDL é imposto a você e você não deve alterá-lo. Mais importante, de um ambiente para outro (teste vs ao vivo), a url do endpoint provavelmente mudará .. e ninguém quer ajustar o wsdl e recompilar neste caso.
Myobis