2017-06-02 31 views
0

當指定某個時段時,我們準備一個Web API,該API返回該時段中每個日期的數據。如何設計模型以存儲動態字段ResponseBody

具體地說,POST

{"targetFrom": "2016-04-01", "targetTo": "2016-04-03"}} 

以下JSON數據被返回。

{ 
    "meta": { 
     "StartTime": "2017-06-01T06:50:28.001344102Z", 
     "execute_time": 7532.0517, 
     "host": "49a6ced149d2", 
     "rid": "" 
    }, 
    "result": { 
     "2016-04-01": { 
      "0:num": 121, 
      "0:price": 5244614, 
      "1:num": 124, 
      "1:price": 6324547, 
      "2:num": 115, 
      "2:price": 5604491 
     }, 
     "2016-04-02": { 
      "0:num": 125, 
      "0:price": 6321222, 
      "1:num": 117, 
      "1:price": 5835030, 
      "2:num": 118, 
      "2:price": 5771826 
     }, 
     "2016-04-03": { 
      "0:num": 118, 
      "0:price": 5486071, 
      "1:num": 131, 
      "1:price": 6563447, 
      "2:num": 111, 
      "2:price": 5740078 
     }, 
     "subTotal": { 
      "total_2016-04-01_num": 360, 
      "total_2016-04-01_price": 17173652, 
      "total_2016-04-02_num": 360, 
      "total_2016-04-02_price": 17928078, 
      "total_2016-04-03_num": 360, 
      "total_2016-04-03_price": 17789596 
      }, 
     "total": { 
      "num": 1080, 
      "price": 52891326 
     } 
    } 
} 

問題是日期字段的一部分,如「2016-04-01」。 我想在SpringBoot的應用程序端接受這個,考慮處理修改,並且想要定義一個合適的模型。 但是,我找不到一個好方法。

首先,我認爲以下是愚蠢的做法。

@JsonProperty("2016-04-01") 
private ResAnalyzeResultDayDto result_20160401; 

這是愚蠢的,因爲它不能對應於取決於參數targetFrom或targetTo在詢價時返回的數據。

那麼,我們如何定義一個模型來處理響應數據,並根據請求動態變化呢? 如果你有一個好主意,請告訴我。

附加說明: 我沒有相處得很好,因爲我寫了下面的代碼。

@JsonProperty("[0-9]{4}-[0-9]{2}-[0-9]{2}") 
private Map<String,ResAnalyzeResultSubTotalDayDto> maps; 

首先,「@ JsonProperty」似乎並不能夠使用正則表達式,我不認爲它會自動設置地圖的關鍵。

請求部分的代碼使用「RestTemplate」。

ReqTotalSalesStatusDto reqGoMonth = new ReqTotalSalesStatusDto(); 
reqGoMonth.setStrTo("2016-04-03"); 
reqGoMonth.setStrFrom("2016-04-01"); 

// Jackson2HttpMessage 
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 

ResponseEntity<ResAnalyzeDto> resultGoMonth = restTemplate.exchange(
    "http://localhost:18000/analyze" 
    , HttpMethod.POST 
    , new HttpEntity<>(reqGoMonth) 
    , ResAnalyzeDto.class); 

回答

1

你可以把所有的結果場那樣的地圖對象:

private Map<String,Object> result; 
result.forEach((k,v)->{ 
System.out.println("key: " + k + " value: " + v); 
if("total".equals(k)){ 
    Total total = (Total) v; 
} else if("subTotal".equals(k)) { 
    SubTotal subTotal = (SubTotal) v; 
} else { 
    ResAnalyzeResultDayDto resAnalyzeResultDayDto = (ResAnalyzeResultDayDto) v; 
} 
}); 

之後,你可以檢查的密鑰。至於你的示例地圖值可以是3個不同的對象。 Total,SubTotal或DayInfo(ResAnalyzeResultDayDto)。您可以輕鬆瞭解總計和小計,並可將它們轉換爲相應的對象類型。對於地圖的其他值,它們將轉換爲ResAnalyzeResultDayDto。

0

謝謝barbakini

我試圖在我教的方式,但我不能把它很好的演員,現在是一步到位。 。

的日誌如下

