当前位置: 首页 > 知识库问答 >
问题:

如何使用rest模板spring boot映射此Json

施飞雨
2023-03-14

我是REST API的新手,我必须映射一个endpoint来返回这个JSON:

{
"request": {
    "Target": "Affiliate_Offer",
    "Format": "json",
    "Service": "HasOffers",
    "Version": "2",
    "api_key": "3225235c5633454cf60d35838cf8466f8fcf184b1360d",
    "Method": "findAll",
    "contain": [
        "Country"
    ]
},
"response": {
    "status": 1,
    "httpStatus": 200,
    "data": {
        "18292": {
            "Offer": {
                "id": "18292",
                "name": "247 Profit Formula",
                "description": "<b>Description:</b> Register for a chance to earn $500 or more per day from home!<br><br>\r\n\r\n<b>Requirement:</b> First Page Submit<br><br>\r\n\r\n<b>Country(ies):</b> US<br><br>\r\n\r\n<b>Media:</b> Blog, Display, Newsletter, Social Media, Text Links<br><br>\r\n\r\n<b>Restrictions:</b> No Incentives; no Email<br><br>\r\n\r\n<b>Other:</b> None.<br><br>\r\n",
                "require_approval": "0",
                "require_terms_and_conditions": 0,
                "terms_and_conditions": null,
                "preview_url": "https://www.247profitsecret.com/formula?",
                "currency": null,
                "default_payout": "0.90000",
                "protocol": "server",
                "status": "active",
                "expiration_date": "2039-01-06 04:59:59",
                "payout_type": "cpa_flat",
                "percent_payout": null,
                "featured": null,
                "conversion_cap": "0",
                "monthly_conversion_cap": "0",
                "payout_cap": "0.00",
                "monthly_payout_cap": "0.00",
                "allow_multiple_conversions": "0",
                "allow_website_links": "0",
                "allow_direct_links": "0",
                "show_custom_variables": "0",
                "session_hours": "24",
                "show_mail_list": "0",
                "dne_list_id": "0",
                "email_instructions": "0",
                "email_instructions_from": "Your List Name",
                "email_instructions_subject": "Survey Takers Needed\r\nFortune 500 Companies Need You!\r\nEarn $45 Per Online Survey\r\nSimple Survey Jobs",
                "enforce_secure_tracking_link": "1",
                "has_goals_enabled": "0",
                "default_goal_name": "",
                "modified": 1634138487,
                "use_target_rules": "0",
                "use_payout_groups": "0",
                "link_platform": null,
                "is_expired": "0",
                "dne_download_url": null,
                "dne_unsubscribe_url": null,
                "dne_third_party_list": false,
                "approval_status": "approved"
            },
            "Country": {
                "US": {
                    "id": "840",
                    "code": "US",
                    "name": "United States",
                    "regions": []
                }
            }
        },
        "17823": {
            "Offer": {
                "id": "17823",
                "name": "American Career Guide",
                "description": "<b>Description:</b> American Career Guide is your free guide to help you search jobs in your city!<br><br>\r\n\r\n<b>Requirement:</b> Email Submit<br><br>\r\n\r\n<b>Country(ies):</b> US<br><br>\r\n\r\n<b>Media:</b> Display, Email, Newsletter, Search, Text Link<br><br>\r\n\r\n<b>Restrictions:</b> 18+; no Incentives, no Social Media<br><br>\r\n\r\n<b>Other:</b> Contact Affiliate Manager for Suppression list.   <br><br>\r\n",
                "require_approval": "1",
                "require_terms_and_conditions": 0,
                "terms_and_conditions": null,
                "preview_url": "https://jobs.theamericancareerguide.com/api/offer",
                "currency": null,
                "default_payout": "2.40000",
                "protocol": "server",
                "status": "active",
                "expiration_date": "2030-01-08 04:59:59",
                "payout_type": "cpa_flat",
                "percent_payout": null,
                "featured": null,
                "conversion_cap": "200",
                "monthly_conversion_cap": "0",
                "payout_cap": "0.00",
                "monthly_payout_cap": "0.00",
                "allow_multiple_conversions": "0",
                "allow_website_links": "0",
                "allow_direct_links": "0",
                "show_custom_variables": "1",
                "session_hours": "24",
                "show_mail_list": "0",
                "dne_list_id": "0",
                "email_instructions": "1",
                "email_instructions_from": "AmericanCareerGuide\r\nAmerican_Career_Guide\r\nTheAmericanCareerGuide\r\nJobsAvailable",
                "email_instructions_subject": "Job Offers Are Waiting For You\r\nJobs Available - Positions Paying Up to $35/Hour\r\nHelp Wanted - Jobs Available in Your Area!\r\nHelp Wanted in Your Area - Pick Your New Job Today!\r\nLooking for a New Career?  Jobs Available in Your Area!\r\nThere Are Jobs Paying $25/Hour+ in Your City!  Search Now!",
                "enforce_secure_tracking_link": "1",
                "has_goals_enabled": "0",
                "default_goal_name": "",
                "modified": 1647550322,
                "use_target_rules": "0",
                "use_payout_groups": "0",
                "link_platform": null,
                "is_expired": "0",
                "dne_download_url": null,
                "dne_unsubscribe_url": null,
                "dne_third_party_list": false,
                "approval_status": null
            },
            "Country": {
                "US": {
                    "id": "840",
                    "code": "US",
                    "name": "United States",
                    "regions": []
                }
            }
        },

我有我的控制器与此调用:

 @GetMapping("/find-all-offers-api")
public ResponseEntity<OfferMapper> findAllOffersApi() {
    log.info("Find All Offers From Api - Controller Call");
   return service.findAllOffersApi();
}

我的服务实现:

@Override
public ResponseEntity<OfferMapper> findAllOffersApi() {
    log.info("Find All Offers From Api - Service Call");
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(List.of(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
    return restTemplate.exchange(GET_ALL_OFFERS_API, HttpMethod.GET, entity, OfferMapper.class);
}

现在我有点糊涂了。我创建了OfferMapper来接收来自这个JSON的所有属性,但有些属性将为空。我也不知道创建子对象(OfferRequest请求、OfferResponse响应)是否是映射它的正确方法。

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class OfferMapper {
  OfferRequest request;
  OfferResponse response;
}

以下是OfferResponse请求和响应:

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class OfferRequest {

  private String target;
  private String format;
  private String service;
  private String version;
  private String api_key;
  private String method;
  private List<String> contains;

}

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class OfferResponse {
   private int status;
   private int httpStatus;
   private OfferData data;
}

当我打电话给邮递员时,我得到了这样的回应:

{
"request": {
    "target": null,
    "format": null,
    "service": null,
    "version": null,
    "api_key": "3225235c5633454cf60d35838cf8466f8fcf184b1360d",
    "method": null,
    "contains": null
},
"response": {
    "status": 1,
    "httpStatus": 200,
    "data": {
        "offer": null
    }
}

}

这个调用返回了一些值,但是我不明白为什么我会得到这些空值,也不明白我要如何在Java中实现这个部分,因为它不像一个列表结构,JSON没有[]只提供{}:

"data": {
    "18292": {
        "Offer": {
            "id": "18292",
            "name": "247 Profit Formula",

共有2个答案

唐焕
2023-03-14

尝试@SerializedName(“Field_name”)作为开头的字段按大写字母(目标,格式...)

@SerializedName("Target")
private String target;

我认为在这些变化之后,你可以得到价值。

朱慈
2023-03-14

在您的API响应中,您会得到这样的结果(我只使用了一个片段,但是您可以将这个想法扩展到所有其他字段):

{
    "request": {
        "Target": "Affiliate_Offer",
        "Format": "json",

但是,在您的POJO中,您有以下内容:

public class OfferRequest {

  private String target;
  private String format;

您必须知道,Jackson在序列化/反序列化时将使用反射,除非另有规定。这意味着,如果您声明字段名为<code>target,它将期望Json包含<code>target。

请注意,让Jackson使用反射而不是使用Jackson的注释是一种糟糕的做法,因为您严格地将代码链接到它们表示的Json(不应该是这种情况)。

为了使您的代码可靠,我建议如下:

首先,使用@JsonProperty注释显式命名字段:

@JsonProperty("Target") //<-- I'm saying the serialized name of this property is Target with capital T
private String target;

其次,声明字段<code>final</code>(它们无论如何都不应该更改):

private final String target; //<-- field must be initialized and can't change its value anymore

以上将强制您在构造函数中初始化它们。因此,您可以为您的类创建一个构造函数,您将使用@JsonConstructor对其进行注释,并指导Jackson正确构建您的类:

@JsonCreator
public OfferRequest(@JsonProperty(value = "Target", required = true) String target) { //<-- you require the field Target to be present, else you stop the Json deserialization with an error
    this.target = requireNonNull(target, "target should not be null");
}

像这样,您明确地告诉Jackson,您希望字段Target在Json中,如果不是,您将有一个解析异常。

另外,对象。requireNonNull()是检查字段不应为null(因为如果Json包含“Target”:null,Jackson将看到该字段,并无论如何让它通过)。

 类似资料:
  • 嗨,我有一个restendpointxyz。com/test/create,其中预期的内容类型为application/json,内容为 在具有数组的body中还有一些其他字段。 我在Spring rest控制器中使用rest模板来访问上述endpoint,我还想传递数据。我不确定endpoint端使用什么域模型将json中的数据从客户端映射到服务器端。 如何使用rest模板使用上述数据命中上述e

  • 我正在尝试使用客户端发送到映射(或JSON对象)中的JSON对象。我使用的是Jersey2.22.1,默认情况下它使用的是Moxy。尝试了如下所示的HashMap,但没有成功。它给出415错误-“不支持的媒体类型” 尝试使用自定义类以及包装一个映射。同样的错误。有谁能帮我,让我知道如何处理地图。 作为临时解决方案,我使用下面代码。但想知道如何正确地使用Map完成此操作

  • 我需要用'username'和'password'json主体向/user/auth发出POST请求,以从spring安全endpoint检索用户身份验证。 我有一个thymeleaf登录表单。它发送'username'和'password'到我的自定义身份验证筛选器endpoint。 正在触发终结点,但它接收的对象为NULL。 我可以使用postman将json主体发送到endpoint,并且可

  • 我已经为这些列表创建了模型类,这些列表是我收到的对我的服务的响应 清单1 清单2 列表3是最后的列表,上面两个列表映射的结果,即我的服务的响应 清单3 这些列表与用户名和用户标签相连。我已将列表1的所有值映射到列表3。现在对于列表2,我需要检查每个userLabel是否在list3中存在一个userName等于userLabel的对象,如果为true,则totalUsers的值设置为list3的那

  • 我已经讨论过这个问题:如何使用Mockito在Spring中模拟自动构建的@Value字段?。我们如何模拟以下内容? 这样我们就可以在进行模拟时获取其价值?

  • 我有一个API阶段没有使用“Lambda代理集成”,它有一个Lambda函数传递一个错误。 在映射模板中,我有以下内容: 有可能做我想做的事吗?我找不到$util.parsejson(即stringify)的反向。 谢谢!