Analysieren Sie HTTP-Anfragen mit Java-Protokollfiltern
javax.servlet.FilterEine praktische Möglichkeit, den Inhalt von HTTP-Anfragen und Ausgabeprotokollen zu implementieren und zu analysieren.FilterVorstellung der Klasse.
Dieser Protokollfilter verwendet „java.util.logging.Logger“ für die Protokollausgabe, und Sie können die Informationsausgabe ändern, indem Sie die Protokollebene ändern.
Was ist javax.servlet.Filter?
Beim Erstellen einer Webanwendung ist es zusätzlich zur Hauptgeschäftsverarbeitung erforderlich, vor und nach der Hauptgeschäftsverarbeitung eine gemeinsame Sekundärverarbeitung durchzuführen.
Zum Beispiel Client-Authentifizierung, Autoritätsprüfung, Protokollierung usw.
Die Codierung einer solchen Nebenverarbeitung in jeder Ressource wird zu einer Hauptursache für die Beeinträchtigung der Wartbarkeit der Software, was zu einer schwierig zu wartenden Anwendung führt.
Durch die Implementierung von javax.servlet.Filter können Sie diese Nebenverarbeitung üblicherweise durchführen, bevor die Anforderung an die Servlet-Klasse übergeben wird.
Da Filtereinstellungen auch in web.xml vorgenommen werden können, können Sie Filter flexibel hinzufügen oder löschen, ohne den Quellcode zu ändern.
Versuchen Sie es mit einem Protokollfilter
Lassen Sie uns tatsächlich einen Protokollfilter verwenden, um HTTP-Anfragen zu filtern und zu analysieren.
DiesmalKaterWir werden die Beispielanwendung verwenden, die von Anfang an verfügbar ist.
Sie können diesen Filter sofort ausführen, indem Sie die folgenden Einstellungen vornehmen.
2. Platzieren Sie die kompilierte Klassendatei unter „/examples/WEB-INF/classes“.
3.Legen Sie die folgende Definition in web.xml fest.
LogFilter LogFilter logging.Level BUSSGELD LogFilter /*
*Das URL-Muster bei Verwendung des Struts-Frameworks ist wie folgt.
*.Tun
Bitte überprüfen Sie die Protokollausgabeergebnisse der Ausführung des Sitzungsbeispielbildschirms.
Protokollinformationen und Protokollebene ausgeben
●Ausgabeinhalt protokollieren
Protokollinformationen | Protokollebene |
---|---|
Cookie-Informationen | BUSSGELD |
HTTP-Header-Informationen | BUSSGELD |
HTTPWeitere Informationen | BUSSGELD |
HTTP-Anfrageparameter | KONFIG |
Anforderungsbereichsobjekt | KONFIG |
Sitzungsbezogenes Objekt | KONFIG |
Speichernutzung vor und nach Anfragen | KONFIG |
Informationen zum Bildschirmübergang | DIE INFO |
Am besten verwenden Sie die Protokollebenen wie folgt.
- FEIN: Gibt das detaillierteste Protokoll aus. Legen Sie dies fest, wenn Sie die HTTP-Anfrage im Detail analysieren möchten.
- CONFIG... Gibt ein einigermaßen detailliertes Protokoll aus. Es empfiehlt sich, diesen Wert während der Entwicklungsphase beizubehalten.
- INFO: Gibt nur Informationen zum Bildschirmübergang aus.
●So ändern Sie die Protokollebene
Sie können die Protokollausgabeebene ändern, indem Sie den Initialisierungsparameter logging.Level festlegen.
Beispiel:
logging.Level DIE INFO
Quellcode
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;
/**
* Implementieren Sie javax.servlet.Filter, um den Inhalt von HTTP-Anfragen und Ausgabeprotokollen zu analysieren
* Filterklasse.
*/
Die öffentliche Klasse LogFilter implementiert Filter {
privater statischer Logger logger =
Logger.getLogger(LogFilter.class.getName());
privater statischer finaler String LINE_SEPA =
System.getProperty(“line.separator”);
private static final String NEXT_PAGE = „LogFilter.NEXT_PAGE“;
/**
* Initialisieren Sie diesen Protokollfilter.
* @param-Zuordnung
*/
public void init(FilterConfig-Mapping) {
String str = Mapping.getInitParameter(“logging.Level”);
System.out.println(“Protokollebene auf „+str+“ setzen.“);
Level level = null;
versuchen {
level = Level.parse(str);
} Catch (Ausnahme 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);
}
/**
* Dies ist ein Filter, der Protokolle ausgibt.
* @param request HTTP-Anfrage wird verarbeitet
* @param Antwort HTTP-Antwort wird generiert
* @param-Kette
*/
public void doFilter(ServletRequest _request, ServletResponse _response,
FilterChain-Kette) löst IOException, ServletException {
// --------------------"Vorverarbeitung"
HttpServletRequest request = (HttpServletRequest) _request;
HttpServletResponse Antwort = (HttpServletResponse) _response;
if (logger.isLoggable(Level.CONFIG)) {
logger.config(
„============ Start anfordern!!“
+“Thread-ID:“
+ Thread.currentThread().hashCode()
+ ” ========================================================”);
}
// Speichernutzung
String actionMemory = null;
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = getMemoryInfo(“ ”
+ new Time(System.currentTimeMillis()) + „Request[ previous]“);
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(“Cookie-Informationen” + getCookieInfo(request));
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(“HTTP-Header-Informationen“ + getHeadersInfo(request));
}
if (logger.isLoggable(Level.FINE)) {
Logger
.fine(“HTTP andere Informationen” + getRequestOtherInfo(request));
}
if (logger.isLoggable(Level.CONFIG)) {
String reqlog = getRequestParametersInfo(request);
logger.config(„HTTP-Anforderungsparameter“ + reqlog);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config(“Bereichsobjekt anfordern”
+ getRequestAttributeInfo(request));
}
if (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request,true);
logger.config („Sitzungsbereichsobjekt (vor der Anforderungsverarbeitung)“
+ Sitzungsprotokoll);
}
// Nächsten Filter aufrufen
chain.doFilter(Anfrage, Antwort);
// -------------------- "Nachbearbeitung"
if (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request,false);
logger.config („Sitzungsbereichsobjekt (nach der Anforderungsverarbeitung)“
+ Sitzungsprotokoll);
}
// Speichernutzung
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = „Speichernutzung vor und nach der Anfrage“+LINE_SEPA
+ actionMemory + LINE_SEPA
+ getMemoryInfo(“ ” + new Time(System.currentTimeMillis())
+ „Anfrage[nach]“);
logger.config(actionMemory+LINE_SEPA);
}
// Informationen zum Bildschirmübergang
if (logger.isLoggable(Level.INFO)) {
String nextPage = (String) 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“) + „]“);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config(
„============ Anforderungsende!!“
+“Thread-ID:“+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
public void destroy() {
}
// ---------- Private Methode unten -----------
privater statischer String getMemoryInfo(String message) {
DecimalFormat dFromat = new DecimalFormat(“#,###KB”);
long free = Runtime.getRuntime().freeMemory() / 1024;
long total = Runtime.getRuntime().totalMemory() / 1024;
long max = Runtime.getRuntime().maxMemory() / 1024;
lange genutzt = insgesamt – kostenlos;
String msg = message + „:“ + „total=“ + dFromat.format(total) + „,“
+ „Used amount=“ + dFromat.format(used) + „(“ + (used * 100 / total)
+ „%), maximal verfügbar=“ + dFromat.format(max);
Rückgabenachricht;
}
/**
* Alle Anforderungsheader in das Protokoll ausgeben.
*/
privater statischer String getHeadersInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Aufzählung 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);
}
return buff.toString();
}
privater statischer String getCookieInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer();
Cookie[] Cookies = request.getCookies();
if (cookies == null) {
zurückkehren "";
}
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();
}
privater statischer String getRequestParametersInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Karte map = convertRequest(request);
TreeMap trr = new TreeMap(map);
Iterator itr = trr.keySet().iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
buff.append(“ „);
buff.append(key);
buff.append(“=”);
Objektwert = map.get(key);
String[]-Werte = (String[])-Wert;
if (values.length == 1) {
buff.append(values[0]);
} anders {
// String-Array wird konvertiert
String strValue = stratum(values);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
return buff.toString();
}
privater statischer String getRequestAttributeInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Aufzählung e = request.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
buff.append(“ name=“ + name + „, attributeClass=“
+ request.getAttribute(name).getClass().getName()
+ „, toString() =“ + request.getAttribute(name)
+ LINE_SEPA);
}
return buff.toString();
}
privater statischer 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();
}
privater statischer String getSessionInfo(HttpServletRequest request,boolean before) {
HttpSession session = request.getSession();
StringBuffer buff = new StringBuffer();
buff.append(LINE_SEPA);
wenn (vorher) {
buff.append(“ session.isNew() = ” + session.isNew());
buff.append(LINE_SEPA);
buff.append(“ session.getId() = ” + session.getId());
buff.append(LINE_SEPA);
}
Aufzählung 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 = „
+ sessionClassName+LINE_SEPA);
}
return buff.toString();
}
private static Hashtable convertRequest(HttpServletRequest request) {
Hashtable tempHash = new Hashtable();
Aufzählung e = request.getParameterNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String[] Werte = request.getParameterValues(key);
String[] parameterValues = new String[values.length];
for (int i = 0; i < Werte.Länge; i++) {
parameterValues[i] = convUnicode(values[i]);
}
tempHash.put(key, parameterValues);
}
return tempHash;
}
privater statischer String stratum(Objektwert) {
if (Wert == null) {
„null“ zurückgeben;
} else if (Wertinstanz von String[]) {
return convString((String[]) value);
} anders {
Rückgabewert.toString();
}
}
/**
* Gibt den Inhalt des String-Arrays [strArray] als String wie den folgenden zurück.
* „[temp1,temp2,temp3]“
* @param strArray String-Array, das ausgewertet werden soll
* @return String nach der Konvertierung
*/
privater statischer String convString(String[] strArray) {
if (strArray == null)
null zurückgeben;
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();
}
/**
* Konvertieren Sie [str] in Unicode.
* @param str
* @zurückkehren
*/
privater statischer String convUnicode(String str) {
if (str == null)
null zurückgeben;
versuchen {
return new String(str.getBytes(„8859_1“), „JISAutoDetect“);
} Catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
// ———————————————————————–
Die statische Klasse CustomFormatter erweitert Formatter {
static final String pattern = „yyyy/MM/dd HH:mm:ss“;
öffentliches synchronisiertes String-Format (LogRecord-Datensatz) {
StringBuffer buf = new StringBuffer();
// Datum und Uhrzeit einstellen
Datum date = neues Date();
date.setTime(record.getMillis());
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
buf.append(formatter.format(date));
buf.append(“:”);
// Level einstellen
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(“:”);
buf.append(record.getMessage());
buf.append(LINE_SEPA);
return buf.toString();
}
}
Die statische Klasse CustomConsoleHandler erweitert StreamHandler {
public CustomConsoleHandler() {
super();
setOutputStream(System.out);
}
/**
* Gibt einen LogRecord aus.
* Zunächst werden Protokollierungsanfragen an ein Logger-Objekt gesendet.
* und dieses Objekt initialisiert den LogRecord und
*Hierher weitergeleitet.
*
* @param-Datensatz Beschreibung des Protokollereignisses. Nulldatensätze werden einfach ignoriert
* und es wird keine Benachrichtigung gesendet.
*/
public void Publish(LogRecord-Datensatz) {
super.publish(record);
spülen();
}
/**
* Überschreiben Sie StreamHandler.close, um es zu leeren, aber
* Der Ausgabestream ist nicht geschlossen. Mit anderen Worten, System.err ist nicht geschlossen.
*/
public void close() {
spülen();
}
}
}