`
clq9761
  • 浏览: 592490 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

CXF创建WebService实例

 
阅读更多

一、概述
1、ApacheCXF项目是由ObjectWeb Celtix和CodeHaus XFire合并成立。ObjectWeb Celtix是
由IONA公司赞助,于2005年成立的开源Java ESB产品,XFire则是业界知名的SOAP堆栈。
合并后的ApacheCXF融合该两个开源项目的功能精华,提供了实现SOA所需要的核心ESB功能框架,
包括SOA服务创建,服务路由,及一系列企业级QoS功能。

2.支持标准
(1)JAX-WS, JSR-181, SAAJ, JAX-RS
(2)SOAP 1.1, 1.2, WS-I BasicProfile, WS-Security, WS-Addressing, WS-RM, WS-Policy
(3)WSDL 1.1
(4)MTOM

3.传输方式,绑定,数据绑定,传送数据格式
(1)绑定: SOAP, REST/HTTP
(2)数据绑定: JAXB 2.x, Aegis, XMLBeans, SDO
(3)传送数据格式: XML, JSON, FastInfoset
(4)传输方式: HTTP, Servlet, JMS

 

二、基于SOAP发布webservice

 

(1)pom.xml文件中导入CXF相关包

<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-core</artifactId>
	<version>2.6.2</version>				
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-frontend-jaxws</artifactId>
	<version>2.6.2</version>				
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-transports-http</artifactId>
	<version>2.6.2</version>
</dependency>

 

(2)web.xml文件中配置

<servlet>
<servlet-name>CXFServlet</servlet-name>		
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>

 

(3)创建webService接口UserService

package com.icsshs.dmis.webservice.soap;
import javax.jws.WebParam;
import javax.jws.WebService;
import com.icsshs.dmis.webservice.soap.response.UserDTO;
/**
* JAX-WS2.0的WebService接口定义类 * 
* 使用JAX-WS2.0 annotation设置WSDL中的定义.
* 使用WSResult及其子类包裹返回结果.
* 使用DTO传输对象隔绝系统内部领域对象的修改对外系统的影响.
* 
*/
//name 指明wsdl中<wsdl:portType>元素的名称
@WebService(name = "UserService", targetNamespace = WsConstants.NS)
public interface UserService {

	//@WebService是必须的;@WebParam不是必须的。
	//如果没有@WebParam的描述,在wsdl文件内描述的方法中,参数名将变为arg0,arg1…以此类推.
	public String getUserName(@WebParam(name = "userId")String userId);
	public UserDTO getUser(@WebParam(name = "userId")String userId);
}

 

UserService接口实现类:

package com.icsshs.dmis.webservice.soap;
import javax.jws.WebService;
import com.icsshs.dmis.webservice.soap.response.UserDTO;
/**
* WebService服务端实现类.
*/
//serviceName指明WSDL中<wsdl:service>与<wsdl:binding>元素的名称,
//endpointInterface属性指向Interface类全称.
@WebService(serviceName = "UserService", 
		endpointInterface = "com.icsshs.dmis.webservice.soap.UserService",
targetNamespace = WsConstants.NS)
public class UserServiceImpl implements UserService {
	@Override
	public UserDTO getUser(String userId) {
		UserDTO dto = new UserDTO();
		dto.setId(Long.parseLong("1001"));
		dto.setLoginName("dongwq");
		dto.setName("张三");
		dto.setEmail("dongwq@qq.com");
		return dto;
	}

	@Override
	public String getUserName(String userId) {
		return "dongwq";
	}
}

 

传输的对象UserDTO类:

package com.icsshs.dmis.webservice.soap.response;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.icsshs.dmis.webservice.soap.WsConstants;
/**
* Web Service传输User信息的DTO.* 
* 只传输外部接口需要的属性.使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.* 
* @XmlRootElement指定User为XML的根元素。User类的属性默认指定映射为@XmlElement。
* @XmlElement用来定义XML中的子元素。
* @XmlType-映射一个类或一个枚举类型成一个XML Schema类型
*/
@XmlRootElement
@XmlType(name = "User", namespace = WsConstants.NS)
public class UserDTO {
	private Long id;
	private String loginName;
	private String name;
	private String email;
	// 相关get、set方法省略。
}

 

统一命名空间类定义:

public class WsConstants {
	/**项目内统一的NameSpace定义.**/
	/**wsdl2java生成客户端代码时默认按定义的namespace倒序生成包路径 **/
	public static final String NS = "http://soap.webservice.dmis.icsshs.com";
}

 

(4)在spring的applicationContext.xml文件中进行配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://cxf.apache.org/jaxws 
	http://cxf.apache.org/schemas/jaxws.xsd 
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
	default-lazy-init="true">

<description>SOAP Web Service配置</description>
<!--
1、访问接口服务:http://localhost:8080/dmis/cxf/soap/userService?wsdl
2、访问接口中的方法:
http://localhost:8080/dmis/cxf/soap/userService/getUserName?userId=aaa
或:http://localhost:8080/dmis/cxf/soap/userService/getUserName?arg0=aaa
-->
<!-- jax-ws endpoint定义  -->
<jaxws:endpoint address="/soap/userService">
<jaxws:implementor ref="userService" />
</jaxws:endpoint>
<!-- WebService的实现Bean定义 -->
<bean id="userService" class="com.icsshs.dmis.webservice.soap.UserServiceImpl" />
</beans>

 

(5)启动web应用,测试webservice应用是否发布成功。

访问:http://localhost:8080/dmis/cxf/soap/userService?wsdl

 

三、基于SOAP的客户端调用


(1)通过代理API调用,依赖于服务端的接口

/**
* 通过代理API调用,依赖于服务端的接口
*/
public static void testClientByProxy(){
	// 调用WebService
	JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
	factory.setServiceClass(UserService.class);
	factory.setAddress("http://localhost:8080/dmis/cxf/soap/userService");
	UserService service = (UserService) factory.create();
	UserDTO user = service.getUser("1001");
	System.out.println(user.getName());
}

 

(2)不依赖服务端的接口

/**
* 不依赖服务端的接口
* @throws Exception 
*/
public static void testClient() throws Exception{
	//不依赖服务器端接口来完成调用的,也就是不仅仅能调用Java的接口 
	JaxWsDynamicClientFactory clientFactory = 
		JaxWsDynamicClientFactory.newInstance(); 
	Client client = clientFactory.createClient(
			"http://localhost:8080/dmis/cxf/soap/userService?wsdl"); 
	Object[] result = client.invoke("getUserName", "1001"); 
	System.out.println(result[0]);
}

 

(3)先通过wsdl2Java生成客户端代码,再进行调用

/**
* 先通过wsdl2Java生成客户端代码,再进行调用
*/
public static void testClient2() {
	UserService_Service serivce = new UserService_Service();
	UserService impl = serivce.getUserServiceImplPort();
	String userName = impl.getUserName("1001");
	System.out.println(userName);
}

 

 

四、基于JAX-RS的方式发布WebService


(1)pom.xml文件中导入CXF相关包

<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-frontend-jaxrs</artifactId>
	<version>2.6.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.0.5</version>
</dependency>

 

(2)web.xml文件中配置,同上

<servlet>
<servlet-name>CXFServlet</servlet-name>		
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>

 

(3)创建webService接口UserJaxRsService

package com.icsshs.dmis.webservice.jaxrs;
import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.springframework.beans.factory.annotation.Autowired;
import com.icsshs.dmis.entity.bi.BiPerson;
import com.icsshs.dmis.service.bi.BiService;
import com.icsshs.dmis.webservice.soap.response.UserDTO;

@Path("/user")
public class UserJaxRsService {
	@Autowired
	private BiService biService;//业务系统类接口,省略

	@GET
	@Path("/{personCode}.xml")
	@Produces(MediaType.APPLICATION_XML)
	public UserDTO getAsXml(@PathParam("personCode") String personCode) {
		BiPerson person = biService.findBiPersonByPersonCode(personCode);
		if (person == null) {
			String message = "用户不存在(id:" + personCode + ")";
			throw buildException(Status.NOT_FOUND, message);
		}
		UserDTO dto = new UserDTO();
		dto.setName(person.getPersonName());
		dto.setLoginName(person.getR1PersonId());
		return dto;
	}

	@GET
	@Path("/{personCode}.json")
	@Produces(MediaType.APPLICATION_JSON)
	public UserDTO getAsJson(@PathParam("personCode") String personCode) {
		BiPerson person = biService.findBiPersonByPersonCode(personCode);
		if (personCode == null) {
			String message = "用户不存在(id:" + personCode + ")";
			throw buildException(Status.NOT_FOUND, message);
		}
		UserDTO dto = new UserDTO();
		dto.setName(person.getPersonName());
		dto.setLoginName(person.getR1PersonId());
		return dto;
	}

	@POST
	@Path("/addUser")
	@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public UserDTO addUser(UserDTO user) throws IOException {
		System.out.println(user);
		user.setName("jojo##12321321");
		return user;
	}

	private WebApplicationException buildException(Status status, String message){
		return new WebApplicationException(Response.status(status).entity(
			message).type(MediaType.TEXT_PLAIN).build());
	}
}

 

(4)在spring的applicationContext.xml文件中进行配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://cxf.apache.org/jaxrs 
http://cxf.apache.org/schemas/jaxrs.xsd 
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-lazy-init="true">
<description>Apache CXF的Restful Web Service配置</description>
<!-- jax-rs endpoint定义  -->
<jaxrs:server id="serviceContainer" address="/jaxrs">
<jaxrs:serviceBeans>
	<ref bean="userJaxRsService" />
</jaxrs:serviceBeans>
<jaxrs:providers>
	<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
<!-- WebService的实现Bean定义 -->
<bean id="userJaxRsService" 
	  class="com.icsshs.dmis.webservice.jaxrs.UserJaxRsService" />
</beans>

 

(5)启动web应用,测试webservice应用是否发布成功。
访问:http://localhost:8080/dmis/cxf/jaxrs?_wadl

 

五、基于JAX-RS的Restful客户端调用

(1)依赖服务端的接口,通过代理API调用 

/**
* 依赖服务端的接口
* 代理API允许你使用RESTful服务的资源类和接口。
* 代理类是客户端直接调用接口方法,使用户不需要手工创建HTTP请求。
*/
public static void testClientByProxy(){		
	UserJaxRsService store = JAXRSClientFactory
			.create("http://localhost:8080/dmis/cxf/jaxrs", 
					UserJaxRsService.class);
	System.out.println(store.getAsXml("15811006"));
}

 (2)通过HTTP客户端进行调用

/**
* HTTP客户端
* 使用org.apache.cxf.jaxrs.client.WebClient调用RESTful服务
*
*/
public static void testClientByHttp(){		
	String format = MediaType.APPLICATION_XML;
	WebClient client = WebClient.create("http://localhost:8080/dmis/cxf/jaxrs");   
	client.path("/user/15811006.xml").accept(format).type(format);   
	UserDTO user = client.get(UserDTO.class); 	    
	System.out.println("userName: " + user.getName());      
}

 

3、通过HTTP客户端进行调用,并传递对象

/**
* HTTP客户端(传递对象)	 
*
*/
public static void testClientByObject(){		
	String format = MediaType.APPLICATION_XML;
	System.out.println("testAddCategory called with format " );   
	WebClient client = WebClient.create("http://localhost:8080/dmis/cxf/jaxrs");   
	client.path("/user/addUser").accept(format).type(format);   
	UserDTO userDTO = new UserDTO();
	userDTO.setName("userName");
	userDTO.setLoginName("loginName");
	UserDTO returnUser = client.post(userDTO,UserDTO.class); 	    
	System.out.println("userName: " + returnUser.getName()
			+" lgoinName: "+returnUser.getLoginName());      
}

 

注:HTTP客户端调用时,如果不依赖于服务端接口,可通过wsdl2java或wadl2java生成客户端代码。

 

分享到:
评论
3 楼 基地分子 2015-11-12  
请问楼主:tomcat启动的时候报这样的错误这是什么原因呢?:严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cxf.jaxws.EndpointImpl--1803756460': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Z
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Z
at org.apache.cxf.common.util.SpringAopClassHelper.getRealClassInternal(SpringAopClassHelper.java:85)
at org.apache.cxf.common.util.ClassHelper.getRealClass(ClassHelper.java:55)
at org.apache.cxf.jaxws.EndpointImpl.getImplementorClass(EndpointImpl.java:210)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:385)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:329)
2 楼 基地分子 2015-11-12  
请问楼主:tomcat启动的时候报这样的错误这是什么原因呢?:严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cxf.jaxws.EndpointImpl--1803756460': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Z
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5016)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5524)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Z
at org.apache.cxf.common.util.SpringAopClassHelper.getRealClassInternal(SpringAopClassHelper.java:85)
at org.apache.cxf.common.util.ClassHelper.getRealClass(ClassHelper.java:55)
at org.apache.cxf.jaxws.EndpointImpl.getImplementorClass(EndpointImpl.java:210)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:385)
1 楼 menghuannvxia 2015-05-29  
文章很好,学习了,谢谢

相关推荐

    cxf构建webservice实例

    cxf构建webservice实例,包含客户端调用测试代码以及完整lib包,即下即用。另InterfaceController.java开始,利用velocity封装了xml与bean模版化转换,希望对大家有用。

    ssh2+cxf搭建webservice实例

    SSH2+CXF 搭建 WebService 实例详解 SSH(Struts2、Spring、Hibernate)是一个常见的 Java Web 开发框架组合,而 CXF 是一个用于构建和开发 Web 服务的开源框架。本教程将详细介绍如何在 SSH 项目中集成 CXF 来创建...

    Spring + cxf = webservice 完整实例源码免费下载

    Spring + cxf = webservice 完整实例源码免费下载 完全免费。此资源仅为文档提供。 版权为百度文档 "Spring + cxf = webservice 完整实例源码免费下载" 所有。

    基于CXF的WebService实例

    【基于CXF的WebService实例详解】 在Web服务领域,WebService是一种标准的接口定义方式,它允许不同的系统之间通过网络进行通信和数据交换。Apache CXF是一个开源的Java框架,专门用于构建和部署SOAP(简单对象访问...

    CXF-webService实例(eclipse工程,有jar包,可运行)

    CXF-webService实例(eclipse工程,有jar包,可运行) jax-ws和pojo两种方式发布

    CXF WebService实例

    在这个"CXF WebService实例"中,我们将深入探讨如何使用CXF进行Web服务的开发,以及涉及到的一些关键知识点。 首先,让我们从最基础的"HelloWorld"例子开始。在Java中,创建一个CXF WebService的"HelloWorld"示例...

    SSH整合cxf webservice实例

    下面我们将详细探讨如何在SSH框架下整合CXF,创建一个完整的Webservice实例。 1. **Spring整合CXF** Spring是SSH中的核心,负责管理整个应用的依赖注入。整合CXF时,首先需要在Spring配置文件中定义CXF的Bus实例...

    CXF-WebService实例

    使用webservice的简单实例,包含客户端代码

    cxf,webservice实例

    webservice客户端与服务端实例,可以运行,java代码编写,发布方式有两种,1为cxf集成到spring 通过tomcat 发布,2为endpoint方式以main方法运行。 提供了返回常用的基本数据类型和map,list,javabean 4个接口服务 ...

    CXF创建Webservice接口与Spring整合实例

    本文将深入探讨如何利用CXF创建带有用户认证的Web服务接口,并将其与SSH(Spring、Struts、Hibernate)框架整合。 首先,让我们了解一下CXF创建Web服务的基本步骤: 1. **设置项目环境**:确保你的开发环境中已经...

    CXF实现WebService详解实例

    本篇文章将详细探讨如何使用CXF实现WebService,并通过实例进行深入解析。 **一、CXF简介** Apache CXF是一个强大的开源工具,它提供了多种方式来创建和使用Web服务,包括SOAP、RESTful API、XML以及JSON等。CXF...

    spring整合cxf发布webservice实例

    将下载的demo(包括serviceserverdemo及serviceclientdemo,bat文件在serviceclientdemo的src下)导入eclipse即可运行使用,编译时可能需要修改jdk版本,如果导入有错,可新建web项目,按所下载demo的结构搭建即可,...

    CXF创建webservice服务端.doc

    如果项目中使用了Spring框架,那么可以将CXF服务配置到Spring的ApplicationContext中,通过Spring的依赖注入管理服务实例。这样可以方便地与其他Spring管理的组件进行交互,进一步提高代码的可维护性和可测试性。 ...

    Java通过Cxf创建webService接口.docx

    4. 启动服务:然后,你需要创建一个启动类,如`StartService`,用于实例化服务类并发布服务。在这里,我们使用`JaxWsServerFactoryBean`来配置服务地址和服务类,并启动服务。 ```java public class StartService {...

    使用CXF开发WebService简单实例

    这个实例展示了CXF如何简化Web服务的开发,使得我们可以快速地创建服务并进行调用。通过理解这个基础实例,开发者可以进一步探索CXF的高级特性,如WS-Security、MTOM、XOP等,以满足更复杂的企业级需求。 在压缩包...

    cxf+spring webService实例

    在这个"CXF+Spring WebService实例"中,我们将深入探讨如何利用这两个工具来创建、发布和消费Web服务。 CXF全称为CXF CXF (CXF XFire + XWS), 是一个开源的Java框架,它支持多种Web服务标准,如SOAP、WSDL、WS-...

    php调用webservice及myeclipse创建webservice实例

    在提供的压缩包文件中,"php+webservice"很可能包含了PHP代码文件,用于演示如何调用由MyEclipse创建的Web服务。这些文件可能包括一个PHP脚本,该脚本使用SoapClient类与Web服务交互,以及MyEclipse项目中的源代码和...

    cxf 开发webservice客户端

    总结,利用CXF开发Web服务客户端涉及了从生成客户端代码、创建实例到测试的整个流程。了解这些知识点,能够帮助我们更高效地构建和测试与Web服务交互的应用程序。在实际项目中,还需要根据具体需求进行相应的调整和...

    CXF开发webservice服务端

    本文将详细介绍如何使用Apache CXF框架来构建WebService服务器端,并通过实例演示整个过程。 #### 二、所需工具与环境 在开始之前,确保已准备好以下工具和资源: 1. **Apache CXF**:版本为2.2.6。 2. **Spring WS...

Global site tag (gtag.js) - Google Analytics