json解析日期

tcbh2hod  于 2024-01-07  发布在  Java
关注(0)|答案(1)|浏览(459)

我在解析你的约会时遇到了问题 JSON ,当我的程序消耗 POST 包含 Body ,而不是 REST 客户端程序 Postman 效果很好。
使用带有url的 Postman http://localhost:8080/api/v1/customers/createpurchaser

带收割台

我的程序客户端控制台的输出是:
java.time.format.datetimeparseexception:无法在索引0处分析文本“653038060000”
我的程序客户端的代码( ConsumingServices 类)是:

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

public class ConsumingServices {

    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.setFirstName("John");
        customer.setLastName("Mason");
        customer.setEmail("john.mason@mail.com");
        customer.setDateOfBirth(new Date());
        customer.setStatus(CustomerStatus.ACTIVE);

        ClientBuilder clientBuilder = ClientBuilder.newBuilder();
        clientBuilder.connectTimeout(1000, TimeUnit.SECONDS);
        clientBuilder.readTimeout(1000, TimeUnit.SECONDS);
        Client client = clientBuilder.build();

        WebTarget target = client.target("http://localhost:8080/api/v1/customers");

        Invocation.Builder invocationBuilder = target.path("createPurchaser")
                .request(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                ;

        Response response = invocationBuilder
                .header("Authorization", "1234")
                .post(Entity.entity(customer, MediaType.APPLICATION_JSON));

        System.out.println("response.getStatus():" + response.getStatus());
        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            Purchaser purchaser = response.readEntity(Purchaser.class);
            System.out.println("purchaser:".concat(purchaser.toString()));
        } else {
            if (MediaType.TEXT_PLAIN_TYPE.equals(response.getMediaType())) {
                String message = response.readEntity(String.class);
                System.out.println("message:" + message);
            } else if (MediaType.APPLICATION_JSON.equals(response.getMediaType())) {
                ApiError apiError = response.readEntity(ApiError.class);
                System.out.println("apiError:".concat(apiError.toString()));
            } else {
                System.out.println("response.getMediaType():" + response.getMediaType());
                String content = response.readEntity(String.class);
                System.out.println("message:" + content);
            }
        }
    }
}

输出:

--- exec-maven-plugin:1.5.0:exec (default-cli) @ acme-customers-client ---
response.getStatus():500

response.getMediaType():text/html
message:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Payara Server  5.2020.3 #badassfish - Error report</title><style type="text/css"><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - Internal Server Error</h1><hr/><p><b>type</b> Exception report</p><p><b>message</b>Internal Server Error</p><p><b>description</b>The server encountered an internal error that prevented it from fulfilling this request.</p><p><b>exception</b> <pre>javax.servlet.ServletException: javax.ws.rs.ProcessingException: Error deserializing object from entity stream.</pre></p><p><b>root cause</b> <pre>javax.ws.rs.ProcessingException: Error deserializing object from entity stream.</pre></p><p><b>root cause</b> <pre>javax.json.bind.JsonbException: Unable to deserialize property &#39;dateOfBirth&#39; because of: Error parsing class java.util.Date from value: 1599180453470. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.</pre></p><p><b>root cause</b> <pre>javax.json.bind.JsonbException: Error parsing class java.util.Date from value: 1599180453470. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.</pre></p><p><b>root cause</b> <pre>java.time.format.DateTimeParseException: Text &#39;1599180453470&#39; could not be parsed at index 0</pre></p><p><b>note</b> <u>The full stack traces of the exception and its root causes are available in the Payara Server  5.2020.3 #badassfish logs.</u></p><hr/><h3>Payara Server  5.2020.3 #badassfish</h3></body></html>
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time:  5.574 s
Finished at: 2020-09-03T19:47:36-05:00
------------------------------------------------------------------------

样式化输出。

type Exception report

messageInternal Server Error

descriptionThe server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: javax.ws.rs.ProcessingException: Error deserializing object from entity stream.
root cause

javax.ws.rs.ProcessingException: Error deserializing object from entity stream.
root cause

javax.json.bind.JsonbException: Unable to deserialize property 'dateOfBirth' because of: Error parsing class java.util.Date from value: 653038060000. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.
root cause

javax.json.bind.JsonbException: Error parsing class java.util.Date from value: 653038060000. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.
root cause

java.time.format.DateTimeParseException: Text '653038060000' could not be parsed at index 0

这个 Customer 类(问题中的所有代码是javax.ws.rs.processingexception,在payara server 5中找不到内容类型application/json类型的writer)

import java.io.Serializable;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer extends BaseType implements Serializable {

    private String firstName;
    private String lastName;
    private CustomerStatus status;
    private String email;
    private Date dateOfBirth;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public CustomerStatus getStatus() {
        return status;
    }

    public void setStatus(CustomerStatus status) {
        this.status = status;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
}

这个 pom.xml 我的程序客户端的依赖项是:

<dependencies>
    <dependency>
        <groupId>com.acme</groupId>
        <artifactId>acme-customers-lib</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.31</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.inject/jersey-hk2 -->
    <dependency>
        <groupId>org.glassfish.jersey.inject</groupId>
        <artifactId>jersey-hk2</artifactId>
        <version>2.31</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.31</version>
    </dependency>
</dependencies>

如何在我的客户机中解决这个问题(使用 ClientBuilder/WebTarget) 程序,如果使用rest客户端程序工作正常??

zbwhf8kr

zbwhf8kr1#

你的问题很可能是在解析你的 Customer 在客户机程序中将示例类化为json。请注意,在postman中,您已经提供了正确的json(您希望 Customer 类示例将被解析为),但在客户端程序中,您希望您的http客户端代码解析 Customer 在这段代码中将示例类化为json:

Response response = invocationBuilder
            .header("Authorization", "1234")
            .post(Entity.entity(customer, MediaType.APPLICATION_JSON));

但是,日期被解析为“653038060000”,正如错误消息告诉您的那样。因此,我建议首先测试我的假设是否正确,尝试发送json文本而不是 Customer 类示例。如果我的假设是正确的,这就行了。如果是这样的话,那么您需要确保无论以何种方式解析 Customer json的类示例是正确的。或者自己使用一些json库(我建议jacksonjson,githubjacksonhome)。以下是maven工件:

<groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>

)或者获取您的http客户端 Invocation.Builder 正确解析。为此,您可能需要在customer类中添加以下注解:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
   private Date dateOfBirth;

您可能需要向代码中添加相同的jacksonmaven工件。关于详细的答案,请参阅这个问题:SpringDataJPA-ZoneDateTime格式用于json序列化,如果您使用的是Java8或更高版本,我强烈建议不要使用过时的 Date 类(没有双关语),但切换到 java.time 打包并使用localdate类或其他可用类,如 LocalDateTime 或者 ZonedDateTime 或者其他人。最后,如果您愿意,您可以尝试另一个来自mgntutils库的3d方http客户端。下面是它的javadoc:httpclient。这个库本身可以在这里作为maven工件和github上找到(包括源代码和javadoc)。这个库不将类解析为json,但是可以将文本作为请求体发送(免责声明:这个库是我写的)。

相关问题