java - jackson 加工杂志

标签 java rest jackson jersey-client

几天来,我一直在拔头发。我不知道发生了什么事。我正在使用GWT开发WebApp,该WebApp使用RestAPI与其他服务器通信。我使用Jersey客户端与GWT项目的“服务器”部分通信到其他服务器。

本质上,Jackson解析从RestAPI服务器返回的JSON时遇到问题。它解析的JSON对象已在Android应用程序和IOS应用程序中成功使用,而RestAPI服务器没有问题。

本质上,为了调试该问题,我取出了Jersey媒体插件,让jersey只返回对象的字符串,然后将该字符串传递给ObjectMapper。我正在使用最新的Jackson版本2.4.4。

我有一个自定义的反序列化器,该序列化器可用于日期格式,并且我收到的错误始终与该日期有关。原始JSON看起来不错,但Jackson对象映射器抛出错误。错误并不总是在相同的位置,而是总是与lastInspectionDate一起出现。该错误有时是表示要解析的字符串为空,或者该字符串是一些奇怪的值。

这是一些希望澄清的代码:

它在解析时遇到麻烦的EstablishmentEntity类:

@JsonIgnoreProperties(ignoreUnknown = true)
public class EstablishmentEntity {
    private long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    private String establishmentName;

    public String getEstablishmentName() {
        return establishmentName;
    }

    public void setEstablishmentName(String establishmentName) {
        this.establishmentName = establishmentName;
    }

    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    private String city;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    private String county;

    public String getCounty() {
        return county;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    private String stateOrProvince;

    public String getStateOrProvince() {
        return stateOrProvince;
    }

    public void setStateOrProvince(String stateOrProvince) {
        this.stateOrProvince = stateOrProvince;
    }


    private String postalCode;

    public String getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    private String telephone;

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    private String establishmentType;

    public String getEstablishmentType() {
        return establishmentType;
    }

    public void setEstablishmentType(String establishmentType) {
        this.establishmentType = establishmentType;
    }

    @JsonSerialize(using = JsonDateOnlySerializer.class)
    @JsonDeserialize(using = JsonDateOnlyDeserializer.class)
    private Date lastInspectionDate;

    public Date getLastInspectionDate() {
        return lastInspectionDate;
    }

    public void setLastInspectionDate(Date lastInspectionDate) {
        this.lastInspectionDate = lastInspectionDate;
    }

    private String lastInspectionScore;

    public String getLastInspectionScore() {
        return lastInspectionScore;
    }

    public void setLastInspectionScore(String lastInspectionScore) {
        this.lastInspectionScore = lastInspectionScore;
    }

    @JsonSerialize(using = JsonDateOnlySerializer.class)
    @JsonDeserialize(using = JsonDateOnlyDeserializer.class)
    private Date lastInspectionScoreDate;

    public Date getLastInspectionScoreDate() {
        return lastInspectionScoreDate;
    }

    public void setLastInspectionScoreDate(Date lastInspectionScoreDate) {
        this.lastInspectionScoreDate = lastInspectionScoreDate;
    }

    private String lastInspectionGrade;

    public String getLastInspectionGrade() {
        return lastInspectionGrade;
    }

    public void setLastInspectionGrade(String lastInspectionGrade) {
        this.lastInspectionGrade = lastInspectionGrade;
    }

    @JsonSerialize(using = JsonDateOnlySerializer.class)
    @JsonDeserialize(using = JsonDateOnlyDeserializer.class)
    private Date lastInspectionGradeDate;

    public Date getLastInspectionGradeDate() {
        return lastInspectionGradeDate;
    }

    public void setLastInspectionGradeDate(Date lastInspectionGradeDate) {
        this.lastInspectionGradeDate = lastInspectionGradeDate;
    }

    private String healthDepartment;

    public String getHealthDepartment() {
        return healthDepartment;
    }

    public void setHealthDepartment(String healthDepartment) {
        this.healthDepartment = healthDepartment;
    }

    private boolean lastInspectionCritical;

    public boolean isLastInspectionCritical() {
        return lastInspectionCritical;
    }

    public void setLastInspectionCritical(boolean lastInspectionCritical) {
        this.lastInspectionCritical = lastInspectionCritical;
    }

    private boolean lastInspectionPriority;

    public boolean isLastInspectionPriority() {
        return lastInspectionPriority;
    }

    public void setLastInspectionPriority(boolean lastInspectionPriority) {
        this.lastInspectionPriority = lastInspectionPriority;
    }

    private boolean lastInspectionPriorityFoundation;

    public boolean isLastInspectionPriorityFoundation() {
        return lastInspectionPriorityFoundation;
    }

    public void setLastInspectionPriorityFoundation(boolean lastInspectionPriorityFoundation) {
        this.lastInspectionPriorityFoundation = lastInspectionPriorityFoundation;
    }

    private double latitude;

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    private double longitude;

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    private Timestamp added;

    public Timestamp getAdded() {
        return added;
    }

    public void setAdded(Timestamp added) {
        this.added = added;
    }

    private String geocoder;

    public String getGeocoder() {
        return geocoder;
    }

    public void setGeocoder(String geocoder) {
        this.geocoder = geocoder;
    }

    private String geocoderVersion;

    public String getGeocoderVersion() {
        return geocoderVersion;
    }

    public void setGeocoderVersion(String geocoderVersion) {
        this.geocoderVersion = geocoderVersion;
    }


    private Double hdscoreRankingPercent;

    public Double getHdscoreRankingPercent() {
        return hdscoreRankingPercent;
    }

    public void setHdscoreRankingPercent(Double hdscoreRankingPercent) {
        this.hdscoreRankingPercent = hdscoreRankingPercent;
    }


    private String hdscoreProvider;

    public String getHdscoreProvider() {
        return hdscoreProvider;
    }

    public void setHdscoreProvider(String hdscoreProvider) {
        this.hdscoreProvider = hdscoreProvider;
    }


    private Double hdscore;

    public Double getHdscore() {
        return hdscore;
    }

    public void setHdscore(Double hdscore) {
        this.hdscore = hdscore;
    }

    private String hdscoreVersion;

    public String getHdscoreVersion() {
        return hdscoreVersion;
    }

    public void setHdscoreVersion(String hdscoreVersion) {
        this.hdscoreVersion = hdscoreVersion;
    }



}


JSON反序列化器:

public class JsonDateOnlyDeserializer extends JsonDeserializer<Date> {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String dateString = jp.getText();
        try {
            return dateFormat.parse(dateString);
        }
        catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }
}


