Filter 起航 编程式配置 压缩响应 日志过滤器
【编程式配置】可以用web.xml配置替换
@WebListener
public class FilterListenerConfigurator implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent e) {
ServletContext context = e.getServletContext();
FilterRegistration.Dynamic registration = context.addFilter("requestLogFilter",new RequestLogFilter());
registration.addMappingForUrlPatterns(null,false,"/*"); registration = context.addFilter("compressionFilter",new CompressionFilter());
registration.setAsyncSupported(true);//相当于xml <async-supported>
registration.addMappingForUrlPatterns(null,false,"/*");
}
}
【日志过滤器】
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
Instant time = Instant.now();
StopWatch timer = new StopWatch();
try {
timer.start();
filterChain.doFilter(req, resp);
}finally {
timer.stop();
HttpServletRequest in = (HttpServletRequest) req;
HttpServletResponse out = (HttpServletResponse) resp;
String length = out.getHeader("Content-Length");
if (length == null || length.length()==0){
length = "-";
}
System.out.println(in.getRemoteAddr() + " - - ["+time+"]"+" \""+in.getMethod()+
" "+in.getRequestURI()+" "+in.getProtocol()+"\" "+out.getStatus()+" "+length+
" "+timer);
}
}
【压缩过滤器】
public class CompressionFilter implements Filter
{
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
if(((HttpServletRequest)request).getHeader("Accept-Encoding")
.contains("gzip"))
{
System.out.println("Encoding requested.");
((HttpServletResponse)response).setHeader("Content-Encoding", "gzip");
ResponseWrapper wrapper =
new ResponseWrapper((HttpServletResponse)response);
try
{
chain.doFilter(request, wrapper);
}
finally
{
try {
wrapper.finish();
} catch(Exception e) {
e.printStackTrace();
}
}
}
else
{
System.out.println("Encoding not requested.");
chain.doFilter(request, response);
}
} private static class ResponseWrapper extends HttpServletResponseWrapper
{
private GZIPServletOutputStream outputStream;
private PrintWriter writer; public ResponseWrapper(HttpServletResponse request)
{
super(request);
} @Override
public synchronized ServletOutputStream getOutputStream()
throws IOException
{
if(this.writer != null)
throw new IllegalStateException("getWriter() already called.");
if(this.outputStream == null)
this.outputStream =
new GZIPServletOutputStream(super.getOutputStream());
return this.outputStream;
} @Override
public synchronized PrintWriter getWriter() throws IOException
{
if(this.writer == null && this.outputStream != null)
throw new IllegalStateException(
"getOutputStream() already called.");
if(this.writer == null)
{
this.outputStream =
new GZIPServletOutputStream(super.getOutputStream());
this.writer = new PrintWriter(new OutputStreamWriter(
this.outputStream, this.getCharacterEncoding()
));
}
return this.writer;
} @Override
public void flushBuffer() throws IOException
{
if(this.writer != null)
this.writer.flush();
else if(this.outputStream != null)
this.outputStream.flush();
super.flushBuffer();
} @Override
public void setContentLength(int length) { } @Override
public void setContentLengthLong(long length) { } @Override
public void setHeader(String name, String value)
{
if(!"content-length".equalsIgnoreCase(name))
super.setHeader(name, value);
} @Override
public void addHeader(String name, String value)
{
if(!"content-length".equalsIgnoreCase(name))
super.setHeader(name, value);
} @Override
public void setIntHeader(String name, int value)
{
if(!"content-length".equalsIgnoreCase(name))
super.setIntHeader(name, value);
} @Override
public void addIntHeader(String name, int value)
{
if(!"content-length".equalsIgnoreCase(name))
super.setIntHeader(name, value);
} public void finish() throws IOException
{
if(this.writer != null)
this.writer.close();
else if(this.outputStream != null)
this.outputStream.finish();
}
} private static class GZIPServletOutputStream extends ServletOutputStream
{
private final ServletOutputStream servletOutputStream;
private final GZIPOutputStream gzipStream; public GZIPServletOutputStream(ServletOutputStream servletOutputStream)
throws IOException
{
this.servletOutputStream = servletOutputStream;
this.gzipStream = new GZIPOutputStream(servletOutputStream);
} @Override
public boolean isReady()
{
return this.servletOutputStream.isReady();
} @Override
public void setWriteListener(WriteListener writeListener)
{
this.servletOutputStream.setWriteListener(writeListener);
} @Override
public void write(int b) throws IOException
{
this.gzipStream.write(b);
} @Override
public void close() throws IOException
{
this.gzipStream.close();
} @Override
public void flush() throws IOException
{
this.gzipStream.flush();
} public void finish() throws IOException
{
this.gzipStream.finish();
}
}
}
Filter 起航 编程式配置 压缩响应 日志过滤器的更多相关文章
- Spring4.0编程式定时任务配置
看过很多定时调度的配置,大多使用XML配置,觉得比较麻烦,也比较老套.这里介绍一种基于spring4.0注解编程式配置定时任务,简单清晰,使用方便.. 至于引入spring相关jar这里不多说,直接切 ...
- 事务之三:编程式事务、声明式事务(XML配置事务、注解实现事务)
Spring2.0框架的事务处理有两大类: JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还无法保证数据操作的原子性(要么全部生效,要么全部无效),如: Jd ...
- SpringMVC 解析(四)编程式路由
多数情况下,我们在使用Spring的Controller时,会使用@RequestMapping的形式把请求按照URL路由到指定方法上.Spring还提供了一种编程的方式去实现请求和路由方法之间的路由 ...
- spring 事物(二)—— 编程式事物实现与扩展
简介 使用TransactionTemplate 不需要显式地开始事务,甚至不需要显式地提交事务.这些步骤都由模板完成.但出现异常时,应通过TransactionStatus 的setRollback ...
- 全面分析 Spring 的编程式事务管理及声明式事务管理
开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...
- Spring学习8-Spring事务管理(编程式事务管理)
一.Spring事务的相关知识 1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一 ...
- spring 编程式事务管理和声明式事务管理
编程式事务管理 Spring 的编程式事务管理概述 在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择.用过 Hibernate 的人都知道,我们需要在代码中显式调用be ...
- 【spring 6】Spring和Hibernate的整合:编程式事务
一.编程式事务简介 在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择.用过 Hibernate 的人都知道,我们需要在代码中显式调用beginTransaction() ...
- 全面分析 Spring 的编程式事务管理及声明式事务管理--转
开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...
随机推荐
- thinkphp5 如何监听sql?
第一步 在database配置文件中开启 // 是否需要进行SQL性能分析'sql_explain' => true, 第二步 在需要测试的sql前,使用以下demo Db::listen(fu ...
- js原生事件系统与坐标系统
今天来实现一个可兼容的js原生拖拽,在这里面我将会讲到: 1.封装兼容性的事件系统. 2.封装得到鼠标当前位置的系统. 3.完成拖拽的实现. 首先,我们要讲到鼠标位置的获取,讲到这个,就离不开js的w ...
- OpenLayers学习笔记(二)— QML与HTML通信之画图
作者: 狐狸家的鱼 Github: 八至 本文链接:QML与 HTML通信—实现QML中点击功能按钮在地图上画图 一.HTML-map var drarGraphic; var drawType;fu ...
- 纪中2018暑假培训day7提高b组改题记录
由于今天太颓了,所以没有解释 t1: Description 码零鼠是一只很喜欢mx数学的神犇,上面那个不是ta本人的样子.这天,ta在研究一个神奇的数列,这个数列是这样的:a0 = 1an = ai ...
- Javascript深入之创建对象的多种方式以及优缺点
1.工厂模式 function createPerson(name) { var o = new Object(); o.name = name; o.getName = function() { c ...
- FluentScheduler定时器计划任务
http://www.cnblogs.com/lgxlsm/p/6734011.html 用了FluentScheduler后,再也比想用timer计时器了. FluentScheduler 是 .N ...
- Codeforces Round #523 (Div. 2) D. TV Shows
传送门 https://www.cnblogs.com/violet-acmer/p/10005351.html 题意: 有n个节目,每个节目都有个开始时间和结束时间. 定义x,y分别为租电视需要的花 ...
- JavaSE_坚持读源码_ClassLoader对象_Java1.7
ClassLoader java.lang public abstract class ClassLoader extends Object //类加载器的责任就是加载类,说了跟没说一样 A clas ...
- Web项目发布BUG总结
1.字符集乱码问题: 这是一个常遇见的问题,但总是解决不了,让人很头疼笔者最近就遇到了这个问题.首先确保你传入的数据是UTF-8格式的,如果你是用jsp+servlert写的话,你的servlert中 ...
- dom4j基础教程【转】
转自 http://blog.csdn.net/whatlonelytear/article/details/42234937 ,但经过大量美化及补充. Dom4j是一个易用的.开源的库,用于XML, ...