【问题标题】:no String-argument constructor/factory method to deserialize from String value没有从字符串值反序列化的字符串参数构造函数/工厂方法
【发布时间】:2017-03-03 03:43:04
【问题描述】:

我正在尝试使用外部 NYtimes API。这是一个示例数据输出:

{
    "status": "OK",
    "copyright": "Copyright (c) 2016 The New York Times Company. All Rights Reserved.",
    "section": "home",
    "last_updated": "2016-10-20T19:57:45-04:00",
    "num_results": 30,
    "results": [{
            "section": "Briefing",
            "subsection": "",
            "title": "Election, Dodgers, Duterte: Your Thursday Evening Briefing",
            "abstract": "Here’s what you need to know at the end of the day.",
            "url": "abc.co",
            "byline": "By KAREN ZRAICK and MERRILL D. OLIVER",
            "item_type": "Article",
            "updated_date": "2016-10-20T18:32:41-04:00",
            "created_date": "2016-10-20T17:58:30-04:00",
            "published_date": "2016-10-20T17:58:30-04:00",
            "material_type_facet": "",
            "kicker": "",
            "des_facet": [],
            "org_facet": [],
            "per_facet": [],
            "geo_facet": [],
            "multimedia": [{
                "url": "abc.co",
                "format": "Standard Thumbnail",
                "height": 75,
                "width": 75,
                "type": "image",
                "subtype": "photo",
                "caption": "",
                "copyright": "Damon Winter/The New York Times"
            }, {
                "url": "abc.co",
                "format": "thumbLarge",
                "height": 150,
                "width": 150,
                "type": "image",
                "subtype": "photo",
                "caption": "",
                "copyright": "Damon Winter/The New York Times"
            }, {
                "url": "abc.co",
                "format": "Normal",
                "height": 127,
                "width": 190,
                "type": "image",
                "subtype": "photo",
                "caption": "",
                "copyright": "Damon Winter/The New York Times"
            }, {
                "url": "abc.co",
                "format": "mediumThreeByTwo210",
                "height": 140,
                "width": 210,
                "type": "image",
                "subtype": "photo",
                "caption": "",
                "copyright": "Damon Winter/The New York Times"
            }, {
                "url": "abc.co",
                "format": "superJumbo",
                "height": 1365,
                "width": 2048,
                "type": "image",
                "subtype": "photo",
                "caption": "",
                "copyright": "Damon Winter/The New York Times"
            }],
            "short_url": "http://abc.co"
        }

    ]
}

这是 bean 的定义

