【问题标题】:How to handle error of wrong JSON data in Java Rest Web Service: Jackson JSON Parser Unrecognized token如何处理 Java Rest Web Service 中错误 JSON 数据的错误:Jackson JSON Parser Unrecognized token
【发布时间】:2017-06-05 09:25:40
【问题描述】:

这是我的网络服务,我在其中接收学生对象中的 JSON。

 @PUT
    @Path("/{stuId}")
    @Consumes({MediaType.APPLICATION_JSON})
    public Response update( @PathParam("stuId") UUID stuUUID , Student updatedStudentInfo) {
            return updateService.update(stuUUID, updatedStudentInfo);
        }

这是学生班:

    public class Student{

      private int id;
      private String studentName;
      private String Address;

    @JsonProperty
     public int getId() {
        return id;
    }
    @JsonProperty
    public void setId(int id) {
        this.id = id;
    }
    @JsonProperty
    public String getStudentName() {
        return studentName;
    }

       .
       .
       .
       .
  }

它工作正常,但是当我通过发送错误的 JSON 数据对其进行测试时,我无法处理这种情况。例如,如果我这样做

curl -v 'https://localhost:9803/school/student/29374-345tr-44' -X PUT -H 'Accept: application/json, text/plain, /' -H 'My-API-版本:1' -H '授权:基本' -H '内容类型:application/json;charset=utf-8' --data '{"studentName":"rock","Address":723868764}'强>

它会产生错误:

Unrecognized token '723868764': was expecting ('true', 'false' or 'null')

现在我该如何处理这种情况,如果出现一些错误数据,那么除了我要发送的错误或异常之外,它不应该发回任何错误或异常。

编辑 1:

下面我们还可以看到Java代码正在生成的异常

 Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'sdfsdfdsfdsf': was expecting ('true', 'false' or 'null') at 
[Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@5c6d324d; line: 1, column: 59]

【问题讨论】:

  • 为什么你得到true, false 或 null ,它不是布尔对象
  • 您可以尝试捕获该异常并在其中定义您自己的自定义消息:catch (JSONException e) { //add custome ex message here e.getMessage() } 此外,由于您已将 Address 声明为 String 并可能尝试将其设置为数字,因此会抛出无法识别的令牌而不是字符串,将其括在双引号中,这可能会使错误消失!
  • @coolgirl 是的,我是故意传递数字而不是字符串,这是我的问题,如果我发送了一些错误的 JSON 数据,那么我该如何解决?其次,我可以在这段代码中的哪里使用这个 TRY CATCH,因为这个异常是在方法的签名级别生成的,所以编译器甚至不会进入方法内部。
  • 我想try catch 处理应该在你的服务类中完成。
  • @CarlosLaspina - 与coolgirl 的解释相同,问题的目的是修复错误处理。 OP很清楚数据是无效的。

标签: java json rest jakarta-ee jackson


【解决方案1】:

我找到了两种可用的解决方案:
解决方案 1: ExceptionMapper (jersey)

@Provider
public class ClientExceptionMapper implements ExceptionMapper<Throwable>
{
    @Override
    public Response toResponse(Throwable ex) 
    {

        return Response
                .status(Response.Status.BAD_REQUEST)
                .build();
    }
}

这里重要的是注解

@provider

我不确定在使用注释将扫描配置放入 web.xml 后是否有必要,但为了安全起见,让我们这样做

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>
        org.glassfish.jersey.servlet.ServletContainer
    </servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>
         com.myrootpackgae.ws;com.anotherPackage.errorHandling;
        </param-value>
    </init-param>
    <init-param>
        <param-name>jersey.config.server.provider.scanning.recursive</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

您的 ExceptionMapper 类应该在您的 Rest Service 的同一包中或在包层次结构下。
最后但并非最不重要的一点是,我在示例中使用了 Throwable,但您可以针对任何异常,例如

JsonParseException
JsonMappingException
UnrecognizedPropertyException 等...



解决方案 2: javax.ws.rs.container.ContainerResponseFilter

 public class MyRestAppResponseFilter implements ContainerResponseFilter {

        @Override
        public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
                throws IOException {

            // Remove StackTrace from all exceptions
            Object entity = responseContext.getEntity();
    if (entity instanceof Throwable) {
                responseContext.setEntity(null);
                responseContext.setStatus(Response.Status.BAD_REQUEST.getStatusCode());
 }           
            // TF-246 Prevent caching for privacy reasons
            responseContext.getHeaders().add("Cache-Control", "no-cache, no-store, must-revalidate");
            responseContext.getHeaders().add("Pragma", "no-cache");
            responseContext.getHeaders().add("Expires", "Thu, 01 Jan 1970 01:00:00 CET");

            // TF-752 Enable CORS for WkWebView
            responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        }
    }


还可以使用RequestEventListener 的请求事件监听器,它提供onEvent(RequestEvent) 方法。
我更喜欢使用解决方案 #2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2018-08-19
    • 2015-12-24
    • 1970-01-01
    相关资源
    最近更新 更多