原始JSON示例(由于篇幅而删节):

{ 
   "responseId":1,
   "resultsLimited":true,
   "totalResults":485651,
   "geoHashLevel":2,
   "items":[ 
      { 
         "establishmentEntity":{ 
            "id":469715,
            "establishmentName":"PENNY'S KITCHEN",
            "address":"822 W 14th St",
            "city":"Coffeyville",
            "county":"Montgomery",
            "stateOrProvince":"KS",
            "postalCode":"67337-4402",
            "telephone":"9183317321",
            "establishmentType":null,
            "lastInspectionScore":null,
            "lastInspectionGrade":null,
            "healthDepartment":"State of Kansas",
            "lastInspectionCritical":false,
            "lastInspectionPriority":false,
            "lastInspectionPriorityFoundation":false,
            "latitude":37.02878,
            "longitude":-95.625374,
            "added":1409016435000,
            "geocoder":"com.hdscores.inspection.source.geocoding.MapQuestLicensedGeocoder",
            "geocoderVersion":"1.12",
            "hdscoreRankingPercent":0.301823675,
            "hdscoreProvider":"com.hdscores.inspection.hdscore.ViolationsHDScoreProvider",
            "hdscore":4.373924497631436,
            "hdscoreVersion":"1.04",
            "lastInspectionDate":"2013-10-17",
            "lastInspectionScoreDate":null,
            "lastInspectionGradeDate":null
         },
         "preferredLevel":0,
         "logoUrl":null,
         "resultsTop":false,
         "resultsBottom":false,
         "featured":false,
         "reportsViolations":true,
         "displayName":"PENNY'S KITCHEN"
      },
      { 
         "establishmentEntity":{ 
            "id":281253,
            "establishmentName":"COFFEYVILLE LIVESTOCK MARKET",
            "address":"822 W 14th St",
            "city":"Coffeyville",
            "county":"Montgomery",
            "stateOrProvince":"KS",
            "postalCode":"67337-4402",
            "telephone":"6202515460",
            "establishmentType":null,
            "lastInspectionScore":null,
            "lastInspectionGrade":null,
            "healthDepartment":"State of Kansas",
            "lastInspectionCritical":true,
            "lastInspectionPriority":false,
            "lastInspectionPriorityFoundation":false,
            "latitude":37.02878,
            "longitude":-95.625374,
            "added":1405623496000,
            "geocoder":"com.hdscores.inspection.source.geocoding.MapQuestLicensedGeocoder",
            "geocoderVersion":"1.12",
            "hdscoreRankingPercent":0.133052767,
            "hdscoreProvider":"com.hdscores.inspection.hdscore.ViolationsHDScoreProvider",
            "hdscore":6.5,
            "hdscoreVersion":"1.04",
            "lastInspectionDate":"2011-06-23",
            "lastInspectionScoreDate":null,
            "lastInspectionGradeDate":null
         },
         "preferredLevel":0,
         "logoUrl":null,
         "resultsTop":false,
         "resultsBottom":false,
         "featured":false,
         "reportsViolations":true,
         "displayName":"COFFEYVILLE LIVESTOCK MARKET"
      },
      { 
         "establishmentEntity":{ 
            "id":368166,
            "establishmentName":"TROPICAL SNO",
            "address":"823 E 11th St",
            "city":"Coffeyville",
            "county":"Montgomery",
            "stateOrProvince":"KS",
            "postalCode":"67337-6603",
            "telephone":"6203303296",
            "establishmentType":null,
            "lastInspectionScore":null,
            "lastInspectionGrade":null,
            "healthDepartment":"State of Kansas",
            "lastInspectionCritical":false,
            "lastInspectionPriority":false,
            "lastInspectionPriorityFoundation":false,
            "latitude":37.032937,
            "longitude":-95.602057,
            "added":1406367309000,
            "geocoder":"com.hdscores.inspection.source.geocoding.MapQuestLicensedGeocoder",
            "geocoderVersion":"1.12",
            "hdscoreRankingPercent":0.449228445,
            "hdscoreProvider":"com.hdscores.inspection.hdscore.ViolationsHDScoreProvider",
            "hdscore":3.3172017928863275,
            "hdscoreVersion":"1.04",
            "lastInspectionDate":"2013-04-04",
            "lastInspectionScoreDate":null,
            "lastInspectionGradeDate":null
         },
         "preferredLevel":1,
         "logoUrl":null,
         "resultsTop":false,
         "resultsBottom":false,
         "featured":false,
         "reportsViolations":true,
         "displayName":"TROPICAL SNO"
      },
      { 
         "establishmentEntity":{ 
            "id":494794,
            "establishmentName":"SIR VON II",
            "address":"806 E 11th St",
            "city":"Coffeyville",
            "county":"Montgomery",
            "stateOrProvince":"KS",
            "postalCode":"67337-6604",
            "telephone":"6206886321",
            "establishmentType":null,
            "lastInspectionScore":null,
            "lastInspectionGrade":null,
            "healthDepartment":"State of Kansas",
            "lastInspectionCritical":true,
            "lastInspectionPriority":false,
            "lastInspectionPriorityFoundation":false,
            "latitude":37.032902,
            "longitude":-95.604437,
            "added":1410044780000,
            "geocoder":"com.hdscores.inspection.source.geocoding.MapQuestLicensedGeocoder",
            "geocoderVersion":"1.12",
            "hdscoreRankingPercent":0.195856264,
            "hdscoreProvider":"com.hdscores.inspection.hdscore.ViolationsHDScoreProvider",
            "hdscore":5.5,
            "hdscoreVersion":"1.04",
            "lastInspectionDate":"2012-07-30",
            "lastInspectionScoreDate":null,
            "lastInspectionGradeDate":null
         },
         "preferredLevel":0,
         "logoUrl":null,
         "resultsTop":false,
         "resultsBottom":false,
         "featured":false,
         "reportsViolations":true,
         "displayName":"SIR VON II"
      },
      { 
         "establishmentEntity":{ 
            "id":377960,
            "establishmentName":"DAYS INN",
            "address":"820 E 11th St",
            "city":"Coffeyville",
            "county":"Montgomery",
            "stateOrProvince":"KS",
            "postalCode":"67337-6604",
            "telephone":"6202510002",
            "establishmentType":null,
            "lastInspectionScore":null,
            "lastInspectionGrade":null,
            "healthDepartment":"State of Kansas",
            "lastInspectionCritical":false,
            "lastInspectionPriority":false,
            "lastInspectionPriorityFoundation":false,
            "latitude":37.0329,
            "longitude":-95.60475,
            "added":1406692555000,
            "geocoder":"com.hdscores.inspection.source.geocoding.MapQuestLicensedGeocoder",
            "geocoderVersion":"1.12",
            "hdscoreRankingPercent":0.6747599,
            "hdscoreProvider":"com.hdscores.inspection.hdscore.ViolationsHDScoreProvider",
            "hdscore":2.0,
            "hdscoreVersion":"1.04",
            "lastInspectionDate":"2013-12-24",
            "lastInspectionScoreDate":null,
            "lastInspectionGradeDate":null
         },
         "preferredLevel":1,
         "logoUrl":null,
         "resultsTop":false,
         "resultsBottom":false,
         "featured":false,
         "reportsViolations":true,
         "displayName":"DAYS INN"
      },
      { 
         "establishmentEntity":{ 
            "id":119641,
            "establishmentName":"SIRLOIN STOCKADE",
            "address":"104 W 11th St",
            "city":"Coffeyville",
            "county":"Montgomery",
            "stateOrProvince":"KS",
            "postalCode":"67337-5902",
            "telephone":"6202518156",
            "establishmentType":null,
            "lastInspectionScore":null,
            "lastInspectionGrade":null,
            "healthDepartment":"State of Kansas",
            "lastInspectionCritical":false,
            "lastInspectionPriority":false,
            "lastInspectionPriorityFoundation":false,
            "latitude":37.03298,
            "longitude":-95.615787,
            "added":1400599518000,
            "geocoder":"com.hdscores.inspection.source.geocoding.MapQuestGeocoder",
            "geocoderVersion":"1.00",
            "hdscoreRankingPercent":0.147512679,
            "hdscoreProvider":"com.hdscores.inspection.hdscore.ViolationsHDScoreProvider",
            "hdscore":6.209693418399466,
            "hdscoreVersion":"1.04",
            "lastInspectionDate":"2014-03-07",
            "lastInspectionScoreDate":null,
            "lastInspectionGradeDate":null
         },
         "preferredLevel":0,
         "logoUrl":null,
         "resultsTop":false,
         "resultsBottom":false,
         "featured":false,
         "reportsViolations":true,
         "displayName":"SIRLOIN STOCKADE"
      },


这是我多次重新运行同一代码的一些错误:

   java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: multiple points (through reference chain: com.hdscores.consumer.service.client.SearchResponse["items"]->java.util.ArrayList[0]->com.hdscores.consumer.service.client.Establishment["establishmentEntity"]->com.hdscores.consumer.service.client.EstablishmentEntity["lastInspectionDate"])

(Removed intermediate errors)

Caused by: java.lang.NumberFormatException: multiple points
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1101)
    at java.lang.Double.parseDouble(Double.java:540)
    at java.text.DigitList.getDouble(DigitList.java:168)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1321)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2088)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
    at java.text.DateFormat.parse(DateFormat.java:355)
    at com.hdscores.consumer.service.client.JsonDateOnlyDeserializer.deserialize(JsonDateOnlyDeserializer.java:23)
    at com.hdscores.consumer.service.client.JsonDateOnlyDeserializer.deserialize(JsonDateOnlyDeserializer.java:16)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:538)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:238)
    ... 51 more