//Headline.class
public class Headline {

@JsonProperty("status")
String status;
@JsonProperty("copyright")
String copyright;
@JsonProperty("section")
String section;
@JsonProperty("last_updated")
String last_updated;
@JsonProperty("num_results")
int num_results;
@JsonProperty("results")
List<Story> results;

`

//Story.class
    @JsonProperty("section")
        String section;
        @JsonProperty("subsection")
        String subsection;
        @JsonProperty("title")
        String title;
        @JsonProperty("abstract")
        String storyAbstract;
        @JsonProperty("url")
        String url;
        @JsonProperty("byline")
        String byline;
        @JsonProperty("item_type")
        String item_type;
        @JsonProperty("updated_date")
        String updated_date;
        @JsonProperty("created_date")
        String created_date;
        @JsonProperty("published_date")
        String published_date;
        @JsonProperty("material_type_facet")
        String material_type_facet;
        @JsonProperty("kicker")
        String kicker;
        /*@JsonProperty("des_facet")
        List des_facet;
        @JsonProperty("org_facet")
        List org_facet;
        @JsonProperty("per_facet")
        List per_facet;
        @JsonProperty("geo_facet")
        List geo_facet;*/
        @JsonProperty("multimedia")
        List<Media> multimedia;
        @JsonProperty("short_url")
        String short_url;

//Media.class
        @JsonProperty("url")
        String url;
        @JsonProperty("format")
        String format;
        @JsonProperty("height")
        int height;
        @JsonProperty("width")
        int width;
        @JsonProperty("type")
        String type;
        @JsonProperty("subtype")
        String subtype;
        @JsonProperty("caption")
        String caption;
        @JsonProperty("copyright")
        String copyright;

这是我的来电者:

RestTemplate restTemplate = new RestTemplate();
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        jsonConverter.setSupportedMediaTypes(Arrays.asList(new MediaType("text","json",MappingJackson2HttpMessageConverter.DEFAULT_CHARSET)));
        restTemplate.getMessageConverters().add(jsonConverter);
        Headline headline =  restTemplate.getForObject("http://abc/svc/topstories/v1/home.json?api-key=key",Headline.class);
        logger.info("Headline"+headline.toString());

现在我打电话时得到的例外是:

Exception in thread "main" org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not construct instance of java.util.ArrayList: no String-argument constructor/factory method to deserialize from String value ('')
 at [Source: java.io.PushbackInputStream@22d9d; line: 1, column: 1185] (through reference chain: NYTimes.Payload.Headline["results"]->java.util.ArrayList[0]->NYTimes.Story.Story["multimedia"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.ArrayList: no String-argument constructor/factory method to deserialize from String value ('')
 at [Source: java.io.PushbackInputStream@22d9d; line: 1, column: 1185] (through reference chain: NYTimes.Payload.Headline["results"]->java.util.ArrayList[0]->NYTimes.Story.Story["multimedia"])

我一直试图理解为什么它不反序列化。如果字符串值为空 - 那么它应该导致一个空列表?

【问题讨论】:

  • 你为什么不把它变成一个正确的 JSON?只需将其包裹在括号中,看看会发生什么。
  • 我现在用正确的 JSON 更新了它。
  • @HarryGohl 如果你用它运行你的代码有什么改变吗?
  • 不,json 总是正确的。我粘贴了一半作为示例。它仍然失败。
  • 您的代码和 json 似乎是正确的,我执行了,您确定每次获得相同的 json 数据吗?

标签: java spring jackson


【解决方案1】:

由于您收到的 json 响应而发生此异常 -

{
    "status": "OK",
    "copyright": "Copyright (c) 2016 The New York Times Company. All Rights Reserved.",
    "section": "home",
    "last_updated": "2016-10-20T19:57:45-04:00",
    "num_results": 30,
    "results": [{
            "section": "Briefing",
            "subsection": "",
            "title": "Election, Dodgers, Duterte: Your Thursday Evening Briefing",
            "abstract": "Here’s what you need to know at the end of the day.",
            "url": "abc.co",
            "byline": "By KAREN ZRAICK and MERRILL D. OLIVER",
            "item_type": "Article",
            "updated_date": "2016-10-20T18:32:41-04:00",
            "created_date": "2016-10-20T17:58:30-04:00",
            "published_date": "2016-10-20T17:58:30-04:00",
            "material_type_facet": "",
            "kicker": "",
            "des_facet": [],
            "org_facet": [],
            "per_facet": [],
            "geo_facet": [],
            "multimedia": "",
            "short_url": "http://abc.co"
        }

    ]
} 

“多媒体”字段为空字符串

因此您需要验证您的 json 并相应地映射您的 pojo。

【讨论】:

  • 感谢德里克。但问题是我不控制数据 - 我如何处理空字符串?
  • 为此,您必须编写自己的自定义反序列化器,这可能会有所帮助 - stackoverflow.com/questions/12933394/…
【解决方案2】:

此代码正在运行。

尝试使用这些对象调用您的 API。

我认为您在多媒体或类似方面存在命名问题。

class Multimedia{
    public String url;
    public String format;
    public int height;
    public int width;
    public String type;
    public String subtype;
    public String caption;
    public String copyright;

    @Override
    public String toString() {
        return String.format(
                "Multimedia (url=%s, format=%s, height=%s, width=%s, type=%s, subtype=%s, caption=%s, copyright=%s)", this.url, this.format, this.height, this.width, this.type, this.subtype, this.caption, this.copyright);
    }
}

class Result{
    public String section;
    public String subsection;
    public String title;
    @JsonProperty("abstract")
    public String abstract2;
    public String url;
    public String byline;
    public String item_type;
    public Date updated_date;
    public Date created_date;
    public Date published_date;
    public String material_type_facet;
    public String kicker;
    public List<Object> des_facet;
    public List<Object> org_facet;
    public List<Object> per_facet;
    public List<Object> geo_facet;
    public List<Multimedia> multimedia;
    public String short_url;

    @Override
    public String toString() {
        return String.format(
                "Result (section=%s, subsection=%s, title=%s, abstract2=%s, url=%s, byline=%s, item_type=%s, updated_date=%s, created_date=%s, published_date=%s, material_type_facet=%s, kicker=%s, des_facet=%s, org_facet=%s, per_facet=%s, geo_facet=%s, multimedia=%s, short_url=%s)", this.section, this.subsection, this.title, this.abstract2, this.url, this.byline, this.item_type, this.updated_date, this.created_date, this.published_date, this.material_type_facet, this.kicker, this.des_facet, this.org_facet, this.per_facet, this.geo_facet, this.multimedia, this.short_url);
    }
}

class Root{
    public String status;
    public String copyright;
    public String section;
    public Date last_updated;
    public int num_results;
    public List<Result> results;

    @Override
    public String toString() {
        return String.format(
                "Root (status=%s, copyright=%s, section=%s, last_updated=%s, num_results=%s, results=%s)", this.status, this.copyright, this.section, this.last_updated, this.num_results, this.results);
    }
}

public class IAE {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\n" +
                "    \"status\": \"OK\",\n" +
                "    \"copyright\": \"Copyright (c) 2016 The New York Times Company. All Rights Reserved.\",\n" +
                "    \"section\": \"home\",\n" +
                "    \"last_updated\": \"2016-10-20T19:57:45-04:00\",\n" +
                "    \"num_results\": 30,\n" +
                "    \"results\": [{\n" +
                "            \"section\": \"Briefing\",\n" +
                "            \"subsection\": \"\",\n" +
                "            \"title\": \"Election, Dodgers, Duterte: Your Thursday Evening Briefing\",\n" +
                "            \"abstract\": \"Here’s what you need to know at the end of the day.\",\n" +
                "            \"url\": \"abc.co\",\n" +
                "            \"byline\": \"By KAREN ZRAICK and MERRILL D. OLIVER\",\n" +
                "            \"item_type\": \"Article\",\n" +
                "            \"updated_date\": \"2016-10-20T18:32:41-04:00\",\n" +
                "            \"created_date\": \"2016-10-20T17:58:30-04:00\",\n" +
                "            \"published_date\": \"2016-10-20T17:58:30-04:00\",\n" +
                "            \"material_type_facet\": \"\",\n" +
                "            \"kicker\": \"\",\n" +
                "            \"des_facet\": [],\n" +
                "            \"org_facet\": [],\n" +
                "            \"per_facet\": [],\n" +
                "            \"geo_facet\": [],\n" +
                "            \"multimedia\": [{\n" +
                "                \"url\": \"abc.co\",\n" +
                "                \"format\": \"Standard Thumbnail\",\n" +
                "                \"height\": 75,\n" +
                "                \"width\": 75,\n" +
                "                \"type\": \"image\",\n" +
                "                \"subtype\": \"photo\",\n" +
                "                \"caption\": \"\",\n" +
                "                \"copyright\": \"Damon Winter/The New York Times\"\n" +
                "            }, {\n" +
                "                \"url\": \"abc.co\",\n" +
                "                \"format\": \"thumbLarge\",\n" +
                "                \"height\": 150,\n" +
                "                \"width\": 150,\n" +
                "                \"type\": \"image\",\n" +
                "                \"subtype\": \"photo\",\n" +
                "                \"caption\": \"\",\n" +
                "                \"copyright\": \"Damon Winter/The New York Times\"\n" +
                "            }, {\n" +
                "                \"url\": \"abc.co\",\n" +
                "                \"format\": \"Normal\",\n" +
                "                \"height\": 127,\n" +
                "                \"width\": 190,\n" +
                "                \"type\": \"image\",\n" +
                "                \"subtype\": \"photo\",\n" +
                "                \"caption\": \"\",\n" +
                "                \"copyright\": \"Damon Winter/The New York Times\"\n" +
                "            }, {\n" +
                "                \"url\": \"abc.co\",\n" +
                "                \"format\": \"mediumThreeByTwo210\",\n" +
                "                \"height\": 140,\n" +
                "                \"width\": 210,\n" +
                "                \"type\": \"image\",\n" +
                "                \"subtype\": \"photo\",\n" +
                "                \"caption\": \"\",\n" +
                "                \"copyright\": \"Damon Winter/The New York Times\"\n" +
                "            }, {\n" +
                "                \"url\": \"abc.co\",\n" +
                "                \"format\": \"superJumbo\",\n" +
                "                \"height\": 1365,\n" +
                "                \"width\": 2048,\n" +
                "                \"type\": \"image\",\n" +
                "                \"subtype\": \"photo\",\n" +
                "                \"caption\": \"\",\n" +
                "                \"copyright\": \"Damon Winter/The New York Times\"\n" +
                "            }],\n" +
                "            \"short_url\": \"http://abc.co\"\n" +
                "        }\n" +
                "\n" +
                "    ]\n" +
                "}";

        System.out.println(objectMapper.readValue(json,Root.class));
    }

}

输出:

Root (status=OK, copyright=Copyright (c) 2016 The New York Times Company. All Rights Reserved., section=home, last_updated=Fri Oct 21 02:57:45 IDT 2016, num_results=30, results=[Result (section=Briefing, subsection=, title=Election, Dodgers, Duterte: Your Thursday Evening Briefing, abstract2=Here’s what you need to know at the end of the day., url=abc.co, byline=By KAREN ZRAICK and MERRILL D. OLIVER, item_type=Article, updated_date=Fri Oct 21 01:32:41 IDT 2016, created_date=Fri Oct 21 00:58:30 IDT 2016, published_date=Fri Oct 21 00:58:30 IDT 2016, material_type_facet=, kicker=, des_facet=[], org_facet=[], per_facet=[], geo_facet=[], multimedia=[Multimedia (url=abc.co, format=Standard Thumbnail, height=75, width=75, type=image, subtype=photo, caption=, copyright=Damon Winter/The New York Times), Multimedia (url=abc.co, format=thumbLarge, height=150, width=150, type=image, subtype=photo, caption=, copyright=Damon Winter/The New York Times), Multimedia (url=abc.co, format=Normal, height=127, width=190, type=image, subtype=photo, caption=, copyright=Damon Winter/The New York Times), Multimedia (url=abc.co, format=mediumThreeByTwo210, height=140, width=210, type=image, subtype=photo, caption=, copyright=Damon Winter/The New York Times), Multimedia (url=abc.co, format=superJumbo, height=1365, width=2048, type=image, subtype=photo, caption=, copyright=Damon Winter/The New York Times)], short_url=http://abc.co)])

【讨论】:

    猜你喜欢
    • 2018-09-09
    • 1970-01-01
    • 2019-12-31
    • 2017-12-23
    • 2021-09-22
    • 1970-01-01
    • 2019-05-15
    • 2017-04-20
    • 2019-06-14
    相关资源
    最近更新 更多