使用 Java 日志过滤器分析 HTTP 请求。
javax.servlet.Filter.来实现解析 HTTP 请求内容和输出日志的便捷方法。过滤器班级
此日志过滤器使用 "java.util.logging.Logger "进行日志输出,可通过更改日志级别来改变信息输出。
什么是 javax.servlet.Filter?
在构建Web应用时,除了主要业务处理之外,还需要在主要业务处理前后进行常见的二次处理。
例如,客户端认证、权限检查、日志记录等。
在每个资源中对这种副处理进行编码成为阻碍软件可维护性的主要原因,导致应用程序难以维护。
通过实施 javax.servlet.Filter,可以在请求传递给 servlet 类之前共同执行这种子处理。
还可以在 web.xml 中配置过滤器,这样就可以灵活地添加和删除过滤器,而无需更改源代码。
尝试使用日志过滤器。
让我们将日志过滤器付诸实践,通过过滤器来分析 HTTP 请求。
这一次汤姆猫从一开始,EXAMPLES 应用程序就可以在
该过滤器可通过以下设置立即执行。
< 过滤器 LogFilter 过滤器名 LogFilter(日志过滤器 <init-param logging.Level</参数名称 FINE 参数值 </init-param </filter < 过滤器映射 日志过滤器</过滤器名称 /* </filter 过滤器映射
*使用 Struts 框架时,URL 模式如下。
*.do。
检查运行会话示例屏幕的日志输出结果。
输出日志信息和日志级别。
日志输出内容
日志信息 | 日志级别 |
---|---|
Cookie 信息 | 纤细 |
HTTP 头信息 | 纤细 |
HTTP 其他信息 | 纤细 |
HTTP 请求参数 | 配置 |
请求范围中的对象 | 配置 |
会话作用域中的对象 | 配置 |
请求前后的内存使用情况 | 配置 |
屏幕过渡信息 | 信息 |
应在以下情况下使用日志级别
- 精细...... 输出最详细的日志,如果您想详细分析 HTTP 请求,可进行设置。
- CONFIG - 输出更详细的日志。建议在开发过程中保持这一水平。
- INFO・・・・ 只输出屏幕过渡信息。
如何更改日志级别。
日志输出级别可通过设置初始化参数 logging.Level.
例如
<init-param logging.Level</参数名称 INFO。
源代码
导入 javax.servlet.Filter;
导入 javax.servlet.FilterChain;
导入 javax.servlet.FilterConfig;
导入 javax.servlet.ServletException;
导入 javax.servlet.ServletRequest;
导入 javax.servlet.ServletResponse;
导入javax.servlet.http.Cookie;
导入 javax.servlet.http.HttpServletRequest;
导入 javax.servlet.http.HttpServletResponse;
导入 javax.servlet.http.HttpSession;
/**
* 实现javax.servlet.Filter来分析HTTP请求内容并输出日志
* 过滤器类。
*/
公共类 LogFilter 实现 Filter {
私有静态记录器记录器=
Logger.getLogger(LogFilter.class.getName());
私有静态最终字符串 LINE_SEPA =
System.getProperty(“line.separator”);
私有静态最终字符串NEXT_PAGE =“LogFilter.NEXT_PAGE”;
/**
* 初始化该日志过滤器。
* @参数映射
*/
公共无效初始化(FilterConfig映射){
String str = mapping.getInitParameter(“logging.Level”);
System.out.println(“设置日志级别为“+str+”。”);
级别 level = null;
尝试 {
级别 = Level.parse(str);
} catch (异常 e) {
e.printStackTrace();
级别 = 级别.INFO;
}
LogManager.getLogManager().reset();
处理程序 handler = new CustomConsoleHandler();
handler.setFormatter(new CustomFormatter());
handler.setLevel(级别);
logger.setLevel(级别);
logger.getParent().addHandler(处理程序);
}
/**
* 这是一个输出日志的过滤器。
* @param request 正在处理的HTTP请求
* @param response 正在生成 HTTP 响应
* @参数链
*/
公共无效 doFilter(ServletRequest _request, ServletResponse _response,
FilterChain 链)抛出 IOException、ServletException {
// --------------------“预处理”
HttpServletRequest 请求 = (HttpServletRequest)_request;
HttpServletResponse 响应 = (HttpServletResponse) _response;
如果(logger.isLoggable(Level.CONFIG)){
记录器.config(
“============请求开始!!”
+“线程ID:”
+ Thread.currentThread().hashCode()
+ ” ========================================================”);
}
// 内存使用情况
字符串actionMemory = null;
如果(logger.isLoggable(Level.CONFIG)){
动作内存 = getMemoryInfo(” ”
+ new Time(System.currentTimeMillis()) + ”Request[上一个]”);
}
如果 (logger.isLoggable(Level.FINE)) {
logger.fine(“Cookie 信息” + getCookieInfo(request));
}
如果 (logger.isLoggable(Level.FINE)) {
logger.fine(“HTTP头信息” + getHeadersInfo(request));
}
如果 (logger.isLoggable(Level.FINE)) {
记录器
.fine(“HTTP其他信息” + getRequestOtherInfo(request));
}
如果(logger.isLoggable(Level.CONFIG)){
字符串 reqlog = getRequestParametersInfo(request);
logger.config(“HTTP请求参数” + reqlog);
}
如果(logger.isLoggable(Level.CONFIG)){
logger.config(“请求范围对象”
+ getRequestAttributeInfo(请求));
}
如果(logger.isLoggable(Level.CONFIG)){
字符串 sessionlog = getSessionInfo(request,true);
logger.config(“会话范围对象(请求处理之前)”
+ 会话日志);
}
// 调用下一个过滤器
chain.doFilter(请求,响应);
// - - - - - - - - - - “后期处理”
如果(logger.isLoggable(Level.CONFIG)){
字符串 sessionlog = getSessionInfo(request,false);
logger.config(“会话范围对象(请求处理后)”
+ 会话日志);
}
// 内存使用情况
如果(logger.isLoggable(Level.CONFIG)){
actionMemory = ”请求前后的内存使用情况”+LINE_SEPA
+ 动作内存 + LINE_SEPA
+ getMemoryInfo(” ” + new Time(System.currentTimeMillis())
+“请求[之后]”);
logger.config(actionMemory+LINE_SEPA);
}
// 屏幕转换信息
如果 (logger.isLoggable(Level.INFO)) {
String nextPage = (String) request.getAttribute(NEXT_PAGE);
if (nextPage == null || nextPage.length() == 0) {
下一页 = request.getRequestURI();
}
logger.info(“NEXT_PAGE=[” + nextPage + “], ”
+ “IP_ADDRESS=[” + request.getRemoteAddr() + “], ”
+ “SESSION_ID=[” + request.getSession().getId() + “], ”
+ “USER-AGENT=[” + request.getHeader(“用户代理”) + “]”);
}
如果(logger.isLoggable(Level.CONFIG)){
记录器.config(
“============请求结束!!”
+”线程ID:”+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
公共无效销毁(){
}
// ---------- 下面的私有方法 ------------
私有静态 String getMemoryInfo(String message) {
DecimalFormat dFromat = new DecimalFormat(“#,###KB”);
长空闲 = Runtime.getRuntime().freeMemory() / 1024;
长总计 = Runtime.getRuntime().totalMemory() / 1024;
长最大值 = Runtime.getRuntime().maxMemory() / 1024;
使用时间长=总计-免费;
String msg = 消息 + ” : ” + “total=” + dFromat.format(total) + “, ”
+ “已使用量=” + dFromat.format(已使用) + ” (” + (已使用 * 100 / 总计)
+ “%), 最大可用=” + dFromat.format(max);
返回消息;
}
/**
* 将所有请求头输出到日志中。
*/
私有静态字符串 getHeadersInfo(HttpServletRequest 请求) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
枚举 headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
buff.append(“”);
buff.append(headerName);
buff.append(“=”);
buff.append(request.getHeader(headerName));
buff.append(LINE_SEPA);
}
返回 buff.toString();
}
私有静态字符串 getCookieInfo(HttpServletRequest 请求) {
StringBuffer buff = new StringBuffer();
Cookie[] cookies = request.getCookies();
if (cookies == null) {
返回 ””;
}
for (int i = 0; i < cookies.length; i++) {
buff.append(“\n — Cookie[” + i + “] —\n”);
buff.append(“”);
buff.append(cookies[i].getName());
buff.append(“=”);
buff.append(cookies[i].getValue());
buff.append(LINE_SEPA);
buff.append(“”);
buff.append(“getVersion()”);
buff.append(“=”);
buff.append(cookies[i].getVersion());
buff.append(LINE_SEPA);
buff.append(“”);
buff.append(“getComment()”);
buff.append(“=”);
buff.append(cookies[i].getComment());
buff.append(LINE_SEPA);
buff.append(“”);
buff.append(“getDomain()”);
buff.append(“=”);
buff.append(cookies[i].getDomain());
buff.append(LINE_SEPA);
buff.append(“”);
buff.append(“getMaxAge()”);
buff.append(“=”);
buff.append(cookies[i].getMaxAge());
buff.append(LINE_SEPA);
buff.append(“”);
buff.append(“getPath()”);
buff.append(“=”);
buff.append(cookies[i].getPath());
buff.append(LINE_SEPA);
buff.append(“”);
buff.append(“getSecure()”);
buff.append(“=”);
buff.append(cookies[i].getSecure());
buff.append(LINE_SEPA);
}
返回 buff.toString();
}
私有静态字符串 getRequestParametersInfo(HttpServletRequest 请求) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
地图map=convertRequest(request);
TreeMap trr = new TreeMap(map);
迭代器 itr = trr.keySet().iterator();
while (itr.hasNext()) {
字符串键 = (字符串) itr.next();
buff.append(“”);
buff.append(key);
buff.append(“=”);
对象值=map.get(key);
String[]值=(String[])值;
if (values.length == 1) {
buff.append(值[0]);
} 别的 {
// 字符串数组转换
字符串 strValue = 层(值);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
返回 buff.toString();
}
私有静态字符串 getRequestAttributeInfo(HttpServletRequest 请求) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
枚举 e = request.getAttributeNames();
while (e.hasMoreElements()) {
字符串名称 = (String) e.nextElement();
buff.append(” 名称=” + 名称 + “, attributeClass= ”
+ request.getAttribute(name).getClass().getName()
+ “, toString() = ” + request.getAttribute(name)
+ LINE_SEPA);
}
返回 buff.toString();
}
私有静态字符串 getRequestOtherInfo(HttpServletRequest 请求) {
StringBuffer buff = new StringBuffer();
buff.append(LINE_SEPA);
buff.append(”getCharacterEncoding()=”);
buff.append(request.getCharacterEncoding());
buff.append(LINE_SEPA);
buff.append(“getContentLength()=”);
buff.append(request.getContentLength());
buff.append(LINE_SEPA);
buff.append(”getContentType()=”);
buff.append(request.getContentType());
buff.append(LINE_SEPA);
buff.append(”getLocale()=”);
buff.append(request.getLocale());
buff.append(LINE_SEPA);
buff.append(”getProtocol()=”);
buff.append(request.getProtocol());
buff.append(LINE_SEPA);
buff.append(”getRemoteAddr()=”);
buff.append(request.getRemoteAddr());
buff.append(LINE_SEPA);
buff.append(”getRemoteHost()=”);
buff.append(request.getRemoteHost());
buff.append(LINE_SEPA);
buff.append(”getScheme()=”);
buff.append(request.getScheme());
buff.append(LINE_SEPA);
buff.append(”getServerName()=”);
buff.append(request.getServerName());
buff.append(LINE_SEPA);
buff.append(”getServerPort()=”);
buff.append(request.getServerPort());
buff.append(LINE_SEPA);
buff.append(”isSecure()=”);
buff.append(request.isSecure());
buff.append(LINE_SEPA);
buff.append(”getAuthType()=”);
buff.append(request.getAuthType());
buff.append(LINE_SEPA);
buff.append(”getContextPath()=”);
buff.append(request.getContextPath());
buff.append(LINE_SEPA);
buff.append(“getMethod()=”);
buff.append(request.getMethod());
buff.append(LINE_SEPA);
buff.append(”getPathInfo()=”);
buff.append(request.getPathInfo());
buff.append(LINE_SEPA);
buff.append(“getPathTranslated()=”);
buff.append(request.getPathTranslated());
buff.append(LINE_SEPA);
buff.append(”getQueryString()=”);
buff.append(request.getQueryString());
buff.append(LINE_SEPA);
buff.append(”getRemoteUser()=”);
buff.append(request.getRemoteUser());
buff.append(LINE_SEPA);
buff.append(”getRequestedSessionId()=”);
buff.append(request.getRequestedSessionId());
buff.append(LINE_SEPA);
buff.append(“getRequestURI()=”);
buff.append(request.getRequestURI());
buff.append(LINE_SEPA);
buff.append(”getServletPath()=”);
buff.append(request.getServletPath());
buff.append(LINE_SEPA);
buff.append(”getUserPrincipal()=”);
buff.append(request.getUserPrincipal());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdFromCookie()=”);
buff.append(request.isRequestedSessionIdFromCookie());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdFromURL()=”);
buff.append(request.isRequestedSessionIdFromURL());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdValid()=”);
buff.append(request.isRequestedSessionIdValid());
buff.append(LINE_SEPA);
返回 buff.toString();
}
private static String getSessionInfo(HttpServletRequest request,boolean before) {
HttpSession 会话 = request.getSession();
StringBuffer buff = new StringBuffer();
buff.append(LINE_SEPA);
如果(之前){
buff.append(” session.isNew() = ” + session.isNew());
buff.append(LINE_SEPA);
buff.append(” session.getId() = ” + session.getId());
buff.append(LINE_SEPA);
}
枚举 e = session.getAttributeNames();
while (e.hasMoreElements()) {
String sessionName = (String) e.nextElement();
String sessionClassName = session.getAttribute(sessionName)
.getClass().getName();
buff.append(” name =” + sessionName + “, value =”
+ session.getAttribute(sessionName) + “, attributeClass = ”
+ 会话类名称+LINE_SEPA);
}
返回 buff.toString();
}
私有静态Hashtable ConvertRequest(HttpServletRequest请求){
Hashtable tempHash = new Hashtable();
枚举 e = request.getParameterNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String[]values=request.getParameterValues(key);
String[]参数值=new String[values.length];
for (int i = 0; i < 值.length; i++) {
参数值[i] = convUnicode(值[i]);
}
tempHash.put(key, 参数值);
}
返回临时哈希值;
}
私有静态字符串层(对象值){
如果(值==空){
返回“空”;
} else if (value instanceof String[]) {
返回 convString((String[]) 值);
} 别的 {
返回值.toString();
}
}
/**
* 将字符串数组 [strArray] 的内容作为字符串返回,如下所示。
*“[温度1,温度2,温度3]”
* @param strArray 要计算的字符串数组
* @return 转换后的字符串
*/
私有静态字符串 convString(String[] strArray) {
if (strArray == null)
返回空值;
StringBuffer buff = new StringBuffer(“[”);
for (int i = 0; i < strArray.length; i++) {
buff.append(strArray[i] + “, “);
}
buff.delete(buff.length() – 2, buff.length());
buff.append(“]”);
返回 buff.toString();
}
/**
* 将 [str] 转换为 Unicode。
* @参数str
* @返回
*/
私有静态字符串 convUnicode(字符串 str) {
if (str == null)
返回空值;
尝试 {
返回新字符串(str.getBytes(“8859_1”),“JISAutoDetect”);
} catch (UnsupportedEncodingException e) {
抛出新的运行时异常(e);
}
}
// ———————————————————————–
静态类 CustomFormatter 扩展 Formatter {
静态最终字符串模式=“yyyy/MM/dd HH:mm:ss”;
公共同步字符串格式(LogRecord记录){
StringBuffer buf = new StringBuffer();
// 设置日期和时间
日期日期 = 新日期();
date.setTime(record.getMillis());
SimpleDateFormat 格式化程序 = new SimpleDateFormat(pattern);
buf.append(formatter.format(日期));
buf.append(“:”);
// 设置级别
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(“:”);
buf.append(record.getMessage());
buf.append(LINE_SEPA);
返回 buf.toString();
}
}
静态类 CustomConsoleHandler 扩展 StreamHandler {
公共 CustomConsoleHandler() {
极好的();
setOutputStream(System.out);
}
/**
* 发出日志记录。
* 最初,记录请求被发送到 Logger 对象。
* 该对象初始化 LogRecord 并
*重定向至此处。
*
* @param record 日志事件的描述。空记录被简单地忽略
* 并且不会发送任何通知。
*/
公共无效发布(LogRecord记录){
超级.发布(记录);
冲洗();
}
/**
* 重写 StreamHandler.close 来刷新,但是
* 输出流未关闭。换句话说,System.err 没有关闭。
*/
公共无效关闭(){
冲洗();
}
}
}