tomcat配置gzip压缩compressionMinSize选项无效

配置tomcat的gzip压缩功能之后,配置有个compressionMinSize选项,表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩。但是有时候你会发现这个配置并不起作用,貌似只要客户端加了Accept-Encoding: gzip, deflate,响应就是压缩的,无论响应报文体有多大,这是怎么回事呢? 查看tomcat源码,关于压缩条件控制的地方:org.apache.coyote.http11.AbstractHttp11Processor类中: // Check if sufficient length to trigger the compression long contentLength = response.getContentLengthLong(); if ((contentLength == -1) || (contentLength > compressionMinSize)) { // Check for compatible MIME-TYPE if (compressableMimeTypes != null) { return (startsWithStringArray(compressableMimeTypes, response.getContentType())); } } 可以看到,tomcat判断是否压缩的的依据是根据你响应里的Content-length来的,如果没有Content-length或者Content-length大于compressionMinSize就进行压缩。如果你的报文小于compressionMinSize,却被压缩了,那就是你的响应报文中并不含有Content-length。 Content-length可以在往外写响应流之前手动设置,如果你不设置的话,在关闭响应流的时候,如果你的响应体没超过tomcat默认缓存区大小8*1024,它也会帮你设置Content-lenth,如果超过了缓存区大小,tomcat会以Transfer-Encoding: chunked的形式返回响应。 所以如果你的设置compressionMinSize的没有生效,很有可能是 你的设置的compressionMinSize超出了tomcat的缓冲区大小,响应默认是chunked的形式返回的,这种情况是肯定压缩的。这种情况,还是有部分响应<8k的响应是不压缩的。 如果你的响应无论什么大小都被压缩了,那很有可能就是你在代码中使用了OutputStream.flush(),或者PrintWriter.flush()。使用flush()的意思是响应开始往外写了,Content-length已经来不及写了,tomcat会默认使用Transfer-Encoding: chunked形式帮你返回消息,响应肯定是要被压缩的。

2015年2月9日 · 1 分钟

HTTP中的GZIP压缩实现

HTTP协议中关于压缩传输的规定 第一:客户端传输到服务器请求中带有:Accept-Encoding:gzip, deflate 字段,向服务器表示,客户端支持的压缩格式(gzip或者deflate),如果不发送改消息头,服务器是不会压缩的。 第二:服务端在收到请求之后,如果发现请求头中含有Accept-Encoding字段,并且支持该类型的压缩,就对响应报文压缩之后返回给客户端,并且携带Content-Encoding:gzip消息头,表示响应报文是根据该格式压缩过的。 第三:客户端接收到请求之后,先判断是否有Content-Encoding消息头,如果有,按该格式解压报文。否则按正常报文处理。 服务端实现报文压缩 一般http容器都有配置实现压缩的,不需要代码实现 [nginx实现压缩,在nginx.conf中配置] #开启缓存 gzip on; #启动压缩的最小报文大小 gzip_min_length 1k; #压缩所使用的缓存 gzip_buffers 4 16k; #压缩等级1表示最快,9表示最好 gzip_comp_level 2; #压缩支持的content-Type类型 gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xml application/xml+rss; [apache实现压缩,在httpd.conf中配置] #启动deflate模块 LoadModule deflate_module modules/mod_deflate.so #配置压缩等级和压缩类型 DeflateCompressionLevel 6 AddOutputFilterByType DEFLATE text/plain text/html text/css text/javascript application/x-javascript [tomcat配置压缩] 参考《Tomcat配置gzip提高js文件下载速度》 客户端实现报文解压缩 [浏览器] 浏览器在访问一个网站的时候,默认都是带着Accept-Encoding:gzip, deflate头信息的,当收到响应的时候,如果是压缩的格式,也会自然解压。这一般不需要我们关系的。 [JAVA代码实现] java中访问一个url,一般使用apache的HttpClient,加上它的连接池管理,参考《JAVA的那些池子》 获得一个HttpClient实现类对象: HttpClient httpClient = new DefaultHttpClient(connectionManager, params); 使用它去发送http请求。这个httpclient发出去的http请求是默认不带Accept-Encoding:gzip, deflate头信息的。自然返回的响应也不会是压缩的。如果你希望实现接收压缩,进行解压缩的功能,你可以使用org.apache.http.impl.client.DecompressingHttpClient,它只是对Httpclient进行了一个包装。构造方法如下 HttpClient httpClient = new DefaultHttpClient(connectionManager, params); httpClient = new DecompressingHttpClient(httpClient); 后面就和之前发http请求,一样使用这个httpClient了,对压缩解压缩的功能,对你写代码而言是完全透明的。

