Analizza le richieste HTTP con i filtri di registro Java
javax.servlet.FilterUn modo conveniente per implementare e analizzare il contenuto delle richieste HTTP e dei log di output.FiltroPresentazione della classe.
Questo filtro di log utilizza "java.util.logging.Logger" per l'output del log ed è possibile modificare l'output delle informazioni modificando il livello di log.
Cos'è javax.servlet.Filter?
Quando si crea un'applicazione web, oltre all'elaborazione aziendale principale, è necessario eseguire un'elaborazione secondaria comune prima e dopo l'elaborazione aziendale principale.
Ad esempio, l'autenticazione del client, il controllo dell'autorità, la registrazione, ecc.
La codifica di tale elaborazione laterale in ciascuna risorsa diventa una delle principali cause di ostacolo alla manutenibilità del software, risultando in un'applicazione difficile da mantenere.
Implementando javax.servlet.Filter, è possibile eseguire normalmente questa elaborazione laterale prima che la richiesta venga passata alla classe servlet.
Inoltre, poiché le impostazioni dei filtri possono essere eseguite in web.xml, puoi aggiungere o eliminare filtri in modo flessibile senza modificare il codice sorgente.
Prova a utilizzare un filtro di registro
Utilizziamo effettivamente un filtro di registro per filtrare le richieste HTTP e analizzarle.
Questa voltaTomcatUtilizzeremo l'applicazione di esempio disponibile fin dall'inizio.
È possibile eseguire immediatamente questo filtro effettuando le seguenti impostazioni.
2. Posizionare il file di classe compilato in "/examples/WEB-INF/classes".
3.Impostare la seguente definizione in web.xml.
LogFilter LogFilter logging.Level BENE LogFilter /*
*Il modello URL quando si utilizza il framework Struts è il seguente.
*.Fare
Controllare i risultati dell'output del registro dell'esecuzione della schermata Esempio sessioni.
Informazioni sul registro di output e livello di registro
●Contenuto dell'output del registro
Registrare le informazioni | livello di registro |
---|---|
Informazioni sui cookie | BENE |
Informazioni sull'intestazione HTTP | BENE |
HTTPAltre informazioni | BENE |
Parametri della richiesta HTTP | CONFIG |
oggetto ambito richiesta | CONFIG |
oggetto con ambito sessione | CONFIG |
Utilizzo della memoria prima e dopo le richieste | CONFIG |
Informazioni sulla transizione dello schermo | INFORMAZIONI |
È preferibile utilizzare i livelli di registro come segue.
- FINE: genera il registro più dettagliato. Impostalo se vuoi analizzare in dettaglio la richiesta HTTP.
- CONFIG... Restituisce un registro piuttosto dettagliato. È una buona idea mantenerlo a questo livello durante il periodo di sviluppo.
- INFO: emette solo informazioni sulla transizione dello schermo.
●Come modificare il livello di registro
È possibile modificare il livello di output del registro impostando il parametro di inizializzazione logging.Level.
esempio:
logging.Level INFORMAZIONI
Codice sorgente
importa javax.servlet.Filter;
import javax.servlet.FilterChain;
importare javax.servlet.FilterConfig;
import javax.servlet.ServletException;
importa javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
importa javax.servlet.http.Cookie;
importa javax.servlet.http.HttpServletRequest;
importa javax.servlet.http.HttpServletResponse;
importa javax.servlet.http.HttpSession;
/**
* Implementa javax.servlet.Filter per analizzare il contenuto delle richieste HTTP e dei log di output
* Classe di filtro.
*/
la classe pubblica LogFilter implementa il filtro {
Logger statico privato logger =
Logger.getLogger(LogFilter.class.getName());
stringa finale statica privata LINE_SEPA =
System.getProperty("line.separator");
stringa finale statica privata NEXT_PAGE = “LogFilter.NEXT_PAGE”;
/**
* Inizializza questo filtro di registro.
* Mappatura @param
*/
public void init (mappatura FilterConfig) {
String str = mapping.getInitParameter(“logging.Level”);
System.out.println(“Imposta il livello di registro su “+str+”.”);
Livello livello = nullo;
Tentativo {
livello = Livello.parse(str);
} catch (Eccezione e) {
e.printStackTrace();
livello = Livello.INFO;
}
LogManager.getLogManager().reset();
Gestore gestore = new CustomConsoleHandler();
handler.setFormatter(new CustomFormatter());
handler.setLevel(livello);
logger.setLevel(livello);
logger.getParent().addHandler(gestore);
}
/**
* Questo è un filtro che genera log.
* @param request Richiesta HTTP in fase di elaborazione
* Risposta @param Risposta HTTP generata
* @catena param
*/
public void doFilter(ServletRequest _request, ServletResponse _response,
catena FilterChain) lancia IOException, ServletException {
// --------------------" Preelaborazione "
Richiesta HttpServletRequest = (HttpServletRequest) _request;
Risposta HttpServletResponse = (HttpServletResponse) _response;
if (logger.isLoggable(Level.CONFIG)) {
logger.config(
“============ Richiedi inizio!!”
+"ID discussione:"
+ Thread.currentThread().hashCode()
+ ” ========================================================”);
}
// utilizzo della memoria
Stringa actionMemory = null;
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = getMemoryInfo(” ”
+ new Time(System.currentTimeMillis()) + ”Richiesta[precedente]”);
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(“Informazioni sui cookie” + getCookieInfo(richiesta));
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("Informazioni sull'intestazione HTTP" + getHeadersInfo(richiesta));
}
if (logger.isLoggable(Level.FINE)) {
registratore
.fine(“Altre informazioni HTTP” + getRequestOtherInfo(richiesta));
}
if (logger.isLoggable(Level.CONFIG)) {
String reqlog = getRequestParametersInfo(richiesta);
logger.config("Parametri richiesta HTTP" + reqlog);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config("oggetto ambito richiesta"
+ getRequestAttributeInfo(richiesta));
}
if (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request,true);
logger.config("oggetto ambito sessione (prima dell'elaborazione della richiesta)"
+ registro della sessione);
}
// chiama il filtro successivo
chain.doFilter(richiesta, risposta);
// -------------------- "Post produzione"
if (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request,false);
logger.config("oggetto ambito sessione (dopo l'elaborazione della richiesta)"
+ registro della sessione);
}
// utilizzo della memoria
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = "Utilizzo della memoria prima e dopo la richiesta"+LINE_SEPA
+ actionMemory + LINE_SEPA
+ getMemoryInfo(” ” + new Time(System.currentTimeMillis())
+ "richiesta[dopo]");
logger.config(actionMemory+LINE_SEPA);
}
// Informazioni sulla transizione dello schermo
if (logger.isLoggable(Level.INFO)) {
String nextPage = (String) request.getAttribute(NEXT_PAGE);
if (paginasuccessiva == null ||paginasuccessiva.lunghezza() == 0) {
nextPage = request.getRequestURI();
}
logger.info("PAGINA_NEXT=[" + Paginasuccessiva + "], "
+ “IP_ADDRESS=[” + request.getRemoteAddr() + “], ”
+ “SESSION_ID=[” + request.getSession().getId() + “], ”
+ “USER-AGENT=[” + request.getHeader(“user-agent”) + “]”);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config(
“============ Fine richiesta!!”
+"ID discussione:"+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
public void destroy() {
}
// ---------- Metodo privato di seguito -----------
private static String getMemoryInfo(String message) {
DecimalFormat dFromat = nuovo DecimalFormat("#,###KB");
lungo libero = Runtime.getRuntime().freeMemory() / 1024;
lungo totale = Runtime.getRuntime().totalMemory() / 1024;
lungo massimo = Runtime.getRuntime().maxMemory() / 1024;
utilizzato a lungo = totale – gratuito;
Stringa msg = messaggio + " : " + "totale=" + dFromat.format(totale) + ", "
+ “Quantità utilizzata=” + dFromat.format(usato) + ” (“” + (usato * 100 / totale)
+ “%), massimo disponibile=" + dFromat.format(max);
messaggio di ritorno;
}
/**
* Invia tutte le intestazioni delle richieste al registro.
*/
stringa statica privata getHeadersInfo (richiesta HttpServletRequest) {
Buff StringBuffer = nuovo StringBuffer(LINE_SEPA);
Enumerazione headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
buff.append(” “);
buff.append(nomeintestazione);
buff.append(“=");
buff.append(request.getHeader(nomeintestazione));
buff.append(LINE_SEPA);
}
ritorna buff.toString();
}
stringa statica privata getCookieInfo (richiesta HttpServletRequest) {
Buff StringBuffer = new StringBuffer();
Cookie[] cookies = request.getCookies();
se (cookie == null) {
ritorno "";
}
for (int i = 0; i < cookie.lunghezza; 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);
}
ritorna buff.toString();
}
stringa statica privata getRequestParametersInfo(richiesta HttpServletRequest) {
Buff StringBuffer = nuovo StringBuffer(LINE_SEPA);
Mappa mappa = convertRequest(richiesta);
TreeMap trr = nuova TreeMap(mappa);
Iterator itr = trr.keySet().iterator();
mentre (itr.hasNext()) {
Chiave stringa = (Stringa) itr.next();
buff.append(” “);
buff.append(chiave);
buff.append(“=");
Valore oggetto = map.get(chiave);
String[] valori = (String[]) valore;
if (valori.lunghezza == 1) {
buff.append(valori[0]);
} altro {
// L'array di stringhe viene convertito
String strValue = strato(valori);
buff.append(strValore);
}
buff.append(LINE_SEPA);
}
ritorna buff.toString();
}
stringa statica privata getRequestAttributeInfo(richiesta HttpServletRequest) {
Buff StringBuffer = nuovo StringBuffer(LINE_SEPA);
Enumerazione e = request.getAttributeNames();
while (e.hasMoreElements()) {
Nome stringa = (Stringa) e.nextElement();
buff.append(” nome=” + nome + “, attributoClass= ”
+ request.getAttribute(nome).getClass().getName()
+ “, toString() = ” + request.getAttribute(nome)
+LINEA_SEPA);
}
ritorna buff.toString();
}
stringa statica privata getRequestOtherInfo (richiesta HttpServletRequest) {
Buff StringBuffer = 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);
ritorna buff.toString();
}
private static String getSessionInfo(richiesta HttpServletRequest, booleano prima) {
Sessione HttpSession = request.getSession();
Buff StringBuffer = new StringBuffer();
buff.append(LINE_SEPA);
se (prima) {
buff.append(” session.isNew() = ” + session.isNew());
buff.append(LINE_SEPA);
buff.append(” session.getId() = ” + session.getId());
buff.append(LINE_SEPA);
}
Enumerazione e = session.getAttributeNames();
while (e.hasMoreElements()) {
String sessionName = (String) e.nextElement();
String sessionClassName = session.getAttribute(sessionName)
.getClass().getName();
buff.append(” nome =” + nomesessione + “, valore =”
+ session.getAttribute(sessionName) + ", attributiClass = "
+ nomeClassesessione+LINE_SEPA);
}
ritorna buff.toString();
}
convertRequest Hashtable statico privato (richiesta HttpServletRequest) {
Hashtable tempHash = new Hashtable();
Enumerazione e = request.getParameterNames();
while (e.hasMoreElements()) {
Chiave stringa = (Stringa) e.nextElement();
String[] valori = request.getParameterValues(chiave);
String[] parametriValues = new String[values.length];
for (int i = 0; i < valori.lunghezza; i++) {
parametriValori[i] = convUnicode(valori[i]);
}
tempHash.put(chiave, parametriValori);
}
restituire tempHash;
}
strato di stringa statica privata (valore oggetto) {
se (valore == null) {
restituire "null";
} else if (valore istanza di String[]) {
restituisce convString((String[]) valore);
} altro {
restituire valore.toString();
}
}
/**
* Restituisce il contenuto dell'array di stringhe [strArray] come una stringa come quella seguente.
* “[temp1,temp2,temp3]”
* @param strArray Array di stringhe da valutare
* @return Stringa dopo la conversione
*/
private static String convString(String[] strArray) {
if (strArray == null)
restituire null;
Buff StringBuffer = new StringBuffer(“[“);
for (int i = 0; i < strArray.length; i++) {
buff.append(strArray[i] + “, “);
}
buff.delete(buff.length() – 2, buff.length());
buff.append(“]”);
ritorna buff.toString();
}
/**
* Converti [str] in Unicode.
* @paramstr
* @ritorno
*/
private static String convUnicode(String str) {
se (str == null)
restituire null;
Tentativo {
restituisce new String(str.getBytes("8859_1"), "JISAutoDetect");
} catch (UnsupportedEncodingException e) {
lancia una nuova RuntimeException(e);
}
}
// ———————————————————————–
la classe statica CustomFormatter estende Formatter {
modello di stringa finale statico = "aaaa/MM/gg HH:mm:ss";
Formato stringa pubblica sincronizzata (record LogRecord) {
Buff StringBuffer = new StringBuffer();
// imposta data e ora
Data data = nuova data();
date.setTime(record.getMillis());
Formattatore SimpleDateFormat = nuovo SimpleDateFormat(modello);
buf.append(formatter.format(data));
buf.append(“:”);
// imposta il livello
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(“:”);
buf.append(record.getMessage());
buf.append(LINE_SEPA);
ritorna buf.toString();
}
}
la classe statica CustomConsoleHandler estende StreamHandler {
pubblico CustomConsoleHandler() {
super();
setOutputStream(System.out);
}
/**
* Emette un LogRecord.
* Inizialmente, le richieste di registrazione vengono inviate a un oggetto Logger.
* e questo oggetto inizializza LogRecord e
*Reindirizzato qui.
*
* @param record Descrizione dell'evento di registro. i record null vengono semplicemente ignorati
* e non verrà inviata alcuna notifica.
*/
pubblicazione pubblica nulla (record LogRecord) {
super.pubblica(registra);
sciacquone();
}
/**
* Sostituisci StreamHandler.close per svuotare, ma
* Il flusso di output non è chiuso. In altre parole, System.err non è chiuso.
*/
chiusura pubblica vuota() {
sciacquone();
}
}
}