您的位置:首页 > Web前端 > JavaScript

解决在OFFICE平台传输数据慢的问题,使用GZIP+JSON替代WEBSERVICE提供数据

2013-05-15 10:54 716 查看
解决思路:

原使用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压缩办法:

/article/1682768.html

黄海成功按上面的文章配置了Tomcat启用了GZIP压缩后,检查了下我们两种输出方式的文本格式:

@ResponseBody


responseTxt



直接按上面的链接配置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数据后,采用下面的办法转换为可以理解的对象进行处理:

/article/4598446.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);
//        }
}


执行时间:



[b]测试结论:[/b]

[b]视程序部署到哪种网络环境下,[/b]

[b]如果是内网,TOMCAT不必启用GZIP压缩,这样速度反而更快。如果启用了GZIP压缩,那么瓶颈在于压缩和解压的时间,反而慢了下来,考虑到每次5000条的容量不算小了,这样应该算是一个结论了。[/b]

[b]如果是互联网,TOMCAT应启用GZIP压缩,这样因为瓶颈在于网络传输。 [/b]

[b]后来黄海修改了数据的量,改用20000条做为阀值,结果如下:[/b]

webservice:





no gzip:





gzip:





发现5000的阀值偏小,20000与5000差距不大,建议采用更大的阀值,比如20000,采用NO GZIP的方式。

为什么webservice这么慢呢?

http://www.tuicool.com/articles/quuyMv
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