Analizar solicitudes HTTP con filtros de registro de Java
javax.servlet.filtroUna forma conveniente de implementar y analizar el contenido de solicitudes HTTP y registros de salida.FiltrarPresentando la clase.
Este filtro de registro utiliza "java.util.logging.Logger" para la salida del registro y puede cambiar la salida de información cambiando el nivel de registro.
¿Qué es javax.servlet.Filter?
Al crear una aplicación web, además del procesamiento comercial principal, es necesario realizar un procesamiento secundario común antes y después del procesamiento comercial principal.
Por ejemplo, autenticación de cliente, verificación de autoridad, registro, etc.
La codificación de dicho procesamiento lateral en cada recurso se convierte en una de las principales causas de obstaculizar la capacidad de mantenimiento del software, lo que da como resultado una aplicación difícil de mantener.
Al implementar javax.servlet.Filter, normalmente puede realizar este procesamiento lateral antes de que la solicitud se pase a la clase de servlet.
Además, dado que la configuración de los filtros se puede realizar en web.xml, puede agregar o eliminar filtros de manera flexible sin cambiar el código fuente.
Intente usar un filtro de registro
De hecho, usemos un filtro de registro para filtrar las solicitudes HTTP y analizarlas.
Esta vezGatoUsaremos la aplicación de ejemplos que está disponible desde el principio.
Puede ejecutar este filtro inmediatamente realizando las siguientes configuraciones.
2. Coloque el archivo de clase compilado en "/examples/WEB-INF/classes".
3.Establezca la siguiente definición en web.xml.
Filtro de registro Filtro de registro registro.Nivel BIEN Filtro de registro /*
*El patrón de URL cuando se utiliza el marco Struts es el siguiente.
*.hacer
Verifique los resultados de salida del registro al ejecutar la pantalla de ejemplo de sesiones.
Información de registro de salida y nivel de registro
●Registrar contenido de salida
Información de registro | nivel de registro |
---|---|
Información de cookies | BIEN |
información del encabezado HTTP | BIEN |
HTTPOtra información | BIEN |
Parámetros de solicitud HTTP | CONFIGURAR |
objeto de alcance de solicitud | CONFIGURAR |
objeto de ámbito de sesión | CONFIGURAR |
Uso de memoria antes y después de las solicitudes. | CONFIGURAR |
Información de transición de pantalla | INFORMACIÓN |
Lo mejor es utilizar niveles de registro de la siguiente manera.
- FINE: genera el registro más detallado. Configúrelo si desea analizar la solicitud HTTP en detalle.
- CONFIG... Genera un registro algo detallado. Es una buena idea mantenerlo en este nivel durante el período de desarrollo.
- INFO: genera solo información de transición de pantalla.
●Cómo cambiar el nivel de registro
Puede cambiar el nivel de salida del registro configurando el parámetro de inicialización logging.Level.
ejemplo:
registro.Nivel INFORMACIÓN
Código fuente
importar javax.servlet.Filter;
importar javax.servlet.FilterChain;
importar javax.servlet.FilterConfig;
importar javax.servlet.ServletException;
importar javax.servlet.ServletRequest;
importar javax.servlet.ServletResponse;
importar javax.servlet.http.Cookie;
importar javax.servlet.http.HttpServletRequest;
importar javax.servlet.http.HttpServletResponse;
importar javax.servlet.http.HttpSession;
/**
* Implementar javax.servlet.Filter para analizar el contenido de las solicitudes HTTP y los registros de salida.
* Clase de filtro.
*/
la clase pública LogFilter implementa el filtro {
registrador registrador estático privado =
Logger.getLogger(LogFilter.class.getName());
Cadena final estática privada LINE_SEPA =
System.getProperty(“línea.separador”);
Cadena final estática privada NEXT_PAGE = “LogFilter.NEXT_PAGE”;
/**
* Inicialice este filtro de registro.
* @param mapeo
*/
inicio público vacío (mapeo FilterConfig) {
Cadena cadena = mapeo.getInitParameter(“logging.Level”);
System.out.println(“Establezca el nivel de registro en “+str+”.”);
Nivel nivel = nulo;
intentar {
nivel = Nivel.parse(cadena);
} captura (Excepción e) {
e.printStackTrace();
nivel = Nivel.INFO;
}
LogManager.getLogManager().reset();
Controlador controlador = new CustomConsoleHandler();
handler.setFormatter(nuevo CustomFormatter());
handler.setLevel(nivel);
logger.setLevel(nivel);
logger.getParent().addHandler(controlador);
}
/**
* Este es un filtro que genera registros.
* Solicitud @param Solicitud HTTP en proceso
* @param respuesta Se genera respuesta HTTP
* cadena @param
*/
doFilter público vacío (ServletRequest _request, ServletResponse _response,
cadena FilterChain) arroja IOException, ServletException {
// --------------------" Preprocesamiento "
Solicitud HttpServletRequest = (HttpServletRequest) _request;
Respuesta HttpServletResponse = (HttpServletResponse) _respuesta;
si (logger.isLoggable(Nivel.CONFIG)) {
registrador.config(
“============= ¡¡Solicitar inicio!!”
+”ID del hilo:”
+ Hilo.currentThread().hashCode()
+ ” ========================================================”);
}
// uso de memoria
Cadena actionMemory = nulo;
si (logger.isLoggable(Nivel.CONFIG)) {
actionMemory = getMemoryInfo(” ”
+ nuevo Tiempo(System.currentTimeMillis()) + "Solicitud[anterior]");
}
if (logger.isLoggable(Nivel.FINO)) {
logger.fine(“Información de cookies” + getCookieInfo(solicitud));
}
if (logger.isLoggable(Nivel.FINO)) {
logger.fine(“información del encabezado HTTP” + getHeadersInfo(solicitud));
}
if (logger.isLoggable(Nivel.FINO)) {
registrador
.fine(“otra información HTTP” + getRequestOtherInfo(solicitud));
}
si (logger.isLoggable(Nivel.CONFIG)) {
String reqlog = getRequestParametersInfo(solicitud);
logger.config(“parámetros de solicitud HTTP” + reqlog);
}
si (logger.isLoggable(Nivel.CONFIG)) {
logger.config(“objeto de alcance de solicitud”
+ getRequestAttributeInfo(solicitud));
}
si (logger.isLoggable(Nivel.CONFIG)) {
String sessionlog = getSessionInfo(solicitud,verdadero);
logger.config(“objeto de alcance de sesión (antes del procesamiento de la solicitud)”
+ registro de sesión);
}
// llama al siguiente filtro
chain.doFilter (solicitud, respuesta);
// -------------------- "Postprocesamiento"
si (logger.isLoggable(Nivel.CONFIG)) {
String sessionlog = getSessionInfo(solicitud,falso);
logger.config(“objeto de alcance de sesión (después del procesamiento de la solicitud)”
+ registro de sesión);
}
// uso de memoria
si (logger.isLoggable(Nivel.CONFIG)) {
actionMemory = "Uso de memoria antes y después de la solicitud"+LINE_SEPA
+ memoria de acción + LINE_SEPA
+ getMemoryInfo(” ” + nueva hora(System.currentTimeMillis())
+ "solicitud[después]");
logger.config(actionMemory+LINE_SEPA);
}
// Información de transición de pantalla
if (logger.isLoggable(Nivel.INFO)) {
Cadena nextPage = (Cadena) request.getAttribute(NEXT_PAGE);
if (página siguiente == nulo || página siguiente.length() == 0) {
página siguiente = request.getRequestURI();
}
logger.info ("NEXT_PAGE = [" + página siguiente + "], "
+ “IP_ADDRESS=[” + request.getRemoteAddr() + “], ”
+ “ID_SESSION=[” + solicitud.getSession().getId() + “], ”
+ “USUARIO-AGENTE=[” + request.getHeader(“usuario-agente”) + “]”);
}
si (logger.isLoggable(Nivel.CONFIG)) {
registrador.config(
“============= ¡¡Solicitud final!!”
+”ID del hilo:”+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
destrucción de vacío público () {
}
// ---------- Método privado a continuación -----------
Cadena estática privada getMemoryInfo (mensaje de cadena) {
Formato Decimal dFromat = nuevo Formato Decimal(“#,###KB”);
largo libre = Runtime.getRuntime().freeMemory() / 1024;
total largo = Runtime.getRuntime().totalMemory() / 1024;
largo máximo = Runtime.getRuntime().maxMemory() / 1024;
usado durante mucho tiempo = total – gratis;
Mensaje de cadena = mensaje + ”:” + “total=” + dFromat.format(total) + “,”
+ “Cantidad usada=” + dFromat.format(usado) + ” (” + (usado * 100 / total)
+ “%), máximo disponible =” + dFromat.format(max);
devolver mensaje;
}
/**
* Envíe todos los encabezados de solicitud al registro.
*/
Cadena estática privada getHeadersInfo (solicitud HttpServletRequest) {
Mejora de StringBuffer = nuevo StringBuffer(LINE_SEPA);
Nombres de encabezado de enumeración = request.getHeaderNames();
mientras (headerNames.hasMoreElements()) {
Cadena headerName = (Cadena) headerNames.nextElement();
buff.append(” “);
buff.append (nombre del encabezado);
buff.append(“=");
buff.append(request.getHeader(nombre del encabezado));
buff.append(LINE_SEPA);
}
devolver buff.toString();
}
Cadena estática privada getCookieInfo (solicitud HttpServletRequest) {
Mejora de StringBuffer = nuevo StringBuffer();
Cookie[] cookies = request.getCookies();
si (cookies == nulo) {
devolver "";
}
para (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);
}
devolver buff.toString();
}
Cadena estática privada getRequestParametersInfo (solicitud HttpServletRequest) {
Mejora de StringBuffer = nuevo StringBuffer(LINE_SEPA);
Mapa mapa = convertRequest(solicitud);
TreeMap trr = nuevo TreeMap(mapa);
Iterador itr = trr.keySet().iterator();
mientras (itr.hasNext()) {
Clave de cadena = (Cadena) itr.next();
buff.append(” “);
buff.append(clave);
buff.append(“=");
Valor del objeto = map.get(clave);
Valores de cadena [] = valor (cadena []);
if (valores.longitud == 1) {
buff.append(valores[0]);
} demás {
// la matriz de cadenas se convierte
String strValue = estrato (valores);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
devolver buff.toString();
}
Cadena estática privada getRequestAttributeInfo (solicitud HttpServletRequest) {
Mejora de StringBuffer = nuevo StringBuffer(LINE_SEPA);
Enumeración e = request.getAttributeNames();
mientras (e.hasMoreElements()) {
Nombre de cadena = (Cadena) e.nextElement();
buff.append(” nombre=” + nombre + “, atributoClass=”
+ solicitud.getAttribute(nombre).getClass().getName()
+ “, toString() =” + request.getAttribute(nombre)
+LINEA_SEPA);
}
devolver buff.toString();
}
Cadena estática privada getRequestOtherInfo (solicitud HttpServletRequest) {
Mejora de StringBuffer = nuevo 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);
devolver buff.toString();
}
Cadena estática privada getSessionInfo (solicitud HttpServletRequest, booleano antes) {
Sesión HttpSession = request.getSession();
Mejora de StringBuffer = nuevo StringBuffer();
buff.append(LINE_SEPA);
si (antes) {
buff.append(” sesión.isNew() = ” + sesión.isNew());
buff.append(LINE_SEPA);
buff.append(” sesión.getId() = ” + sesión.getId());
buff.append(LINE_SEPA);
}
Enumeración e = session.getAttributeNames();
mientras (e.hasMoreElements()) {
Cadena nombre de sesión = (Cadena) e.nextElement();
Cadena sessionClassName = session.getAttribute(sessionName)
.getClass().getName();
buff.append(” nombre =” + nombre de sesión + “, valor =”
+ sesión.getAttribute (nombre de sesión) + “, clase de atributo =”
+ nombreClaseSesión+LINE_SEPA);
}
devolver buff.toString();
}
convertRequest de tabla hash estática privada (solicitud HttpServletRequest) {
Hashtable tempHash = nueva Hashtable();
Enumeración e = request.getParameterNames();
mientras (e.hasMoreElements()) {
Clave de cadena = (Cadena) e.nextElement();
Valores de cadena [] = request.getParameterValues (clave);
Cadena[] parámetrosValores = nueva Cadena[valores.longitud];
for (int i = 0; i < valores.longitud; i++) {
parámetrosValues[i] = convUnicode(valores[i]);
}
tempHash.put (clave, valores de parámetro);
}
devolver tempHash;
}
estrato de cadena estática privada (valor del objeto) {
si (valor == nulo) {
devolver "nulo";
} else if (valor instancia de String[]) {
devolver convString((String[]) valor);
} demás {
valor de retorno.toString();
}
}
/**
* Devuelve el contenido de la matriz de cadenas [strArray] como una cadena como la siguiente.
* “[temp1,temp2,temp3]”
* @param strArray Matriz de cadenas a evaluar
* @return Cadena después de la conversión
*/
Cadena estática privada convString(String[] strArray) {
si (strArray == nulo)
devolver nulo;
Mejora de StringBuffer = nuevo StringBuffer(“[“);
para (int i = 0; i < strArray.length; i++) {
buff.append(strArray[i] + “, “);
}
buff.delete(buff.length() – 2, buff.length());
buff.append(“]”);
devolver buff.toString();
}
/**
* Convertir [cadena] a Unicode.
* @param str
* @devolver
*/
cadena estática privada convUnicode (cadena cadena) {
si (cadena == nula)
devolver nulo;
intentar {
devolver nueva cadena (str.getBytes ("8859_1"), "JISAutoDetect");
} captura (UnsupportedEncodingException e) {
lanzar nueva RuntimeException(e);
}
}
// ———————————————————————–
clase estática CustomFormatter extiende Formateador {
Patrón de cadena final estático = “aaaa/MM/dd HH:mm:ss”;
formato de cadena pública sincronizada (registro LogRecord) {
StringBuffer buf = nuevo StringBuffer();
//establecer fecha y hora
Fecha fecha = nueva Fecha();
fecha.setTime(record.getMillis());
Formateador SimpleDateFormat = nuevo SimpleDateFormat(patrón);
buf.append(formateador.formato(fecha));
buf.append(“:”);
// establecer nivel
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(“:”);
buf.append(record.getMessage());
buf.append(LINE_SEPA);
devolver buf.toString();
}
}
clase estática CustomConsoleHandler extiende StreamHandler {
público CustomConsoleHandler() {
súper();
setOutputStream(System.out);
}
/**
* Emite un LogRecord.
* Inicialmente, las solicitudes de registro se envían a un objeto Logger.
* y este objeto inicializa LogRecord y
*Redirigido aquí.
*
* @param record Descripción del evento de registro. los registros nulos simplemente se ignoran
* y no se enviará ninguna notificación.
*/
publicación pública vacía (registro LogRecord) {
super.publicar(registro);
enjuagar();
}
/**
* Anule StreamHandler.close para vaciar, pero
* El flujo de salida no está cerrado. En otras palabras, System.err no está cerrado.
*/
cierre público vacío() {
enjuagar();
}
}
}