Tenho uma aplicacao Swing cliente de um servidor que roda varios webservices.
Uso o NetBeans7.2 e com a opcao de gerar cliente de webservice a partir de WSDL fica muito simples.
Contudo, este servidor1 esta sobrecarregado e estou montando o servidor2, exatamente com os mesmos webservices.
O problema é que a geracao de cliente a partir de WSDL amarrou o codigo cliente as URLs do servidor1.
Para eu conseguir acessar o servidor2, a unica opcao (do ponto de vista visual de IDE) é alterar a propriedade da URL e mandar gerar os stubs novamente em tempo de desenvolvimento.
Eu gostaria de saber se existe uma forma de setar, em tempo de execucao, as URLs para o servidor1 ou para o servidor2, e manter o resto da aplicacao funcional, haja vista que a funcionalidade do lado servidor sera exatamente a mesma.
Por enquanto, a unica alternativa que vi foi gerar o XML SOAP na mao e usar o HttpURLConnection pra comunicar. O problema é que terei que mexer no cliente inteiro se for fazer isso…
Desconheço qual a implementação de web service voce esta utilizando, a pouco tempo eu utilizei a jax-ws, com esta implementação você consegue fazer um factory sem depender da ide, utilizando a classe javax.xml.ws.Service, assim você recupera uma implementação do web service baseada em proxy, não posto a solução completa devido a ser codigo proprietario.
URL wsdlURL = new URL("caminho do wsdl");
QName serviceName = new QName("caminho do serviço", "nome do serviço");
QName portName = new QName("caminho do serviço","porta do serviço");
//Recupera uma instancia do service, porém ainda não é a implementação final, é necessario recuperar a porta do service
Service service = Service.create(wsdlURL, serviceName);
//Recupera a porta do service, esta sim trata-se da implementação do web service, esta implementação é baseada em proxy, para que seja possivel recuperar esta porta é necessario passar o parametro interface, sendo esta a interface do web service, que contenha a anotação @WebService
T port = (T) service.getPort(portName, interface.class);
Não tenho muito conhecimento em WS, mas acho que tem outra questão a ser considerada.
Porque é necessário apontar para um ou outro servidor? Porque não realizar um balanceamento de carga sem fidelização? Isso não seria melhor para as aplicações clientes?
Em relação à configuração de URL em tempo de execução, tive o mesmo problema e resulvi de uma forma simples (não sei se é a melhor forma).
No Jboss defino um arquivo com as propriedades da JVM. Quando O servidor sobe as propriedades sobem junto. Nesta propriedade coloco o endereço do webservice.
Na aplicação retiro da anotation o endereço do web service e coloco o endereço na mão, recuperando dessa propriedade que criei no arquivo.
@WebServiceClient(name = "Sessoes", targetNamespace = "http://tempuri.org/")
public class Sessoes
extends Service
{
private final static URL SESSOES_WSDL_LOCATION;
private final static Logger logger = Logger.getLogger(org.tempuri.Sessoes.class.getName());
public static final String PROPRIEDADE_WSDL_LOCATION = "wsdl.location";
public static final String WSDL_LOCATION;
static {
WSDL_LOCATION = System.getProperty(PROPRIEDADE_WSDL_LOCATION);
URL url = null;
try {
URL baseUrl;
baseUrl = org.tempuri.Sessoes.class.getResource(".");
url = new URL(baseUrl, WSDL_LOCATION);
} catch (MalformedURLException e) {
logger.error("Failed to create URL for the wsdl Location: " + WSDL_LOCATION + ", retrying as a local file");
throw new RuntimeException(new DeveloperMessage("Não foi possível recuperar URL Valida no bloco estático: " + url), e.getCause()){};
}
SESSOES_WSDL_LOCATION = url;
}
public Sessoes(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public Sessoes() {
super(SESSOES_WSDL_LOCATION, new QName("http://tempuri.org/", "Sessoes"));
}
...
E aqui o arquivo de propriedades, que fica na pasta deploy: