Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 862|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-3 20:49:32 | 显示全部楼层 |阅读模式

    解决思路:

    原使用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


    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&currentpage=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&currentpage=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&currentpage=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这么慢呢?

    http://www.tuicool.com/articles/quuyMv

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 04:09 , Processed in 0.081247 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表