簡體   English   中英

如果在處理請求主體時發生異常,則不使用Jersey自定義ExceptionMapper

[英]Jersey custom ExceptionMapper not used if exception occurs when processing request body

我的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:枚舉綁定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" />

我已經閱讀了幾個與球衣中的異常映射相關的問題的答案,但在我的情況下,並不是因為映射未被識別,而是在所有情況下都不適用:

  1. checkParameters拋出的異常被映射,結果如預期
  2. 但是如果發送了無效的枚舉,則會調用@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]"
}

任何想法 ?

西里爾

我會嘗試將BusinessExceptionMapper更改為:

public class BusinessExceptionMapper implements ExceptionMapper<Exception>

如果我理解正確,問題是當你對除了你的參數進行IOException時,在這種情況下會拋出IOException而不是我猜測的BusinessException是你的自定義通知。 因此,您可以擴展ExceptionMapper<Exception>ExceptionMapper<IOException>

我注意到當我在JSONCreator中拋出一個已檢查的異常時(就像你一樣),Jackson捕獲它並將其包裝在IllegalArgumentException ,因此IllegalArgumentException最終在ExceptionMapper結束。

也許這是你的問題的原因?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM