解决思路:
原使用Xfire进行webservice数据提供,严重怀疑是这个家伙造成速度慢,所以考虑的思路是以action和json的方式替换掉这个webservice.
在JAVA端要提供的数据以下面的形式提供:
/// <summary> /// 功能:绑定JS树的数据 /// 作者:黄海 /// 时间:2007-11-14 /// </summary> @RequestMapping(value="/getactiontreedata",method=RequestMethod.GET) public @ResponseBody String getactiontreedata() { return sysMenuService.getactiontreedata(); }
老框架这么写
/** * 把字符串返回到前台页面,用Ajax时使 */ private void responseTxt(String str){ try { ServletActionContext.getResponse().setContentType( "text/html;charset=utf-8"); PrintWriter pw = ServletActionContext.getResponse().getWriter(); pw.write(str); pw.flush(); pw.close(); } catch (Exception e) { e.printStackTrace(); } }
因为使用的是text/html形式返回,所以Tomcat设置了压缩后就启用了这个形式的压缩。
这个是以Spring mvc为框架搭建的提供原码,如果是Struts2的旧项目,应该也是提供String返回值,但不能使用@ResponseBody,而是使用responseText函数完成这个操作。如果获取的是一个List<Bean>,List<Map>,Bean等,建议使用fastjson转化为json字符串后进行提供数据。
提供的测试调用如下图:
考虑到json的原始数据模型,需要进行数据压缩进行传递,性能才会更好,所以参考设置一下Tomcat中的gzip压缩,不在代码层面采用GZIP压缩办法:
http://blog.csdn.net/hbcui1984/article/details/5666327
黄海成功按上面的文章配置了Tomcat启用了GZIP压缩后,检查了下我们两种输出方式的文本格式:
@ResponseBody
![](//images0.cnblogs.com/blog/8562/201305/15142330-66dcc3ae0c04417c9638829a3c81a4c3.png)
responseTxt
![](//images0.cnblogs.com/blog/8562/201305/15142510-87d832728eea461c8fe2befb2827ee08.png)
直接按上面的链接配置TOMCAT的gzip,会造成只启用了一部分,不是全都能解析,所以黄海的配置如下:
<Connector port="8400" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,text/json"/>
也就是添加了text/json格式,说明这样的也需要进行GZIP压缩处理。
然后黄海测试了在JAVA中使用HttpClient进行访问有无GZIP两种方式情况下的代码异同点:
@Test public void testGZIPHttpClient() throws IOException { //Tomct服务器端启动压缩设置的Url地址 URL url = new URL("http://10.10.3.13:8080/digital/officegetResrouceBase.action?xdkmid=D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A&ts=0¤tpage=1&pagerow=5000"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //如果这里不设置,返回的就不是gzip的数据了,也就不用解压缩了 conn.setRequestProperty("Accept-Encoding", "gzip,deflate"); //构建user-agent头 //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)"); conn.connect(); InputStream in = conn.getInputStream(); /*经实测试,可以压缩的大小由335K压缩到74KB*/ //持久化这个流,我们测试一下大小 /* String outPath="c:/2.data"; FileOutputStream out = new FileOutputStream(new File(outPath)); int chByte = in.read(); while (chByte != -1) { out.write(chByte); chByte = in.read(); } out.close(); */ //无压缩设置时启用下面的代码,关闭以 GZIPInputStream读取的代码 // BufferedReader bin = new BufferedReader(new InputStreamReader(in,"UTF-8")); //有GZIP压缩设置时启用下面的代码,关闭上面的无压缩设置代码 GZIPInputStream gzin = new GZIPInputStream(in); BufferedReader bin = new BufferedReader(new InputStreamReader(gzin, "UTF-8")); String s = null; while((s=bin.readLine())!=null) { System.out.println(s); } }
至此,JAVA端的提供服务完成,下面将开始C#客户端接收的部分。
================================================================================
================================================================================
================================================================================
在C#端调用的示例代码如下:
private void button1_Click(object sender, EventArgs e) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8400/base_db/getactiontreedata.action"); request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); MessageBox.Show(retString); }
执行结果:
c# 接收到json数据后,采用下面的办法转换为可以理解的对象进行处理:
http://www.cnblogs.com/txw1958/archive/2012/08/01/csharp-json.html
如果需要进一步优化,那么需要在JAVA端启用了GZIP压缩方式,这样一来,C#需要使用WEBCLIENT进行调用 ,也需要启用GZIP解压功能,参考下面的链接:
http://www.2cto.com/kf/201109/106076.html
======================================================================================
附上测试结果:
1、在xfire提供的webservice情况下,使用的代码:
@Test public void testWEBSERVICE() throws Exception { //在你的方法第一行加上: long a=System.currentTimeMillis(); String webservice_url="http://10.10.3.13:8080/digital/services/IResourceBaseService?wsdl"; JaxWsDynamicClientFactory dcf=null; Client client=null; Object[] objects=null; dcf = JaxWsDynamicClientFactory.newInstance(); client = dcf.createClient(webservice_url); objects = client.invoke("getResrouceBase","D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A","0",1,5000); //在最好的一行加上: System.out.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)/1000f+" 秒 "); }
执行时间:
2、换成json+gzip的方法测试代码:
@Test public void testGZIPHttpClient() throws IOException { //在你的方法第一行加上: long a=System.currentTimeMillis(); //Tomct服务器端启动压缩设置的Url地址 URL url = new URL("http://10.10.3.13:8080/digital/officegetResrouceBase.action?xdkmid=D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A&ts=0¤tpage=1&pagerow=5000"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //如果这里不设置,返回的就不是gzip的数据了,也就不用解压缩了 conn.setRequestProperty("Accept-Encoding", "gzip,deflate"); //构建user-agent头 //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)"); conn.connect(); InputStream in = conn.getInputStream(); /*经实测试,可以压缩的大小由335K压缩到74KB*/ //持久化这个流,我们测试一下大小 /* String outPath="c:/2.data"; FileOutputStream out = new FileOutputStream(new File(outPath)); int chByte = in.read(); while (chByte != -1) { out.write(chByte); chByte = in.read(); } out.close(); */ //无压缩设置时启用下面的代码,关闭以 GZIPInputStream读取的代码 // BufferedReader bin = new BufferedReader(new InputStreamReader(in,"UTF-8")); //有GZIP压缩设置时启用下面的代码,关闭上面的无压缩设置代码 GZIPInputStream gzin = new GZIPInputStream(in); BufferedReader bin = new BufferedReader(new InputStreamReader(gzin, "UTF-8")); //在最好的一行加上: System.out.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)/1000f+" 秒 "); // String s = null; // while((s=bin.readLine())!=null) // { // System.out.println(s); // } }
执行时间:
3、使用josn+no gzip的情况下:
@Test public void testGZIPHttpClient() throws IOException { //在你的方法第一行加上: long a=System.currentTimeMillis(); //Tomct服务器端启动压缩设置的Url地址 URL url = new URL("http://10.10.3.13:8080/digital/officegetResrouceBase.action?xdkmid=D4F913E3-EA88-4B06-B9FD-3F1C6AE9341A&ts=0¤tpage=1&pagerow=5000"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //如果这里不设置,返回的就不是gzip的数据了,也就不用解压缩了 //conn.setRequestProperty("Accept-Encoding", "gzip,deflate"); //构建user-agent头 //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)"); conn.connect(); InputStream in = conn.getInputStream(); /*经实测试,可以压缩的大小由335K压缩到74KB*/ //持久化这个流,我们测试一下大小 /* String outPath="c:/2.data"; FileOutputStream out = new FileOutputStream(new File(outPath)); int chByte = in.read(); while (chByte != -1) { out.write(chByte); chByte = in.read(); } out.close(); */ //无压缩设置时启用下面的代码,关闭以 GZIPInputStream读取的代码 BufferedReader bin = new BufferedReader(new InputStreamReader(in,"UTF-8")); //有GZIP压缩设置时启用下面的代码,关闭上面的无压缩设置代码 // GZIPInputStream gzin = new GZIPInputStream(in); // BufferedReader bin = new BufferedReader(new InputStreamReader(gzin, "UTF-8")); //在最好的一行加上: System.out.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)/1000f+" 秒 "); // String s = null; // while((s=bin.readLine())!=null) // { // System.out.println(s); // } }
执行时间:
测试结论:
视程序部署到哪种网络环境下,
如果是内网,TOMCAT不必启用GZIP压缩,这样速度反而更快。如果启用了GZIP压缩,那么瓶颈在于压缩和解压的时间,反而慢了下来,考虑到每次5000条的容量不算小了,这样应该算是一个结论了。
如果是互联网,TOMCAT应启用GZIP压缩,这样因为瓶颈在于网络传输。
后来黄海修改了数据的量,改用20000条做为阀值,结果如下:
webservice:
no gzip:
gzip:
发现5000的阀值偏小,20000与5000差距不大,建议采用更大的阀值,比如20000,采用NO GZIP的方式。
为什么webservice这么慢呢?