key: 2016-04-01 value: {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
v.toString(): {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
2017-06-02 17:12:49.962 [maekawa-PC-http-nio-9999-exec-3] ACS XXX:[id: tenant_id:] url:/api/v1/totalsalesstatus/common3 status:200 elapsedNanoTime:8455258 
2017-06-02 17:12:49.963 [maekawa-PC-http-nio-9999-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to jp.co.temp.sample.management.report.api.dto.ResAnalyzeResultDayDto] with root cause 

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to jp.co.temp.sample.management.report.api.dto.ResAnalyzeResultDayDto 
    at jp.co.temp.sample.management.report.api.TotalSalesStatusCommandService.lambda$createFinalResultObj3$3(TotalSalesStatusCommandService.java:609) 
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) 
    at jp.co.temp.sample.management.report.api.TotalSalesStatusCommandService.createFinalResultObj3(TotalSalesStatusCommandService.java:600) 
+0

嗨,你能分擔率R esAnalyzeResultDayDto類和代碼片段在哪裏執行投射?原因可能是變量名稱不匹配(Java不允許帶有':'的變量名,比如2:num) – barbakini

0

型號

@Data 
public class ResAnalyzeResultDayDto { 

@JsonProperty("0:num") 
private int num0; 

@JsonProperty("0:price") 
private int price0; 

@JsonProperty("1:num") 
private int num1; 

@JsonProperty("1:price") 
private int price1; 

@JsonProperty("2:num") 
private int num2; 

@JsonProperty("2:price") 
private int price2; 
} 

代碼

private ResponseEntity<TotalSalesStatus> createFinalResultObj3(TotalSalesStatus resultObj, 
     List<ResponseEntity<ResAnalyzeDto3>> goResponseEntityList ,String disposalDate) { 

    String methodName = Thread.currentThread().getStackTrace()[1].getMethodName(); 
    this.logger.info("■■UT:[{}] ", methodName); 

    int sumTotalNum = 0; 
    int sumTotalPrice = 0; 

    TotalSalesStatusGrandson totalSalesStatusDay = new TotalSalesStatusGrandson(); 
    resultObj.setTotalSalesStatusDay(totalSalesStatusDay); 

    TotalSalesStatusGrandson totalSalesStatusMonth = new TotalSalesStatusGrandson(); 
    resultObj.setTotalSalesStatusMonth(totalSalesStatusMonth); 

    boolean targetMonthFlag = false; 
    for(ResponseEntity<ResAnalyzeDto3> e : goResponseEntityList){ 
     ResAnalyzeDto3 dto = e.getBody(); 
     ResAnalyzeMetaDto meta = dto.getMeta(); 
     Map<String,Map<String,?>> resu = dto.getResult(); 
     this.logger.info("■■UT:[{}] ResAnalyzeMetaDto :{}", methodName,meta.toString()); 
     this.logger.info("■■UT:[{}] ResAnalyzeResultDto:{}", methodName,resu.toString()); 
      resu.forEach((k,v)->{ 
       System.out.println("key: " + k + " value: " + v); 
       System.out.println("v.toString(): " + v.toString()); 
       String val = v.toString(); 
       ObjectMapper mapper = new ObjectMapper(); 
       if("total".equals(k)){ 
//      ResAnalyzeResultTotalDto total = (ResAnalyzeResultTotalDto) v; 
        try { 
         ResAnalyzeResultTotalDto total = mapper.readValue(val,ResAnalyzeResultTotalDto.class); 
        } catch (Exception e1) { 
         e1.printStackTrace(); 
        } 
       } else if("subTotal".equals(k)) { 
//      ResAnalyzeResultSubTotalDto subTotal = (ResAnalyzeResultSubTotalDto) v; 
        try { 
         ResAnalyzeResultSubTotalDto subTotal = mapper.readValue(val,ResAnalyzeResultSubTotalDto.class); 
        } catch (Exception e1) { 
         e1.printStackTrace(); 
        } 
       } else { 
//      ResAnalyzeResultDayDto resAnalyzeResultDayDto = (ResAnalyzeResultDayDto) v; 
        try { 
         ResAnalyzeResultDayDto resAnalyzeResultDayDto = mapper.readValue(val,ResAnalyzeResultDayDto.class); 
        } catch (Exception e1) { 
         e1.printStackTrace(); 
        } 
       } 
      }); 
    } 
    TotalSalesStatusGrandson totalSalesStatusYear = new TotalSalesStatusGrandson(); 
    totalSalesStatusYear.setTotal(new BigDecimal(sumTotalPrice)); 
    resultObj.setTotalSalesStatusYear(totalSalesStatusYear); 
    resultObj.setUnitLabel("sample"); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(MediaType.APPLICATION_JSON); 
    ResponseEntity<TotalSalesStatus> result = new ResponseEntity<TotalSalesStatus>(resultObj, headers, HttpStatus.CREATED); 
    return result; 
} 

日誌

2017-06-05 13:33:48.382 [maekawa-PC-http-nio-9999-exec-1] INFO SAMPLE:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[createFinalResultObj3] 
2017-06-05 13:33:48.382 [maekawa-PC-http-nio-9999-exec-1] INFO SAMPLE:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[createFinalResultObj3] ResAnalyzeMetaDto :ResAnalyzeMetaDto(startTime=2017-06-05T04:33:48.499791734Z, executeTime=2.1928, host=bb8bfd9acf04, rid=) 
2017-06-05 13:33:48.382 [maekawa-PC-http-nio-9999-exec-1] INFO SAMPLE:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[createFinalResultObj3] ResAnalyzeResultDto:{2016-04-01={0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491}, 2016-04-02={0:num=125, 0:price=6321222, 1:num=117, 1:price=5835030, 2:num=118, 2:price=5771826}, 2016-04-03={0:num=118, 0:price=5486071, 1:num=131, 1:price=6563447, 2:num=111, 2:price=5740078}, subTotal={total_2016-04-01_num=360, total_2016-04-01_price=17173652, total_2016-04-02_num=360, total_2016-04-02_price=17928078, total_2016-04-03_num=360, total_2016-04-03_price=17789596}, total={num=1080, price=52891326}} 
key: 2016-04-01 value: {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
v.toString(): {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('0' (code 48)): was expecting double-quote to start field name 
at [Source: {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491}; line: 1, column: 3] 
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1702) 
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:558) 
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:456) 
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddName(ReaderBasedJsonParser.java:1771) 
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:684) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842) 
    at jp.co.temp.sample.management.report.api.TotalSalesStatusCommandService.lambda$createFinalResultObj3$3(TotalSalesStatusCommandService.java:636) 
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) 
相關問題