- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我刚刚扩展了 OminFaces 的 FullAjaxExceptionHandler
类,以添加我的项目所需的简单功能。
我所要做的就是简单地使用记录器记录所有异常,并在日志和请求中添加唯一的错误标识符(具有特定的属性名称),该标识符将与其他错误页面一起显示信息。
这将允许快速检索日志中的错误(用户只需将此“标识符”发送给支持团队)。我重写了 logException()
方法(尝试了两种重载),但它们从未被调用。查看 GitHub 上 FullAjaxExceptionHandler 的源代码,我发现它在某些特定情况下被调用。因此,我重写了 findErrorPageLocation()
方法(这是初步测试代码):
public final static String ERROR_UUID = "javax.servlet.error.uuid";
@Override
protected String findErrorPageLocation(FacesContext context, Throwable exception) {
// Retrieve error page location from base class
String location = super.findErrorPageLocation(context, exception);
// generate a unique error identifier
String uuid = UUID.randomUUID().toString();
// log into my logger
logException(context, exception, location, "["+uuid+"]: "+exception.getMessage());
// Retrieve request, put the new attribute to be shown into page and return the location
HttpServletRequest req = (HttpServletRequest)context.getExternalContext().getRequest();
req.setAttribute(ERROR_UUID, uuid);
return location;
}
在我刚刚添加的页面
<li>Error UUID: #{requestScope['javax.servlet.error.uuid']}</li>
显示错误 uuid。
嗯,它似乎有效......但我不知道这是否是做此类事情的正确地方。我更愿意仅重载 logException()
方法,因为我想要专门化的是日志记录,而不是其他行为。我做得好还是有更好的解决方案?
我使用的是普通 Java EE 7(即 JSF 2.2)、OmniFaces 2.6.9、Payara 5.181 和 Java SE 1.8.0u170。
最佳答案
FullAjaxExceptionHandler
不会记录非-Ajax JSF 请求的异常。非 Ajax JSF 请求(以及非 JSF 请求!)的异常通常会到达 servlet Filter
。
findErrorPageLocation()
方法确实在 FullAjaxExceptionHandler
之前被调用检查它是否是 Ajax 请求,因此您还可以在那里记录非 Ajax JSF 请求的异常。
但是如果您想要记录非 JSF 请求的异常,那么您仍然需要一个 servlet Filter
。在这种情况下,非 Ajax JSF 请求的异常最终将被记录两次。第一次通过findErrorPageLocation()
自定义异常处理程序的方法和 servlet 的第二次 Filter
.
理想情况下,您最好两者都有一个自定义FullAjaxExceptionHandler
和定制FacesExceptionHandler
每当您想要微调 Web 应用程序抛出的每个可能的异常的日志记录时。
因此,JSF Ajax 请求期间的异常之一:
public class CustomExceptionHandler extends FullAjaxExceptionHandler {
public CustomExceptionHandler(ExceptionHandler wrapped) {
super(wrapped);
}
@Override
protected void logException(FacesContext context, Throwable exception, String location, LogReason reason) {
String uuid = UUID.randomUUID().toString();
String ip = FacesLocal.getRemoteAddr(context);
FacesLocal.setRequestAttribute(context, "UUID", uuid);
super.logException(context, exception, location, "[%s][%s] %s", uuid, ip, reason.getMessage(), location);
}
public static class Factory extends FullAjaxExceptionHandlerFactory {
public Factory(ExceptionHandlerFactory wrapped) {
super(wrapped);
}
@Override
public ExceptionHandler getExceptionHandler() {
return new CustomExceptionHandler(getWrapped().getExceptionHandler());
}
}
}
映射于 faces-config.xml
作为
<factory>
<exception-handler-factory>com.example.CustomExceptionHandler$Factory</exception-handler-factory>
</factory>
还有一个用于所有其他请求期间的异常(exception)情况:
@WebFilter(filterName="customExceptionFilter")
public class CustomExceptionFilter extends FacesExceptionFilter {
private static final Logger logger = Logger.getLogger(CustomExceptionHandler.class.getName());
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) throws ServletException, IOException {
try {
super.doFilter(request, response, session, chain);
}
catch (Exception e) {
String uuid = UUID.randomUUID().toString();
String ip = Servlets.getRemoteAddr(request);
request.setAttribute("UUID", uuid);
logger.log(Level.SEVERE, String.format("[%s][%s]", uuid, ip), e);
throw e;
}
}
}
映射于 web.xml
作为第一个<filter-mapping>
条目:
<filter-mapping>
<filter-name>customExceptionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
拥有 OmniFaces 自己的 FullAjaxExceptionHandler
和FacesExceptionFilter
记录所有异常以及 UUID(和 IP)肯定是一个有用的改进。这确实是一个并不罕见的业务需求。它将在下一个版本中出现。
关于jsf - OmniFaces FullAjaxExceptionHandler 日志记录特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51553394/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!