首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在javax.json.bind.JsonbException (Helidon )上返回自定义响应

如何在javax.json.bind.JsonbException (Helidon )上返回自定义响应
EN

Stack Overflow用户
提问于 2022-04-01 11:11:57
回答 1查看 268关注 0票数 1

当json有效负载无效时,我试图返回一个自定义http响应(400个错误请求),而不是http 500服务器错误。

问题是,当我在javax.json.bind.JsonbException中使用ExceptionMapper<T>作为异常类型时,它无法捕获它,但我可以捕获更通用的javax.ws.rs.ProcessingException

很明显,javax.ws.rs.ProcessingException是由javax.json.bind.JsonbException引起的,因为堆栈跟踪显示:

代码语言:javascript
复制
javax.ws.rs.ProcessingException: Error deserializing object from entity stream.
    at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:86)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:233)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:212)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:49)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1072)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:885)
    at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:290)
    at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:73)
    at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:56)
    at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:50)
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:68)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:109)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:159)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
    at io.helidon.webserver.jersey.JerseySupport$JerseyHandler.lambda$doAccept$4(JerseySupport.java:326)
    at io.helidon.common.context.Contexts.runInContext(Contexts.java:117)
    at io.helidon.common.context.ContextAwareExecutorImpl.lambda$wrap$7(ContextAwareExecutorImpl.java:154)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.json.bind.JsonbException: Unable to deserialize property 'date' because of: Error parsing class java.util.Date from value: 2022-03-31T10:37:23.005Z[UTC]x. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.
    at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserializeInternal(AbstractContainerDeserializer.java:100)
    at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserialize(AbstractContainerDeserializer.java:64)
    at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:62)
    at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:51)
    at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:59)
    at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:99)
    at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:84)
    ... 33 more
Caused by: javax.json.bind.JsonbException: Error parsing class java.util.Date from value: 2022-03-31T10:37:23.005Z[UTC]x. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.
    at org.eclipse.yasson.internal.serializer.AbstractDateTimeDeserializer.deserialize(AbstractDateTimeDeserializer.java:74)
    at org.eclipse.yasson.internal.serializer.AbstractValueTypeDeserializer.deserialize(AbstractValueTypeDeserializer.java:64)
    at org.eclipse.yasson.internal.serializer.ObjectDeserializer.deserializeNext(ObjectDeserializer.java:180)
    at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserializeInternal(AbstractContainerDeserializer.java:94)
    ... 39 more
Caused by: java.time.format.DateTimeParseException: Text '2022-03-31T10:37:23.005Z[UTC]x' could not be parsed, unparsed text found at index 29
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2055)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954)
    at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:600)
    at org.eclipse.yasson.internal.serializer.DateTypeDeserializer.parseWithOrWithoutZone(DateTypeDeserializer.java:79)
    at org.eclipse.yasson.internal.serializer.DateTypeDeserializer.parseDefault(DateTypeDeserializer.java:49)
    at org.eclipse.yasson.internal.serializer.DateTypeDeserializer.parseDefault(DateTypeDeserializer.java:29)
    at org.eclipse.yasson.internal.serializer.AbstractDateTimeDeserializer.deserialize(AbstractDateTimeDeserializer.java:72)
    ... 42 more

但我想知道有没有办法抓住javax.json.bind.JsonbException

我使用的是Helidon 2.4.2。

复制:

  1. 创建Helidon 链接的快速启动
  2. 在问候语资源上添加post方法
代码语言:javascript
复制
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void add(MyClass cal){
        System.out.println(cal.getDate());
    }
代码语言:javascript
复制
public class MyClass {
    private String name;
    private Date date;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public MyClass(String name, Date date) {
        this.name = name;
        this.date = date;
    }

    public MyClass() {
    }
    
}

3.发送带有无效json日期的post请求。有效工资:

代码语言:javascript
复制
{
    "name": "testg",
    "date": "2022-03-31T10:37:23.005Z[UTC]"
}

无效(日期)有效载荷:

代码语言:javascript
复制
{
    "name": "testg",
    "date": "2022-03-31T10:37:23.005Z[UTC]XXXXXXXX"
}
EN

回答 1

Stack Overflow用户

发布于 2022-04-29 15:48:39

我也遇到过类似的麻烦,而且这个解决方案是按照以前的解决方案(泽西:当给出无效的请求体时,返回400错误而不是500)来实现的。

代码语言:javascript
复制
import java.time.format.DateTimeParseException;
import javax.json.bind.JsonbException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.apache.johnzon.mapper.MapperException;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
@Provider
public class InvalidDataMapper implements ExceptionMapper<JsonbException>         {
@Override
public Response toResponse(JsonbException arg0) {
    if (arg0.getCause() instanceof MapperException) {
        MapperException exception = (MapperException) arg0.getCause();
        ErrorMessage errorMessage = null;
        if (exception.getCause() instanceof DateTimeParseException) {
            errorMessage = new ErrorMessage(CustomCodesAndMessages.CODE_ERROR_FORMAT_DATE, exception.getMessage());
        }
        if (exception.getCause() instanceof NumberFormatException) {
            errorMessage = new ErrorMessage(CustomCodesAndMessages.CODE_ERROR_FORMATO_NUMERIC, exception.getMessage());
        }
        return Response.status(Response.Status.BAD_REQUEST).type(APPLICATION_JSON_TYPE).entity(errorMessage).build();
    }
    return Response.status(Response.Status.BAD_REQUEST).build();
  }
}

而ErrorMessage是

代码语言:javascript
复制
package fif.tech.utiles;
import java.util.Objects;
import org.apache.cxf.jaxrs.ext.Nullable;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ErrorMessage {
private final int code;
private final String message;
private final String details;
public ErrorMessage(String message) {
    this(500, message);
}
public ErrorMessage(int code, String message) {
    this(code, message, null);
}
@JsonCreator
public ErrorMessage(@JsonProperty("code") int code,     @JsonProperty("message") String message,
                    @Nullable @JsonProperty("details") String details) {
    this.code = code;
    this.message = message;
    this.details = details;
}
@JsonProperty("code")
public Integer getCode() {
    return code;
}

@JsonProperty("message")
public String getMessage() {
    return message;
}

@JsonProperty("details")
@Nullable
public String getDetails() {
    return details;
}

@Override
public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if ((obj == null) || (getClass() != obj.getClass())) {
        return false;
    }

    final ErrorMessage other = (ErrorMessage) obj;
    return Objects.equals(code, other.code)
            && Objects.equals(message, other.message)
            && Objects.equals(details, other.details);
}

@Override
public int hashCode() {
    return Objects.hash(code, message, details);
}

@Override
public String toString() {
    return "ErrorMessage{code=" + code + ", message='" + message + "', details='" + details + "'}";
 }
}

现在我试图捕捉产生异常的详细字段,但我认为这是一个足够的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71706004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档