2015年2月3日 · 1 分钟

AngularJS 最常用的八种功能

第一 迭代输出之ng-repeat标签 ng-repeat让table ul ol等标签和js里的数组完美结合 <ul> <li ng-repeat="person in persons"> {{person.name}} is {{person.age}} years old. </li> </ul> 你甚至可以指定输出的顺序: <li ng-repeat="person in persons | orderBy:'name'"> 第二 动态绑定之ng-model标签 任何有用户输入,只要是有值的html标签,都可以动态绑定js中的变量, 而且是动态绑定。 <input type="text" ng-model='password'> 对于绑定的变量,你可以使用{{}} 直接引用 <span>you input password is {{password}}</span> 如果你熟悉fiter,你可以很容易的按你的需要格式输出 <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span> 第三 绑定点击事件之ng-click事件 使用ng-click你可以很容易的为一个标签绑定点击事件。 <button ng-click="pressMe()"/> 当然前提是你要在$scope域中定义的自己的pressMe方法。 和传统的onclick方法不同,你甚至可以为ng-click方法传递一个对象,就像这样: <ul> <li ng-repeat="person in persons"> <button ng-click="printf(person)"/> </li> </ul> 当然还有ng-dblclick标签 第四 分支语句之ng-switch on、ng-if/ng-show/ng-hide/ng-disabled标签 分支语句让你在界面上都可以写逻辑判断。 <ul> <li ng-repeat="person in persons"> <span ng-switch on="person.sex"> <span ng-switch-when="1">you are a boy</span> <span ng-switch-when="2">you are a girl</span> </span> <span ng-if="person.sex==1">you may be a father</span> <span ng-show="person.sex==2">you may be a mother</span> <span> please input your baby's name:<input type="text" ng-disabled="!person.hasBaby"/> </span> <span> </li> </ul> 第五 校验语法之ng-trim ng-minlength ng-maxlength required ng-pattern 等标签 表单中的输入框,你可以使用上面的标签来实现对用户输入的校验。 从字面意思上你已经知道了它们的意思。 ...

2014年2月26日 · 1 分钟

AngularJS ng-repeat下使用ng-model

举例: blue:<input type="radio" value="1" ng-model="selectValue"/> red:<input type="radio" value="2" ng-model="selectValue"/> yellow: <input type="radio" value="3" ng-model="selectValue"/> 以上代码实现一个单选框功能,当你选中其中的一个单选框,可以从$scope.selectValue中得到你选中的的选项的value。 同时改变$scope.selectValue的值,也可以让界面上选中相应的单选框。 假设单选框的个数是不固定的,用ng-repeat来展现。 <table> <tr ng-repeat="row in collections"> <td> {{row.name}}: <input type="radio" value="{{row.value}}" ng-model="selectValue"/> </td> </tr> </table> 当你书写了上述代码后。你会发现点击其中的对话框,$scope.selectValue中并没有保存你选中的对应单选框的值。 这是因为处在ng-repeat之间的代码,对全局的$scope里变量的内容是不可见的,像{{row.name}}里的row,并不是全局$scope里的成员。 而是为ng-repeat创建的子scope里面的。所以要引用全局$scope里的成员,你可以使用$parent 来引用全局的$scope <table> <tr ng-repeat="row in collections"> <td> {{row.name}}: <input type="radio" value="{{row.value}}" ng-model="$parent.selectValue"/> </td> </tr> </table>

