如何为Jersey中特定REST API(/api/foo)配置自定义ExceptionMapper
让CustomJsonMapperException仅作用于/api/foo接口的方案
方案一:在ExceptionMapper内判断请求路径
直接在CustomJsonMapperException中注入请求上下文,判断当前请求的路径是否为/api/foo,仅在匹配时返回自定义响应,否则交给默认异常处理器处理:
@Priority(1) @Provider public class CustomJsonMapperException implements ExceptionMapper<JsonMappingException> { @Context private UriInfo uriInfo; private static final String MY_CUSTOM_MESSAGE = "自定义JSON映射错误信息"; @Override public Response toResponse(JsonMappingException bex) { String requestPath = uriInfo.getAbsolutePath().getPath(); // 匹配/api/foo及其子路径(如/api/foo/detail) if (requestPath.startsWith("/api/foo")) { return Response.status(400).entity(MY_CUSTOM_MESSAGE).build(); } else { // 抛出异常,交由Jersey默认的ExceptionMapper处理 throw new WebApplicationException(bex); } } }
方案二:使用DynamicFeature动态控制Mapper注册
通过DynamicFeature根据资源接口的路径,动态决定是否注册自定义ExceptionMapper,更贴合REST资源的设计规范:
- 实现DynamicFeature类:
@Provider public class FooExceptionMapperFeature implements DynamicFeature { @Override public void configure(ResourceInfo resourceInfo, FeatureContext context) { // 获取资源类的@Path注解值(对应/api/后的路径部分) Path classPath = resourceInfo.getResourceClass().getAnnotation(Path.class); // 获取资源方法的@Path注解值 Path methodPath = resourceInfo.getResourceMethod().getAnnotation(Path.class); // 判断当前资源是否属于/api/foo路径 boolean isFooResource = (classPath != null && "/foo".equals(classPath.value())) || (methodPath != null && methodPath.value().startsWith("/foo")); if (isFooResource) { // 仅对/api/foo相关接口注册自定义Mapper context.register(CustomJsonMapperException.class); } else { // 对其他接口排除该自定义Mapper context.property("jersey.config.server.provider.exclude", CustomJsonMapperException.class.getName()); } } }
- 确保
FooExceptionMapperFeature在com.restapi包下(已加@Provider注解,会被Jersey自动扫描到)。
注意事项
- 方案一中的
@Priority(1)保证自定义Mapper优先被调用,路径不匹配时抛出WebApplicationException会触发Jersey寻找下一个优先级的异常处理器。 - 方案二的动态配置方式,能更精准地绑定到指定资源,避免硬编码路径判断。
内容的提问来源于stack exchange,提问作者Janny
相关产品推荐
相关产品推荐

