Estoy tratando de informar sobre todos los códigos de estado HTTP de volver de mi aplicación web. Sin embargo, el código de estado no parece ser accesible a través de ServletResponse, o incluso si lo echo a un HttpServletResponse. ¿Hay alguna forma de acceder a este valor dentro de un ServletFilter?¿Cómo puedo obtener el código de estado HTTP de un ServletResponse en un ServletFilter?
Respuesta
En primer lugar, tiene que guardar el código de estado en un lugar accesible. La mejor manera de envolver la respuesta con su puesta en práctica y mantenerlo allí:
public class StatusExposingServletResponse extends HttpServletResponseWrapper {
private int httpStatus;
public StatusExposingServletResponse(HttpServletResponse response) {
super(response);
}
@Override
public void sendError(int sc) throws IOException {
httpStatus = sc;
super.sendError(sc);
}
@Override
public void sendError(int sc, String msg) throws IOException {
httpStatus = sc;
super.sendError(sc, msg);
}
@Override
public void setStatus(int sc) {
httpStatus = sc;
super.setStatus(sc);
}
public int getStatus() {
return httpStatus;
}
}
Para utilizar este contenedor, es necesario agregar un filtro de servlet, fuera usted puede hacer su reporte:
public class StatusReportingFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
StatusExposingServletResponse response = new StatusExposingServletResponse((HttpServletResponse)res);
chain.doFilter(req, response);
int status = response.getStatus();
// report
}
public void init(FilterConfig config) throws ServletException {
//empty
}
public void destroy() {
// empty
}
}
Escribir una HttpServletResponseWrapper y anular todas las setStatus (sendError),(), métodos y sendRedirect() para registrar todo. Escriba un filtro que intercambia el contenedor para el objeto de respuesta en cada solicitud.
una cosa que falta de la respuesta de David anterior es que también se debe anular la otra forma de sendError:
@Override
public void sendError(int sc, String msg) throws IOException {
httpStatus = sc;
super.sendError(sc, msg);
}
Gracias William, lo he agregado a mi muestra –
desde Servlet 3.0, hay una HttpServletResponse#getStatus()
.
Por lo tanto, si hay espacio para la actualización, actualice a Servlet 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc.) y no necesita un contenedor.
chain.doFilter(request, response);
int status = ((HttpServletResponse) response).getStatus();
también tienen que incluir un contenedor para #sendRedirect, y sería mejor para inicializar el estado a '200' en lugar de '0'
private int httpStatus = SC_OK;
...
@Override
public void sendRedirect(String location) throws IOException {
httpStatus = SC_MOVED_TEMPORARILY;
super.sendRedirect(location);
}
Veo situaciones en las que su ubicación de asignación de filtros puede afectar si se activa su código de anulación. Por ejemplo, un filtro sucesivo puede no envolver su respuesta, sino reemplazarla. Además de esos escenarios, ¿se puede establecer el código de estado en la respuesta sin invocar las variantes setStatus, sendError o sendRedirect? ¿Es por eso que has inicializado el estado a 200? – 1in9ui5t
Si le pegan con un recipiente viejo entonces una solución alternativa a David Rabinowitz que utiliza el código de estado actual (en caso de que cambia después de que se ajusta con la envoltura) es:
public class StatusExposingServletResponse extends HttpServletResponseWrapper {
public StatusExposingServletResponse(HttpServletResponse response) {
super(response);
}
@Override
public void sendError(int sc) throws IOException {
super.sendError(sc);
}
@Override
public void sendError(int sc, String msg) throws IOException {
super.sendError(sc, msg);
}
@Override
public void setStatus(int sc) {
super.setStatus(sc);
}
public int getStatus() {
try {
ServletResponse object = super.getResponse();
// call the private method 'getResponse'
Method method1 = object.getClass().getMethod("getResponse");
Object servletResponse = method1.invoke(object, new Object[] {});
// call the parents private method 'getResponse'
Method method2 = servletResponse.getClass().getMethod("getResponse");
Object parentResponse = method2.invoke(servletResponse, new Object[] {});
// call the parents private method 'getResponse'
Method method3 = parentResponse.getClass().getMethod("getStatus");
int httpStatus = (Integer) method3.invoke(parentResponse, new Object[] {});
return httpStatus;
}
catch (Exception e) {
e.printStackTrace();
return HttpServletResponse.SC_ACCEPTED;
}
}
public String getMessage() {
try {
ServletResponse object = super.getResponse();
// call the private method 'getResponse'
Method method1 = object.getClass().getMethod("getResponse");
Object servletResponse = method1.invoke(object, new Object[] {});
// call the parents private method 'getResponse'
Method method2 = servletResponse.getClass().getMethod("getResponse");
Object parentResponse = method2.invoke(servletResponse, new Object[] {});
// call the parents private method 'getResponse'
Method method3 = parentResponse.getClass().getMethod("getReason");
String httpStatusMessage = (String) method3.invoke(parentResponse, new Object[] {});
if (httpStatusMessage == null) {
int status = getStatus();
java.lang.reflect.Field[] fields = HttpServletResponse.class.getFields();
for (java.lang.reflect.Field field : fields) {
if (status == field.getInt(servletResponse)) {
httpStatusMessage = field.getName();
httpStatusMessage = httpStatusMessage.replace("SC_", "");
if (!"OK".equals(httpStatusMessage)) {
httpStatusMessage = httpStatusMessage.toLowerCase();
httpStatusMessage = httpStatusMessage.replace("_", " ");
httpStatusMessage = capitalizeFirstLetters(httpStatusMessage);
}
break;
}
}
}
return httpStatusMessage;
}
catch (Exception e) {
e.printStackTrace();
return "";
}
}
private static String capitalizeFirstLetters(String s) {
for (int i = 0; i < s.length(); i++) {
if (i == 0) {
// Capitalize the first letter of the string.
s = String.format("%s%s", Character.toUpperCase(s.charAt(0)), s.substring(1));
}
if (!Character.isLetterOrDigit(s.charAt(i))) {
if (i + 1 < s.length()) {
s = String.format("%s%s%s", s.subSequence(0, i + 1),
Character.toUpperCase(s.charAt(i + 1)),
s.substring(i + 2));
}
}
}
return s;
}
@Override
public String toString() {
return this.getMessage() + " " + this.getStatus();
}
}
de advertencia: porciones de supuestos de la jerarquía de clases cuando utilizando SNE reflexión aky e introspección para llegar a los valores de datos privados.
Además de la respuesta de David, también querrá reemplazar el método de reset:
@Override
public void reset() {
super.reset();
this.httpStatus = SC_OK;
}
... así como la obsoleta setStatus (int, String)
@Override
public void setStatus(int status, String string) {
super.setStatus(status, string);
this.httpStatus = status;
}
- 1. viene el nombre de un código de estado HTTP importa
- 2. ¿Cómo se especifica un código de estado HTTP en Cakephp?
- 3. System.Net.WebException Código de estado HTTP
- 4. Net :: HTTP obtener el código fuente y el estado
- 5. ¿Cómo puedo devolver un código de estado HTTP personalizado desde un método WCF REST?
- 6. ¿Cómo puedo obtener el estado de un programa?
- 7. Cómo obtener el mensaje de estado HTTP en (py) curl?
- 8. Comprobando el código de estado HTTP en Selenium
- 9. Analizando el código de estado HTTP
- 10. ¿Cómo puedo obtener el SQL de un estado preparado?
- 11. 502 código de estado HTTP
- 12. Obtener el código HTTP de org.apache.http.HttpResponse
- 13. Webpy: cómo configurar el código de estado http a 300
- 14. Obtener la descripción del código de estado HTTP
- 15. NSUrlConnectionDelegate - Obtener códigos de estado http
- 16. Python CGI devuelve un código de estado http, como 403?
- 17. HttpClient obtener el código de estado
- 18. ¿Cómo obtener el estado de un hilo?
- 19. ¿Cómo puedo obtener el encabezado de la respuesta ya que ServletResponse(). GetHeader (cadena) no está visible?
- 20. ¿Cómo obtener el código de estado de respuesta de jQuery.ajax?
- 21. Devuelve el código de estado HTTP 201 en el matraz
- 22. devuelve un código de estado http específico con php
- 23. QtWebkit: ¿Cómo verificar el código de estado HTTP?
- 24. Cómo obtener códigos de estado HTTP numéricos en PowerShell
- 25. ¿Código de estado de Http con libcurl?
- 26. Establecer el código de estado http a XXX.X?
- 27. Cómo obtener el código de estado HTTP de <img> etiquetas
- 28. ¿Cómo se obtiene el código de estado HTTP para un dominio remoto en php?
- 29. ¿Cómo obtengo el código de estado HTTP con jQuery?
- 30. Código de estado HTTP para datos incorrectos
en el caso alguien no lee hasta el final de la página, ten cuidado con el comentario de Joel a continuación para establecer el estado predeterminado = 200 y también anular el envío de sendRedirect (..) –
Esto fue sumamente útil para una versión anterior de Tomcat que está en la especificación de Servlet 2.4. ¡Gracias! – user3621633
response.sendRedirect() está dando illegalStateExcpetion. He cancelado SendRedirect también como comentario de Joel –