Phân tích cú pháp các yêu cầu HTTP bằng bộ lọc nhật ký Java
javax.servlet.FilterCông cụ này cung cấp một phương thức tiện lợi để phân tích nội dung các yêu cầu HTTP và xuất ra nhật ký.LọcTôi xin tự giới thiệu về lớp học.
Bộ lọc nhật ký này sử dụng "java.util.logging.Logger" để xuất nhật ký, và bạn có thể thay đổi thông tin đầu ra bằng cách thay đổi cấp độ nhật ký.
javax.servlet.Filter là gì?
Khi xây dựng một ứng dụng web, bên cạnh các quy trình nghiệp vụ chính, cần phải thực hiện các quy trình phụ thường diễn ra trước và sau các quy trình chính đó.
Ví dụ: xác thực người dùng, kiểm tra quyền truy cập, ghi nhật ký, v.v.
Việc mã hóa các quy trình phụ như vậy trong từng tài nguyên là một trở ngại lớn đối với khả năng bảo trì phần mềm và dẫn đến một ứng dụng khó bảo trì.
Bằng cách triển khai giao diện javax.servlet.Filter, bạn có thể thực hiện quá trình xử lý thứ cấp này một cách chung chung trước khi yêu cầu được chuyển đến lớp servlet.
Hơn nữa, vì các cài đặt bộ lọc có thể được cấu hình trong web.xml, bạn có thể linh hoạt thêm hoặc xóa bộ lọc mà không cần thay đổi mã nguồn.
Hãy thử sử dụng bộ lọc nhật ký.
Hãy sử dụng bộ lọc nhật ký để phân tích các yêu cầu HTTP bằng cách lọc chúng.
Lần nàyTomcatChúng ta sẽ sử dụng ứng dụng ví dụ được cung cấp sẵn theo mặc định.
Bộ lọc này có thể được chạy ngay sau khi thực hiện các thiết lập sau.
2. Đặt các tập tin lớp đã biên dịch vào thư mục "/examples/WEB-INF/classes".
3. Đặt định nghĩa sau trong web.xml.
Bộ lọc nhật ký Bộ lọc nhật ký ghi nhật ký. Cấp độ KHỎE Bộ lọc nhật ký /*
*Cấu trúc URL khi sử dụng framework Struts như sau:
*.LÀM
Vui lòng kiểm tra kết quả đầu ra nhật ký khi bạn chạy màn hình Ví dụ về Phiên.

Thông tin nhật ký cần ghi và mức độ ghi nhật ký
●Nội dung đầu ra nhật ký
| Thông tin nhật ký | Mức độ ghi nhật ký |
|---|---|
| Thông tin về cookie | KHỎE |
| Thông tin tiêu đề HTTP | KHỎE |
| HTTP và các thông tin khác | KHỎE |
| Tham số yêu cầu HTTP | CẤU HÌNH |
| Đối tượng có phạm vi yêu cầu | CẤU HÌNH |
| Đối tượng có phạm vi phiên | CẤU HÌNH |
| Mức sử dụng bộ nhớ trước và sau yêu cầu | CẤU HÌNH |
| Thông tin chuyển đổi màn hình | THÔNG TIN |
Bạn nên sử dụng các cấp độ ghi nhật ký sau để phân biệt giữa chúng.
- FINE... Chế độ này xuất ra nhật ký chi tiết nhất. Hãy chọn chế độ này khi bạn muốn phân tích các yêu cầu HTTP một cách chi tiết.
- Lệnh CONFIG... xuất ra nhật ký chi tiết hơn một chút. Nên giữ ở mức độ này trong quá trình phát triển.
- THÔNG TIN... Chỉ xuất ra thông tin về quá trình chuyển đổi màn hình.
● Cách thay đổi cấp độ ghi nhật ký
Bạn có thể thay đổi mức độ hiển thị nhật ký bằng cách thiết lập tham số khởi tạo logging.Level.
ví dụ:
ghi nhật ký. Cấp độ THÔNG TIN
Mã nguồn
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Triển khai javax.servlet.Filter để phân tích nội dung của yêu cầu HTTP và xuất nhật ký.
* Lớp lọc.
*/
public class LogFilter implements Filter {
private static Logger logger =
Logger.getLogger(LogFilter.class.getName());
private static final String LINE_SEPA =
System.getProperty(“line.separator”);
private static final String NEXT_PAGE = “LogFilter.NEXT_PAGE”;
/**
* Khởi tạo bộ lọc nhật ký này.
* Ánh xạ @param
*/
public void init(FilterConfig mapping) {
Chuỗi str = mapping.getInitParameter(“logging.Level”);
System.out.println("Đặt mức độ ghi nhật ký thành "+str+".");
Mức độ = null;
thử {
level = Level.parse(str);
} catch (Exception e) {
e.printStackTrace();
level = Level.INFO;
}
LogManager.getLogManager().reset();
Handler handler = new CustomConsoleHandler();
handler.setFormatter(new CustomFormatter());
handler.setLevel(level);
logger.setLevel(level);
logger.getParent().addHandler(handler);
}
/**
* Đây là bộ lọc xuất ra nhật ký.
* @param request Yêu cầu HTTP đang được xử lý
* @param response Phản hồi HTTP đang được tạo
* @param chain
*/
public void doFilter(ServletRequest _request, ServletResponse _response,
Chuỗi FilterChain) ném ra IOException, ServletException {
// —————————————————————『Xử lý sơ bộ』
HttpServletRequest request = (HttpServletRequest) _request;
HttpServletResponse response = (HttpServletResponse) _response;
nếu (logger.isLoggable(Level.CONFIG)) {
logger.Config(
“============ Bắt đầu yêu cầu!!”
+"ID chủ đề:"”
+ Thread.currentThread().hashCode()
+ ” ==========================================================” Bản quyền;
}
// Mức sử dụng bộ nhớ
Chuỗi actionMemory = null;
nếu (logger.isLoggable(Level.CONFIG)) {
actionMemory = getMemoryInfo(” ”
+ new Time(System.currentTimeMillis()) + " Yêu cầu [Trước đó]");
}
nếu (logger.isLoggable(Level.FINE)) {
logger.fine("Thông tin cookie" + getCookieInfo(request));
}
nếu (logger.isLoggable(Level.FINE)) {
logger.fine("Thông tin tiêu đề HTTP" + getHeadersInfo(request));
}
nếu (logger.isLoggable(Level.FINE)) {
người ghi nhật ký
.fine("Thông tin khác về HTTP" + getRequestOtherInfo(request));
}
nếu (logger.isLoggable(Level.CONFIG)) {
Chuỗi reqlog = getRequestParametersInfo(request);
logger.config("Tham số yêu cầu HTTP" + reqlog);
}
nếu (logger.isLoggable(Level.CONFIG)) {
logger.config("đối tượng phạm vi yêu cầu")“
+ getRequestAttributeInfo(request));
}
nếu (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request,true);
logger.config("đối tượng phạm vi phiên (trước khi xử lý yêu cầu)")“
+ nhật ký phiên);
}
// Gọi bộ lọc sau
chain.doFilter(request, response);
// ———————————————————-『Xử lý hậu kỳ』
nếu (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request, false);
logger.config("đối tượng phạm vi phiên (sau khi xử lý yêu cầu)")“
+ nhật ký phiên);
}
// Mức sử dụng bộ nhớ
nếu (logger.isLoggable(Level.CONFIG)) {
actionMemory = "Mức sử dụng bộ nhớ trước và sau yêu cầu" + LINE_SEPA
+ actionMemory + LINE_SEPA
+ getMemoryInfo(” ” + new Time(System.currentTimeMillis())
+ "Yêu cầu [sau]");
logger.config(actionMemory+LINE_SEPA);
}
// Thông tin chuyển đổi màn hình
nếu (logger.isLoggable(Level.INFO)) {
Chuỗi nextPage = (Chuỗi) request.getAttribute(NEXT_PAGE);
if (nextPage == null || nextPage.length() == 0) {
nextPage = request.getRequestURI();
}
logger.info(“NEXT_PAGE=[” + nextPage + “], ”
+ “IP_ADDRESS=[” + request.getRemoteAddr() + “], ”
+ “SESSION_ID=[” + request.getSession().getId() + “], ”
+ “USER-AGENT=[” + request.getHeader(“user-agent”) + “]”);
}
nếu (logger.isLoggable(Level.CONFIG)) {
logger.Config(
“============ Kết thúc yêu cầu!!”
+"ID luồng:"+ Thread.currentThread().hashCode()
+ ” ==========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
public void destroy() {
}
// ------- Các phương thức riêng tư bên dưới -------
private static String getMemoryInfo(String message) {
DecimalFormat dFromat = new DecimalFormat(“#,###KB”);
long free = Runtime.getRuntime().freeMemory() / 1024;
tổng dài = Runtime.getRuntime().totalMemory() / 1024;
dài max = Runtime.getRuntime().maxMemory() / 1024;
đã sử dụng lâu = hoàn toàn miễn phí;
String msg = message + ": " + "Tổng=" + dFormat.format(total) + ", "”
+ “Cách sử dụng =" + dFormat.format(đã sử dụng) + ” (” + (đã sử dụng * 100 / tổng)
+ “%), số lượng tối đa có sẵn=” + dFormat.format(max);
trả về thông báo;
}
/**
* Ghi lại tất cả các tiêu đề yêu cầu.
*/
private static String getHeadersInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Liệt kê headerNames = request.getHeaderNames();
trong khi (headerNames.hasMoreElements()) {
Chuỗi headerName = (String) headerNames.nextElement();
buff.append("");
buff.append(headerName);
buff.append("=");
buff.append(request.getHeader(headerName));
buff.append(LINE_SEPA);
}
return buff.toString();
}
private static String getCookieInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer();
Cookie[] cookies = request.getCookies();
nếu (cookies == null) {
trở lại "";
}
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);
}
return buff.toString();
}
private static String getRequestParametersInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Map map = convertRequest(request);
TreeMap trr = new TreeMap(map);
Iterator itr = trr.keySet().iterator();
trong khi (itr.hasNext()) {
Chuỗi khóa = (Chuỗi) itr.next();
buff.append("");
buff.append(key);
buff.append("=");
Giá trị đối tượng = map.get(key);
String[] values = (String[]) value;
if (values.length == 1) {
buff.append(values[0]);
khác {
// Mảng chuỗi được chuyển đổi.
Chuỗi strValue = stratum(values);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
return buff.toString();
}
private static String getRequestAttributeInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Liệt kê e = request.getAttributeNames();
trong khi (e.hasMoreElements()) {
Tên chuỗi = (String) e.nextElement();
buff.append(” name=” + name + “, attributeClass= ”
+ request.getAttribute(name).getClass().getName()
+ “, toString() = ” + request.getAttribute(name)
+ LINE_SEPA);
}
return buff.toString();
}
private static String getRequestOtherInfo(HttpServletRequest request) {
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);
return buff.toString();
}
private static String getSessionInfo(HttpServletRequest request, boolean before) {
HttpSession session = request.getSession();
StringBuffer buff = new StringBuffer();
buff.append(LINE_SEPA);
nếu (trước) {
buff.append(” session.isNew() = ” + session.isNew());
buff.append(LINE_SEPA);
buff.append(” session.getId() = ” + session.getId());
buff.append(LINE_SEPA);
}
Liệt kê e = session.getAttributeNames();
trong khi (e.hasMoreElements()) {
String sessionName = (String) e.nextElement();
Chuỗi sessionClassName = session.getAttribute(sessionName)
.getClass().getName();
buff.append(" name =" + sessionName + ", value ="”
+ session.getAttribute(sessionName) + “, attributeClass = ”
+ sessionClassName+LINE_SEPA);
}
return buff.toString();
}
private static Hashtable convertRequest(HttpServletRequest request) {
Hashtable tempHash = new Hashtable();
Liệt kê e = request.getParameterNames();
trong khi (e.hasMoreElements()) {
Chuỗi khóa = (Chuỗi) e.nextElement();
String[] values = request.getParameterValues(key);
String[] parameterValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
parameterValues[i] = convUnicode(values[i]);
}
tempHash.put(key, parameterValues);
}
Trả về tempHash;
}
private static String stratum(Object value) {
nếu (giá trị == null) {
Trả về "null";
} else if (value instanceof String[]) {
return convString((String[]) value);
khác {
return value.toString();
}
}
/**
* Trả về nội dung của mảng chuỗi [strArray] dưới dạng chuỗi, như hiển thị bên dưới.
* “[temp1,temp2,temp3]”
* @param strArray Mảng chuỗi cần được đánh giá.
* @return chuỗi đã chuyển đổi
*/
private static String convString(String[] strArray) {
nếu (strArray == null)
trả về 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("]");
return buff.toString();
}
/**
* Chuyển đổi [chuỗi] sang Unicode.
* @param str
* @trở lại
*/
private static String convUnicode(String str) {
nếu (chuỗi == null)
trả về null;
thử {
return new String(str.getBytes(“8859_1”), “JISAutoDetect”);
} catch (UnsupportedEncodingException e) {
ném ngoại lệ RuntimeException mới(e);
}
}
// ———————————————————————–
static class CustomFormatter extends Formatter {
static final String pattern = “yyyy/MM/dd HH:mm:ss”;
public synchronized String format(LogRecord record) {
StringBuffer buf = new StringBuffer();
// Đặt ngày và giờ
Date date = new Date();
date.setTime(record.getMillis());
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
buf.append(formatter.format(date));
buf.append(":");
// Đặt mức độ
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(":");
buf.append(record.getMessage());
buf.append(LINE_SEPA);
return buf.toString();
}
}
static class CustomConsoleHandler extends StreamHandler {
public CustomConsoleHandler() {
siêu();
setOutputStream(System.out);
}
/**
* Một bản ghi nhật ký sẽ được lập.
* Ở trạng thái ban đầu, các yêu cầu ghi nhật ký được chuyển hướng đến đối tượng Logger.
* Việc này được thực hiện để đáp lại và đối tượng này khởi tạo LogRecord.
* Thông tin này đã được chuyển tiếp đến đây.
*
* @param record Mô tả sự kiện nhật ký. Bản ghi rỗng sẽ bị bỏ qua.
* Sẽ không có thông báo nào được gửi.
*/
public void publish(LogRecord record) {
siêu.xuất bản(bản ghi);
tuôn ra();
}
/**
* Mặc dù bạn ghi đè phương thức StreamHandler.close để thực hiện flush,
* Luồng đầu ra sẽ không bị đóng. Nói cách khác, System.err sẽ không bị đóng.
*/
public void close() {
tuôn ra();
}
}
}
