Как передать пользовательское сообщение об ошибке с помощью пользовательской десериализации в десериализации Джексона

У меня есть класс pojo, в котором один из флагов isControl имеет логический тип.

Когда это свойство получает не логическое значение, отличное от true или false, fastxml jackson автоматически преобразует входное значение в true. Итак, я написал класс Custom Deserializer, следуя Jackson Deserialize пользовательскому логическому свойству json

Чтобы показать пользовательское сообщение об ошибке вызывающему абоненту, я написал свой собственный класс сообщений об ошибках, который показывает пользовательское сообщение (Примечание: я не могу показать пользовательское сообщение об ошибке через десериализатор Jackson, поэтому я написал собственный класс). Класс исключения для отображения пользовательского сообщения).

Но теперь моя проблема заключается в том, что когда элемент управления возвращается к методу установки, он содержит значение null в случае неправильного ввода, когда Джексон выдает исключение в моем журнале консоли. Я хочу подавить это исключение в журналах, но если я сохраняю блок catch, фактическая транзакция передается.

Определенно должен быть лучший способ сделать это для отображения пользовательского сообщения об ошибке в случае неправильного ввода в логическое поле. Я не хочу менять тип данных своего логического поля на объект, поскольку мне нужно изменить код во многих местах. Пожалуйста, посоветуйте.

Control.java

@JsonDeserialize(using = BooleanKeyDeserializer.class)

private Boolean isControlEnabled;
public Boolean getIsControlEnabled() {
        return isControlEnabled;
    }

public void setIsControlEnabled(Boolean isControlEnabled) throws BadRequestException {
        System.out.println("------before setIsControlEnabled##: " + isControlEnabled);
        if (isControlEnabled instanceof Boolean) {              
                this.isControlEnabled =((Boolean)isControlEnabled).booleanValue();
        }else{
                throw new BadRequestException("boolean field should be either true|false");//Exception is getting thrown here since BooleanKeyDeserializer returns null value for wrong input
        }

BooleanKeyDeserializer.java

public class BooleanKeyDeserializer extends JsonDeserializer<Boolean>{

    public static final Logger log = LoggerFactory
            .getLogger(BooleanKeyDeserializer.class);
final protected Class<?> _valueClass = Boolean.class;

    @Override
    public Boolean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
            JsonProcessingException {
        try {
            return _parseBooleanPrimitive2(jp, ctxt);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            log.debug("Wrong input is passed for a boolean field");
        }
        return null;
    }

    protected final boolean _parseBooleanPrimitive2(JsonParser jp, DeserializationContext ctxt)
            throws Exception {
        System.out.println("----------Parse Boolean------------");
        JsonToken t = jp.getCurrentToken();

        if (t == JsonToken.VALUE_TRUE) {
            return true;
        }
        if (t == JsonToken.VALUE_FALSE) {
            return false;
        }        
        if (t == JsonToken.VALUE_NUMBER_INT) {         
          throw new BadRequestException("control flag should be either true|false");
        }
        if (t == JsonToken.VALUE_NULL) {
            throw new BadRequestException("control flag should be either true|false");
        }
        if (t == JsonToken.VALUE_STRING) {
            String text = jp.getText().trim();
            if ("true".equalsIgnoreCase(text)) {
                return true;
            }
            if ("false".equalsIgnoreCase(text) || text.length() == 0) {
                return Boolean.FALSE;
            }            
            throw ctxt.weirdStringException(text, _valueClass, "control flag should be true|false");
        }
        if(!t.isBoolean()){
            throw new BadRequestException("control flag should be either true|false");
        }
        // Otherwise, no can do:
        throw ctxt.mappingException(_valueClass);
    }

    @Override
    public Boolean getNullValue(DeserializationContext ctxt) {
        throw new BadRequestException("control flag should be either true|false");
    }

Журнал консоли:

----------Parse Boolean------------
10:34:51.501 [tomcat-http--32] DEBUG c.v.i.v.d.v.BooleanKeyDeserializer - Wrong input is passed for a boolean field
10:35:21.908 [tomcat-http--32] DEBUG o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Error resolving argument [0] 
org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: boolean field should be either true|false (through reference chain: 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:229) ~[spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:213) ~[spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:197) ~[spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:147) ~[spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:125) ~[spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99) ~[spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) [spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) [spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [servlet-api.jar:na]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [catalina.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:na]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.0.33.A]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [catalina.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:na]
    at com.visa.ip.vctc.services.logging.PerformanceFilterNonRealTime.doFilterInternal(PerformanceFilterNonRealTime.java:55) [ip_vctc_services-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [catalina.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:na]
    at com.visa.ip.vctc.services.logging.CorrelationLoggingFilter.doFilterInternal(CorrelationLoggingFilter.java:58) [ip_vctc_services-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [catalina.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:na]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) [catalina.jar:na]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:na]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [catalina.jar:na]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [catalina.jar:na]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:na]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [catalina.jar:na]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:na]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [catalina.jar:na]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-coyote.jar:8.0.33.A]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-coyote.jar:8.0.33.A]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:277) [tomcat-coyote.jar:8.0.33.A]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_101]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_101]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.33.A]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_101]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: boolean field should be either true|false (through reference chain: 
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:564) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:548) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:339) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:339) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[jackson-databind-2.6.3.jar:2.6.3]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2810) ~[jackson-databind-2.6.3.jar:2.6.3]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:226) ~[spring-web-4.2.8.RELEASE.jar:4.2.8.RELEASE]
    ... 46 common frames omitted
Caused by: com.xxxxxxx.BadRequestException: boolean field should be either true|false
    at com.xxxxxxxx.Control.setIsControlEnabled(Control.java:141) ~[xxxxxxxx]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_101]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_101]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_101]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:97) ~[jackson-databind-2.6.3.jar:2.6.3]
    ... 55 common frames omitted

person Prasanna    schedule 04.11.2016    source источник
comment
Кто-нибудь знает, как передать пользовательское сообщение через десериализатор Джексона?   -  person Prasanna    schedule 07.11.2016
comment
если управление поступает в ваш метод установки, вы можете выполнять нулевые проверки для логического поля и выдавать исключение на основе этого.   -  person Derick Daniel    schedule 09.11.2016