简体   繁体   English

如何将此 Json 与 rest 模板 spring boot 映射

[英]How to map this Json with rest template spring boot

I'm kind of new to REST API and I have to map an endpoint that returns me this JSON:我是 REST API 的新手,我必须映射一个返回这个 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": []
                }
            }
        },

I have my controller with this call:我有这个电话的控制器:

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

My service implementation:我的服务实现:

@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);
}

Now I'm getting a little bit confused.现在我有点困惑了。 I created the OfferMapper to receive all the attributes from this JSON but some properties are coming null also I don't know if creating sub-objects (OfferRequest request, OfferResponse response) is the correct way to map it.我创建了 OfferMapper 来接收来自这个 JSON 的所有属性,但是一些属性将变为空,我也不知道创建子对象(OfferRequest 请求、OfferResponse 响应)是否是映射它的正确方法。

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

Here is the OfferResponse request and 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;
}

When I call with postman I get this response:当我打电话给邮递员时,我得到了这个回复:

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

} }

The call return some values but I don't understand why Im getting those nulls values and also how I'm gonna make this part in Java because its not like a list structure the JSON does not have [] for the offers only {}:该调用返回一些值,但我不明白为什么我得到这些空值以及我将如何在 Java 中制作这部分,因为它不像 JSON 没有 [] 仅提供 {} 的列表结构:

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

In your API response, you're getting this (I only use one fragment but you can extend the idea to all the other fields):在你的 API 响应中,你得到了这个(我只使用一个片段,但你可以将这个想法扩展到所有其他领域):

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

However, in your POJO, you have this:然而,在你的 POJO 中,你有这个:

public class OfferRequest {

  private String target;
  private String format;

You must know that Jackson, when serializing/deserializing, will use reflection unless differently specified.您必须知道 Jackson 在序列化/反序列化时将使用反射,除非另有说明。 That means, if you're declaring the field to be named target , it will expect the Json to contain target and not Target .这意味着,如果您将字段声明为target ,它将期望 Json 包含target而不是Target

Note that letting Jackson use reflection instead of using Jackson's annotations is a bad practice, because you strictly link your code to the Json they represent (which should not be the case).请注意,让 Jackson 使用反射而不是使用 Jackson 的注释是一种不好的做法,因为您将代码严格链接到它们所代表的 Json(不应该是这种情况)。

In order to make your code solid, these are the things I suggest:为了使您的代码更加可靠,我建议以下内容:

First, explicitly name your fields using the @JsonProperty annotation:首先,使用 @JsonProperty 注释显式命名您的字段:

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

Second, declare the fields final (they are not supposed to change anyway):其次,将字段声明为final (无论如何它们都不应该改变):

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

The above will force you to initialize them in the constructor.以上将强制您在构造函数中初始化它们。 So you can create a constructor for your class, that you will annotate with @JsonConstructor and will guide Jackson to build your class correctly:因此,您可以为您的类创建一个构造函数,您将使用@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");
}

Like this, you're explicitly telling to Jackson that you expect a field Target to be in the Json and if it's not, you'll have a parse exception.像这样,您明确告诉杰克逊您希望字段Target在 Json 中,如果不是,您将遇到解析异常。

Also, the Objects.requireNonNull() is your way to check that the field should not be null (because if the Json contains "Target": null , Jackson will see the field and will let it pass anyway).此外, Objects.requireNonNull()是您检查该字段不应为null的方法(因为如果 Json 包含"Target": null ,杰克逊将看到该字段并让它通过)。

Try @SerializedName("Field_name") for field that start's By uppercase(Target, Format...)尝试 @SerializedName("Field_name") 以大写开头的字段(目标,格式...)

@SerializedName("Target")
private String target;

I think after this changes 'u can get values.我认为在这种变化之后'你可以获得价值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM