我有一个pojo类,其中一个标志是isControl,其类型为Boolean。
当此属性获取非布尔值而非true或false时,fastxml jackson会自动将输入值转换为true。所以我按照Jackson Deserialize custom boolean json property
编写了Custom Deserializer类为了向调用者显示自定义错误消息,我编写了自己的错误消息类,其中显示了自定义消息(注意:我无法通过Jackson反序列化程序显示自定义错误消息,&& #39;为什么我编写自己的Exception类来显示自定义消息)。
但我现在的问题是当控件返回到setter方法时它包含null
值,如果输入错误,Jackson会在我的控制台日志中抛出异常。我想在日志中抑制这个异常,但是如果我保留一个catch块,那么实际的事务就会被传递。
绝对应该有更好的方法来显示自定义错误消息,以防错误输入boolen字段。我不想将我的布尔字段数据类型更改为Object因为我需要在很多地方改变代码。 请建议。
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