gpt4 book ai didi

jsf - OmniFaces FullAjaxExceptionHandler 日志记录特化

转载 作者:行者123 更新时间:2023-12-04 18:21:06 24 4
gpt4 key购买 nike

我刚刚扩展了 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 自己的 FullAjaxExceptionHandlerFacesExceptionFilter记录所有异常以及 UUID(和 IP)肯定是一个有用的改进。这确实是一个并不罕见的业务需求。它将在下一个版本中出现。

关于jsf - OmniFaces FullAjaxExceptionHandler 日志记录特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51553394/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com