我的REST资源面临着棘手的行为。 期望的方法是期望一个复杂的json对象:
@Path(RestURIConstant.NOTIFICATION_ROOT_URI)
@Component
@Scope("request")
public class NotificationResource implements RestURIConstant {
/** Notification service. */
@Autowired
private INotificationService notificationService;
@Path(RestURIConstant.COMPLEMENT_URI)
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response processNotification(final EventDTO event)
throws BusinessException, TechnicalException {
checkParameters(event);
notificationService.processEvent(event);
return Response.ok().build();
}
}
EventDTO有两个枚举字段:notificationType和eventType:
public class EventDTO {
private ENotificationType notificationType;
private EEventType eventType;
private String eventDate;
private String userName;
//... getters, setters
}
我想要的是从任何类型的数据验证错误中映射异常,以获得带有错误代码和错误消息的json响应。在关注jax-rs jersey: Exception Mapping for Enum bound FormParam之后:
所以对于我写的ENoticationType:
public enum ENotificationEventType {
RULE,
ALARM,
ACK,
INFO;
@JsonCreator
public static ENotificationEventType fromString(final String typeCode)
throws BusinessException {
if (typeCode == null) {
throw new BusinessException(ValidationCode.VALUE_REQUIRED, "type");
}
try {
return valueOf(typeCode);
} catch (final IllegalArgumentException iae) {
throw new BusinessException(ValidationCode.UNSUPPORTED_VALUE, "type", typeCode, Arrays.toString(values()));
}
}
}
对于我写的Mapper:
@Provider
@Singleton
public class BusinessExceptionMapper implements ExceptionMapper<BusinessException> {
@Override
public Response toResponse(final BusinessException exception) {
Status status = Status.INTERNAL_SERVER_ERROR;
// If a validationCode error = unsupported version => CODE 410
if (exception.getErrorCode().equals(ValidationCode.UNSUPPORTED_API_VERSION)) {
status = Status.GONE;
} else if (exception.getErrorCode().getClass().isAssignableFrom(ValidationCode.class)) {
// If a validationCode error then BAD_REQUEST (400) HTTP
status = Status.BAD_REQUEST;
} else if (exception.getErrorCode().getClass().isAssignableFrom(NotFoundCode.class)) { // CODE 404
status = Status.NOT_FOUND;
} else if (exception.getErrorCode().getClass().isAssignableFrom(SecurityCode.class)) { // CODE 401
status = Status.UNAUTHORIZED;
} else if (exception.getErrorCode().getClass().isAssignableFrom(AdminSecurityCode.class)) { // CODE 401
status = Status.UNAUTHORIZED;
}
return Response.status(status).type(MediaType.APPLICATION_JSON)
.entity(ErrorMessageHelper.createErrorMessageHelper(
exception.getErrorCode(), exception.getMessage()))
.build();
}
我的应用程序上下文包含<context:component-scan base-package=" com.technicolor.hovis.backend.rest, com.technicolor.hovis.admin.rest" />
我已经阅读了几个与球衣中的异常映射相关的问题的答案,但在我的情况下,并不是因为映射无法识别,而是在所有情况下都没有应用:
@JsonCreator
方法,抛出相同类型的异常,但不会按预期映射此异常。所以回复如下:
<data contentType="text/plain;charset=UTF-8" contentLength="176">
<![CDATA[Unsupported type value : 'ALARN'. Expected values are [RULE, ALARM, ACK, INFO] (through reference chain: EventDTO["type"])]]>
</data>
而不是预期的:
{
"code": 6,
"message": "Unsupported type value : 'ALARN'. Expected values are [RULE, ALARM, ACK, INFO]"
}
有什么想法吗?
西里尔
答案 0 :(得分:0)
我会尝试将BusinessExceptionMapper
更改为:
public class BusinessExceptionMapper implements ExceptionMapper<Exception>
如果我理解正确,问题是当你对除了你的参数进行反序列化时,在这种情况下会抛出IOException
,而不是BusinessException
,我猜是你的自定义通知。因此,您可以延长ExceptionMapper<Exception>
或ExceptionMapper<IOException>
答案 1 :(得分:0)
我注意到当我在JSONCreator中抛出一个已检查的异常时(就像你一样),杰克逊抓住它并将其包裹在IllegalArgumentException
中,因此IllegalArgumentException
最终会在ExceptionMapper
。< / p>
也许这是你问题的原因?