使用Resteasy异常映射时,如何避免应用日志出现冗余异常?
解决EJB中未认证请求的冗余异常日志问题
问题场景
客户端发起未携带认证信息的请求时(属于标准Basic Auth流程的第一步),服务端虽能通过ExceptionMapper返回正确的401认证质询响应,但JBoss的EJB容器会将MissingCredentialsException的完整异常栈以ERROR级别写入日志,每次请求都会生成几百行冗余日志,严重淹没有效日志信息。
相关代码片段
- REST服务类
@Stateless public class MyRestService { @GET @Path("/allRoles") @Produces("application/json") public List<String> getAllRoles(@Context HttpServletRequest httpServletRequest) throws InvalidUserCredentialsException, MissingCredentialsException { if(httpServletRequest.getHeader("Authorization") == null) throw new MissingCredentialsException(); // 后续业务逻辑 } }
- 自定义异常类
public class MissingCredentialsException extends RuntimeException { private static final long serialVersionUID = 3388868131554531339L; }
- 异常映射器
@Provider public class MissingCredentialsExceptionMapper implements ExceptionMapper<MissingCredentialsException> { @Override public Response toResponse(MissingCredentialsException exception) { return Response.serverError() .header("WWW-Authenticate", "Basic realm=\"nexus\"") .status(Response.Status.UNAUTHORIZED) .type(MediaType.TEXT_PLAIN) .entity("Basic authentication is required!") .build(); } }
解决方案
方案1:将自定义异常改为受检异常
EJB容器默认会对未捕获的RuntimeException输出ERROR级日志,而受检异常若在方法签名中声明,容器不会自动记录异常栈。
修改异常类:
// 改为继承Exception,而非RuntimeException public class MissingCredentialsException extends Exception { private static final long serialVersionUID = 3388868131554531339L; }
保持REST方法的throws声明不变,异常映射器可正常捕获处理该异常,同时EJB容器不再输出冗余日志。
方案2:配置JBoss日志过滤规则
若不想修改异常类型,可通过JBoss的日志配置文件(如standalone.xml或domain.xml)添加过滤规则,抑制org.jboss.as.ejb3.invocation日志记录器对MissingCredentialsException的ERROR级输出。
在日志子系统中添加过滤器:
<subsystem xmlns="urn:jboss:domain:logging:8.0"> <!-- 保留原有日志配置 --> <logger category="org.jboss.as.ejb3.invocation"> <level name="ERROR"/> <filter-spec value="not(match("WFLYEJB0034:.*MissingCredentialsException"))"/> </logger> </subsystem>
该规则会匹配包含WFLYEJB0034和MissingCredentialsException的日志消息,将其过滤以避免冗余输出。
内容的提问来源于stack exchange,提问作者David Hladky
相关产品推荐
相关产品推荐

