Codigo de cliente de webservice x varios servidores => alterar URLs em tempo de execucao

Ola,

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…

Caro Edilmar,

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);

Espero ter ajudado.

Bom dia.

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:

Espero ter ajudado…