API do AdWords em Java sem biblioteca cliente

Introdução

O tutorial Usando a API do AdWords em Java sem a biblioteca cliente está desatualizado. Aqui você pode encontrar dicas para atualizar e melhorar seu cliente.

Dica 1: automatize o processo wsdl2java

Depois de fazer o download do arquivo wsdl do seu serviço google, adicione este código ao seu arquivo de configuração maven para extrair e criar o código java relacionado do serviço. Isso é feito pelo binário wsdl2java .

<build>
<!-- ..your stuff here.. -->
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/your_google_service.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>google</finalName>
</build>

Dica 2: cliente OAuth é uma droga

Olhando para o cliente OAuth do Google, você pode encontrar no pacote com.google.api.ads.common.lib.auth um código inválido como este:

public class OfflineCredentials {

/**
* Enum representing the API that OfflineCredentials can be used for.

*/

public static enum Api {
ADWORDS
("api.adwords.", AdWordsInternals.getInstance()),
DFA
("api.dfa.", DfaInternals.getInstance()),
DFP
("api.dfp.", DfpInternals.getInstance());

private final String propKeyPrefix;
private final Internals internals;

private Api(String propKeyPrefix, Internals internals) {
this.propKeyPrefix = propKeyPrefix;
this.internals = internals;
}

Expor a classe interna é um erro arquitetônico!

Como definir diferentes serviços? Como podemos estender uma das classes internas para adicionar / alterar algum comportamento? De jeito nenhum! Você precisa recompilar o código-fonte … etc … etc …

Se você precisar usar outra API do Google, não exclusivamente AdWords, para o processo de autenticação, você pode trapacear e usar um dos serviços abaixo, mesmo que não os use diretamente.
Uma maneira simples de fazer autenticação é:


import com.google.api.ads.common.lib.auth.OfflineCredentials;
import com.google.api.client.auth.oauth2.Credential;

Credential oAuth2Credential = new OfflineCredentials.Builder()
.forApi(OfflineCredentials.Api.DFP)
.fromFile()
.build()
.generateCredential();

No arquivo src / main / resources / ads.properties, você deve usar a nomenclatura de prefixo “api.dfp” para suas credenciais.

Dica 3: cabeçalho HTTP

Personalize o cabeçalho HTTP para passar a “Autorização: Bearer ACCESS_TOKEN”:

Map<String, List<String>> extraHeader = new HashMap<String, List<String>>();
extraHeader
.put("Authorization", Arrays.asList("Bearer " + ACCESS_TOKEN));
((BindingProvider)port).getRequestContext().put(Message.PROTOCOL_HEADERS, extraHeader);

Dica 4: solicite o cabeçalho do sabonete

Seus serviços de sabão podem exigir um cabeçalho de sabão, basta dar uma olhada em seu arquivo wsdl.

/* create and init the soap header object */
GoogleSoapHeader soapHeader = new GoogleSoapHeader();
//soapHeader.set...

/* Here the technical stuff related to cxf library: */
GoogleObjectFactory obj = new GoogleObjectFactory();
JAXBElement<GoogleSoapHeader> authToken = obj.createGoogleRequestHeader(soapHeader);

List<Header> headersList = new ArrayList<Header>();
headersList
.add(new Header(authToken.getName(), authToken.getValue(),
new JAXBDataBinding(GoogleSoapHeader.class)));
((BindingProvider)port).getRequestContext().put(Header.HEADER_LIST, headersList);

Dica 5: aproveite!

Agora você pode ligar para o serviço.