参考来源:
Apache CXF实现Web Service(4) 创建一个WTP项目,并参照(1) 新建一个测试的Web Service:HelloWorld.java和其实现HelloWorldImpl.java
HelloWorld.java
package com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import org.apache.cxf.annotations.GZIP;
//@GZIP(threshold=128)
@GZIP
@WebService
public interface HelloWorld {
@WebMethod
@WebResult String sayHi(@WebParam String text);
}
HelloWorldImpl.java
package com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services;
import javax.jws.WebService;
@WebService(endpointInterface="com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services.HelloWorld",serviceName="helloService")
public class HelloWorldImpl implements HelloWorld {
public String sayHi(String name) {
String msg = "Hello " + name + "!";
return msg;
}
}
在Spring的配置中需要注意的是,我们需要引入jarws的schema
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
完整的配置文件如下:
<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://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"
default-lazy-init="true">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<bean id="helloService" class="com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services.HelloWorldImpl">
</bean>
<jaxws:endpoint implementor="#helloService" address="/HelloService"/>
</beans>
web.xml文件保持不变
<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://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"
default-lazy-init="true">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<bean id="helloService" class="com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services.HelloWorldImpl">
</bean>
<jaxws:endpoint implementor="#helloService" address="/HelloService"/>
</beans>
在Eclipse中Run As... -> Run on Server,然后在浏览器中验证是否发布成功:
我们Tomcat本地运行的端口是8080。
新建客户端测试代码,并将address设置成"http://localhost:8081/cxf/services/HelloService"
package com.cnblog.richaaaard.cxftest.spring.ws.helloworld.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
import com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services.HelloWorld;
public class Client {
public static void main(String[] args) {
JaxWsProxyFactoryBean client = new JaxWsProxyFactoryBean();
// factory.getInInterceptors().add(new LoggingInInterceptor());
// factory.getOutInterceptors().add(new LoggingOutInterceptor());
// factory.getInInterceptors().add(new GZIPInInterceptor());
// factory.getOutInterceptors().add(new GZIPOutInterceptor());
client.setServiceClass(HelloWorld.class);
client.setAddress("http://localhost:8081/cxf/services/HelloService");
HelloWorld helloworld = (HelloWorld) client.create();
System.out.println(helloworld.sayHi("Richard"));
System.exit(0);
}
}
Run As... -> Java Application
在TCPMon(关于如何使用TCPMon请查看http://www.cnblogs.com/richaaaard/p/5019438.html)中查看结果
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@Inherited
public @interface GZIP {
int threshold() default -1;
boolean force() default false;
}
这个标注有两个属性:threshold 与 force
然后查看Apache CXF 关于@GZIP的文档 (CXF Features http://cxf.apache.org/docs/featureslist.html) 与 (CXF Annotations http://cxf.apache.org/docs/annotations.html)
- threshold - the threshold under which messages are not gzipped
- force - force GZIP compression instead of negotiating via the Accept-Encoding header
GZIP is a negotiated enhancement. An initial request from a client will not be gzipped, but an Accept header will be added and if the server supports it, the response will be gzipped and any subsequent requests will be.
上面一段话的意思是:第一次请求不会发生GZIP,但是如果服务器支持,会加如到Accept头上,返回的消息会发生GZIP然后,后面发生的请求也会有GZIP。
关于threshold的定义:可以发现我们测试中的请求(request)长度(Content-Length)是232,返回(response)长度是259。
我们将threshold修改成256介于232和259之间
@GZIP(threshold=256)
//@GZIP
@WebService
public interface HelloWorld {
@WebMethod
@WebResult String sayHi(@WebParam String text);
}
请求没有发生GZIP,而响应端有GZIP
我们发现,请求(request)并没有像Apache官方文档那样说的,也会有GZIP。
发现连续的两次请求仍然没有发生GZIP。再仔细查看关于GZIP的解释,"...如果服务器支持..."
package com.cnblog.richaaaard.cxftest.spring.ws.helloworld.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
import com.cnblog.richaaaard.cxftest.spring.ws.helloworld.services.HelloWorld;
public class Client {
public static void main(String[] args) {
JaxWsProxyFactoryBean client = new JaxWsProxyFactoryBean();
// factory.getInInterceptors().add(new LoggingInInterceptor());
// factory.getOutInterceptors().add(new LoggingOutInterceptor());
// factory.getInInterceptors().add(new GZIPInInterceptor());
// factory.getOutInterceptors().add(new GZIPOutInterceptor());
client.setServiceClass(HelloWorld.class);
client.setAddress("http://localhost:8081/cxf/services/HelloService");
HelloWorld helloworld = (HelloWorld) client.create();
System.out.println(helloworld.sayHi("Richard"));
System.out.println(helloworld.sayHi("Kobe Bryant"));
System.exit(0);
}
}
compressionMinSize="256"
compression="on"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml"
发现请求(request)仍然没有发生GZIP
我们暂且放下这个问题,先将Tomcat配置文件关于compression的配置还原
在HelloWorld.java的头上修改@GZIP增加force属性,threshold仍然为256
@GZIP(force=true, threshold=256)
@WebService
public interface HelloWorld {
@WebMethod
@WebResult String sayHi(@WebParam String text);
}
请求仍然没有被压缩
[](http://images2015.cnblogs.com/blog/613455/201512/613455-20151204175354393-824266017.png
之前我们反复测试,期望第二次请求(request)可以根据服务端返回的Accept-Encoding header 自行进行GZIP压缩,我们测试代码当时设置的threhold是256,而请求的Content-Length=232。我们将threshold调整到128,去掉force属性,重启服务器再试一下(这时的Tomcat没有配置compression相关属性)。
先后运行两次独立的请求,请求(request)没有发生GZIP,这是因为客户端是不同进程的缘故
由此可见
Tomcat服务器配置的压缩机制是怎么工作的呢?
通过上面的所有测试就能得出结论,这个Interceptor并不对服务端响应消息的GZIP起任何作用,读者可以自行测试