有时这是错误...

Caused by: java.lang.NumberFormatException: For input string: "5E51"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Long.parseLong(Long.java:441)
    at java.lang.Long.parseLong(Long.java:483)
    at java.text.DigitList.getLong(DigitList.java:194)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1316)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1793)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
    at java.text.DateFormat.parse(DateFormat.java:355)
    at com.hdscores.consumer.service.client.JsonDateOnlyDeserializer.deserialize(JsonDateOnlyDeserializer.java:23)
    at com.hdscores.consumer.service.client.JsonDateOnlyDeserializer.deserialize(JsonDateOnlyDeserializer.java:16)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:538)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:238)


它疯狂,有时它没有错误,有时却没有...。

任何帮助,将不胜感激....

最佳答案

我想到了!我发现SimpleDateFormat不是线程安全的,因此我为每个线程创建了一个新实例并更新了JSON反序列化器:

public class JsonDateOnlyDeserializer extends JsonDeserializer<Date> {
    //private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = jp.getText();
        try {
            return dateFormat.parse(dateString);
        }
        catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }
}

关于java - jackson 加工杂志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27529616/

相关文章:

java - 如何从来自 api 响应的 json 字符串构造对象列表?

java设计模式消除代码重复

java - 如何在 Azure Monitor 中监视 Java 堆使用情况

c# - 如何使用 REST API 为 Bucket 和 BigQuery 启用 "Export Billing"信息谷歌云

java - 如何在 REST Assured 中访问底层的 Jackson ObjectMapper?

java - 如何在 Jackson 中反序列化多个嵌套元素?

java - Docker 容器中 FTP 上传文件失败

java - 安装4j 7.0.6 : Cancel installation from "Replacement script for language code"

java - 不存在的可选字段与在休息请求正文中存在空值的字段之间的区别

rest - 如何在 Play Framework 2.3 中向 FakeRequest 添加查询字符串参数?