2014年2月19日 · 1 分钟

artdialog 弹出对话框怎么关闭自己

artDialog是一个基于javascript编写的对话框组件,它拥有精致的界面与友好的接口。 如果你想在弹出的对话框里,加一个自己的按钮,来关闭自己,普通对话框可以使用以下方式: //artdialog弹出对话框之后会返回一个dialog句柄 var dialog = art.dialog(content, ok, cancel) //你可以在对话框事件中通过该句柄的close方法,将对话框自己关闭。 function closeSelf(){ dialog.close(); } 如果是弹出一个iframe对话框呢?获得的对话框句柄在是父窗体里的,需要在子窗体里使用该句柄把自己关掉。 artdialog提供了框架之间的数据传递方式,你要包含artDialog.iframeTools.js方法。 var temp = {}; art.dialog.data('temp', temp); temp.dialog = art.dialog('../childframe.html'); 这样你的数据就穿越了。在childframe.html的js里,你可以使用下面的方式获取自己的窗口句柄,然后关闭自己。 function closeSelf(){ var dialog = art.dialog.data('temp'); dialog.close(); }

2014年2月18日 · 1 分钟

Tomcat配置gzip提高js文件下载速度

在tomcat的conf/server.xml文件的Connector节点中 增加如下配置: <Connector port="8080" redirectPort="8443" compression="on" compressionMinSize="10240" noCompressionUserAgents="gozilla,traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" /> 说明: compression=“on” 打开压缩功能 compressionMinSize=“10240” 启用压缩的输出内容大小,这里是10k noCompressionUserAgents=“gozilla, traviata” 对于以下的浏览器,不启用压缩; compressableMimeType=“text/html,text/xml,text/javascript,text/css,text/plain” 要压缩的文件类型MIME TYPE tomcat的压缩效果很明显,对于90多k的画图js插件 ichartjs(http://www.ichartjs.com),压缩之后只有27.8k,压缩率30% 大大提高了网站的访问速度。

2014年1月13日 · 1 分钟

使用Ajaxupload.js上传文件

ajaxupload.js 是一款使用jquery上传文件的js插件,对于简单的文件上传,足够可以应付。 该插件主要有以下几个选项: settings = { action: 'upload.php', //要提交的地址 name: 'userfile',//参数名次 data: {},//和文件一起提交的其它参数 autoSubmit: true,//选中文件后是否就提交 responseType: false,//返回的相应格式,如果是text格式的,会在响应前后加上一个<pre></pre>标签 hoverClass: 'hover', disabledClass: 'disabled', onChange: function(file, extension){//在选中了文件的时候触发 }, onSubmit: function(file, extension){//在提交的时候触发 }, onComplete: function(file, response){//上传结束的时候触发 } } 你可以使用非自动提交的方式上传文件。 代码示例如下: var ajaxupload =new AjaxUpload($("#uploadFile_button"),{ action: "upload.action", type:"POST", data:{}, autoSubmit:false, responseType:"json", name:'file', onChange: function(file, ext){ if(ext && (/^(xls)$/.test(ext) )){ alert("只支持xls格式的文件"); } }, onComplete: function(file, resp){ alert("上传成功"); } }); 以上代码绑定了id=uploadFile_button的html元素,只要点击它,就会弹出选择文件的对话框。 当选中了文件,你就可以手动触发它上传文件,当然你也可以在正式提交前设置一些参数。 ajaxupload.setData({id,"1"}); ajaxupload.submit(); 注意:当在chrome浏览器下面,该插件存在一个bug 就是重复选择相同的文件,onChange方法不会触发多次, ajaxupload.js只适合简单的文件上传的场景,并没有显示速度的功能,也无法显示进度。 虽然该插件已经很久不再更新,但是使用简单,也有一些人一直在用。 如果你需要更强大的上传功能,ajaxupload.js可能不太适合你。 ...

2014年1月11日 · 1 分钟

TOMCAT配置HTTPS和SSL并HTTP请求强转为HTTPS请求【绝对有效】

1、生成keystore文件 keytool -v -genkey -alias tomcat -keyalg RSA -keystore /home/test/my.keystore 在生成keystore的过程中,要输入一些站点信息和密码,并要求再次核对密码 2、编辑tomcat/conf/server.xml 找到对应的connector,取消注释,并且写入keystore文件路径和密码 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="/home/test/my.keystore" keystorePass="123456"/> 3、强制HTTP转HTTPS 对工程的web.xml进行修改,加入: <security-constraint> <web-resource-collection> <web-resource-name>OPENSSL</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> 4、禁用不安全的http方法 在tomcat/conf/web.xml最后加上一个节点 <security-constraint> <web-resource-collection> <url-pattern>/*</url-pattern> <http-method>PUT</http-method> <http-method>DELETE</http-method> <http-method>HEAD</http-method> <http-method>OPTIONS</http-method> <http-method>TRACE</http-method> </web-resource-collection> <auth-constraint></auth-constraint> </security-constraint>

2014年1月8日 · 1 分钟

介绍一款使用html5画图的JS开源软件ichartjs

示例代码如下: <script type="text/javascript" src="ichart.1.2.min.js" ></script> <script> $(function(){ var data = [ {name : 'UC浏览器',value : 40.0,color:'#4572a7'}, {name : 'QQ浏览器',value : 37.1,color:'#aa4643'}, {name : '欧朋浏览器',value : 13.8,color:'#89a54e'}, {name : '百度浏览器',value : 1.6,color:'#80699b'}, {name : '海豚浏览器',value : 1.4,color:'#92a8cd'}, {name : '天天浏览器',value : 1.2,color:'#db843d'}, {name : '其他',value : 4.9,color:'#a47d7c'} ]; var chart = new iChart.Pie3D({ render : 'canvasDiv', data: data, title : { text : '2012年第3季度中国第三方手机浏览器市场份额', color : '#3e576f' }, sub_option : { label : { background_color:null, sign:false,//设置禁用label的小图标 padding:'0 4', border:{ enable:false, color:'#be5985' }, fontsize:11, fontweight:600, color : '#be5985' }, }, offset_angle:-60,//逆时针偏移60度 mutex : true,//只允许一个扇形弹出 showpercent:true, border :false, decimalsnum:2, width : 800, height : 400, radius:150 });chart.draw(); }); <script> 效果如下: ...

2014年1月6日 · 1 分钟

web.xml版本差异的问题

Web.xml文件有2.3、2.4、2.5、3.0版本,其中有一个很重要的配置差异: 在Servlet 2.5 版本中可以这样配置,多个url映射到同一个servlet。具体如下。 <servlet-mapping> <servlet-name>servletName</servlet-name> <url-pattern>/index</url-pattern> <url-pattern>/login</url-pattern> </servlet-mapping> 在2.3或2.4中不能。 Servlet 2.3 <?xml version=“1.0” encoding=“UTF-8”?> <!DOCTYPE web-app PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN” “http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> … </web-app> Servlet 2.4 <?xml version=“1.0” encoding=“UTF-8”?> <web-app xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns=“http://java.sun.com/xml/ns/j2ee" xmlns:web=“http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" xsi:schemaLocation=“http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd " version=“2.4”> … </web-app> Servlet 2.5 <?xml version=“1.0” encoding=“UTF-8”?> <web-app xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns=“http://java.sun.com/xml/ns/javaee" xmlns:web=“http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id=“WebApp_ID” version=“2.5”> Servlet 3.0 <?xml version=“1.0” encoding=“utf-8”?> <web-app version=“3.0” xmlns=“http://java.sun.com/xml/ns/javaee" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

2014年1月4日 · 1 分钟